Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"/> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
| <title>a11oy — Governed Mission Compute · WarHacker · SZL Holdings</title> | |
| <meta name="description" content="a11oy is governed substrate for defense: code-as-action that is ALLOWED or BLOCKED and sealed into a signed, re-verifiable receipt. Army counter-UAS, Navy maritime, multi-domain joint compute — each a live in-image surface. Honest labels only."/> | |
| <!-- SOVEREIGN: 0 runtime CDN. Fonts self-hosted in-image, served same-origin at | |
| /vendor/fonts/*.woff2 (SAME pattern as the clean console). NO external font CDN. --> | |
| <style> | |
| @font-face{font-family:'Space Grotesk';font-style:normal;font-weight:300 700;font-display:swap;src:url('/vendor/fonts/SpaceGrotesk.woff2') format('woff2');} | |
| @font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;src:url('/vendor/fonts/JetBrainsMono.woff2') format('woff2');} | |
| </style> | |
| <style> | |
| /* a11oy house style — dark-constellation + gold/teal ribbon (matches /superpowers) */ | |
| :root{ | |
| --ground:#0a0a0a; --panel:#0c0c0c; --panel2:#070707; | |
| --gold:#c9b787; --gold-bright:#d6c69a; | |
| --teal:#5fb3a3; --teal-soft:rgba(95,179,163,0.10); | |
| --cream:#f5f5f5; --paragraph:#9a9a9a; --muted:#888; --dim:#555; | |
| --gold-line:rgba(201,183,135,0.15); --gold-soft:rgba(201,183,135,0.04); | |
| --teal-line:rgba(95,179,163,0.22); | |
| --live:#5a8a6e; --err:#b06a5a; | |
| --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,monospace; | |
| --display:'Space Grotesk',Georgia,serif; | |
| } | |
| *{box-sizing:border-box;} | |
| html,body{margin:0;padding:0;background:var(--ground);color:var(--cream); | |
| font-family:var(--display);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;} | |
| .mono{font-family:var(--mono);} | |
| a{color:inherit;} | |
| :focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:3px;} | |
| .ribbon{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:1.25rem; | |
| flex-wrap:wrap;padding:0.5rem 1.25rem;font-family:var(--mono);font-size:10px; | |
| letter-spacing:0.12em;text-transform:uppercase;color:var(--gold); | |
| background:rgba(10,10,10,0.85);backdrop-filter:blur(10px); | |
| border-bottom:1px solid var(--gold-line);} | |
| .ribbon .sep{color:var(--dim);} | |
| .ribbon .teal{color:var(--teal);} | |
| .ribbon .live{display:inline-flex;align-items:center;gap:0.4rem;color:var(--cream);} | |
| .ribbon a{margin-left:auto;color:var(--muted);text-decoration:none;} | |
| .ribbon a:hover{color:var(--gold);} | |
| .live-dot{width:6px;height:6px;border-radius:50%;background:var(--live); | |
| box-shadow:0 0 6px var(--live);animation:pulseDot 2.2s ease-in-out infinite;} | |
| @keyframes pulseDot{0%,100%{opacity:1;}50%{opacity:.35;}} | |
| .hero{position:relative;overflow:hidden;padding:3.5rem 1.5rem 2.5rem;text-align:center;} | |
| .grid-bg{position:absolute;inset:0;pointer-events:none; | |
| background-image: | |
| linear-gradient(rgba(255,255,255,.025) 1px,transparent 1px), | |
| linear-gradient(90deg,rgba(255,255,255,.025) 1px,transparent 1px); | |
| background-size:56px 56px; | |
| -webkit-mask-image:radial-gradient(ellipse at center,#000 30%,transparent 75%); | |
| mask-image:radial-gradient(ellipse at center,#000 30%,transparent 75%);} | |
| .hero-inner{position:relative;z-index:2;max-width:64rem;margin:0 auto;} | |
| .eyebrow{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .85rem; | |
| border-radius:999px;border:1px solid var(--gold-line);background:var(--gold-soft);margin-bottom:1.75rem;} | |
| .eyebrow-dot{width:6px;height:6px;border-radius:50%;background:var(--gold); | |
| animation:pulseDot 2.2s ease-in-out infinite;} | |
| .eyebrow-text{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold);} | |
| .headline{font-size:clamp(2.4rem,5.5vw,4.4rem);font-weight:300;line-height:1.03; | |
| letter-spacing:-.035em;margin:0 0 1.25rem;color:var(--cream);} | |
| .headline .accent{background:linear-gradient(120deg,var(--cream) 20%,var(--gold) 90%); | |
| -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;} | |
| .support{font-size:16px;line-height:1.65;color:var(--paragraph);max-width:44rem;margin:0 auto 2rem;} | |
| .runall{display:inline-flex;align-items:center;gap:.5rem;padding:.7rem 1.5rem;font-size:12.5px; | |
| font-weight:500;font-family:var(--mono);border-radius:8px;border:1px solid var(--gold); | |
| background:var(--gold);color:var(--ground);cursor:pointer;letter-spacing:.06em;margin-top:.5rem;} | |
| .runall:hover{background:var(--gold-bright);} | |
| .runall:disabled{opacity:.5;cursor:not-allowed;} | |
| .stats{display:flex;flex-wrap:wrap;justify-content:center;gap:.75rem;max-width:60rem;margin:2rem auto 0;} | |
| .stat{flex:1 1 150px;min-width:140px;border:1px solid var(--gold-line);border-radius:8px; | |
| background:var(--panel);padding:.9rem 1rem;text-align:left;} | |
| .stat .k{font-family:var(--mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);} | |
| .stat .v{font-size:1.35rem;font-weight:500;color:var(--gold);margin-top:.25rem;} | |
| .stat .v.teal{color:var(--teal);} | |
| .grid{max-width:64rem;margin:2.75rem auto 4rem;padding:0 1.25rem; | |
| display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:1.25rem;} | |
| .card{border:1px solid var(--gold-line);border-radius:12px;background:var(--panel); | |
| padding:1.4rem 1.4rem 1.6rem;display:flex;flex-direction:column;} | |
| .card-head{display:flex;align-items:baseline;gap:.6rem;margin-bottom:.5rem;flex-wrap:wrap;} | |
| .card-num{font-family:var(--mono);font-size:11px;color:var(--teal);border:1px solid var(--teal-line); | |
| border-radius:5px;padding:.1rem .4rem;background:var(--teal-soft);} | |
| .card-organ{font-family:var(--mono);font-size:10px;color:var(--gold);border:1px solid var(--gold-line); | |
| border-radius:5px;padding:.1rem .4rem;background:var(--gold-soft);text-transform:uppercase;letter-spacing:.08em;} | |
| .card-title{font-size:1.1rem;font-weight:500;color:var(--cream);letter-spacing:-.01em;} | |
| .card-sub{font-size:12.5px;color:var(--paragraph);line-height:1.6;margin:0 0 1rem;} | |
| .card-endpoint{font-family:var(--mono);font-size:10px;color:var(--muted);margin-bottom:1rem;word-break:break-all;} | |
| .card-endpoint b{color:var(--gold);font-weight:500;} | |
| .card-controls{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1rem;} | |
| .r-btn{display:inline-flex;align-items:center;gap:.4rem;padding:.5rem 1rem;font-size:11.5px; | |
| font-weight:500;font-family:var(--mono);border-radius:6px;border:1px solid var(--gold-line); | |
| background:transparent;color:var(--gold);cursor:pointer;letter-spacing:.04em; | |
| transition:background .18s ease,border-color .18s ease;} | |
| .r-btn:hover{background:rgba(201,183,135,.08);border-color:rgba(201,183,135,.35);} | |
| .r-btn:active{opacity:.75;} | |
| .r-btn:disabled{opacity:.4;cursor:not-allowed;} | |
| .r-btn-primary{background:var(--gold);color:var(--ground);border-color:var(--gold);} | |
| .r-btn-primary:hover{background:var(--gold-bright);border-color:var(--gold-bright);} | |
| .verdict{display:inline-flex;align-items:center;gap:.4rem;font-family:var(--mono);font-size:11px; | |
| padding:.2rem .6rem;border-radius:5px;margin-bottom:.6rem;visibility:hidden;} | |
| .verdict.show{visibility:visible;} | |
| .verdict.ok{color:var(--live);border:1px solid rgba(90,138,110,.4);background:rgba(90,138,110,.08);} | |
| .verdict.warn{color:var(--gold);border:1px solid var(--gold-line);background:var(--gold-soft);} | |
| .verdict.err{color:var(--err);border:1px solid rgba(176,106,90,.4);background:rgba(176,106,90,.08);} | |
| .receipt{font-family:var(--mono);font-size:10px;color:var(--teal);margin:-.2rem 0 .6rem;visibility:hidden;} | |
| .receipt.show{visibility:visible;} | |
| .out{position:relative;border:1px solid var(--gold-line);border-radius:8px;background:var(--panel2); | |
| overflow:hidden;margin-top:auto;} | |
| .out-label{display:flex;align-items:center;justify-content:space-between;padding:.45rem .85rem; | |
| border-bottom:1px solid var(--gold-line);font-family:var(--mono);font-size:9px; | |
| letter-spacing:.1em;text-transform:uppercase;color:var(--muted);} | |
| .out-status{display:inline-flex;align-items:center;gap:.4rem;} | |
| .status-dot{width:6px;height:6px;border-radius:50%;background:var(--dim);transition:background .3s;} | |
| .status-dot.ok{background:var(--live);box-shadow:0 0 6px var(--live);} | |
| .status-dot.err{background:var(--err);box-shadow:0 0 6px var(--err);} | |
| .status-dot.loading{background:var(--gold);animation:pulseDot 1s ease-in-out infinite;} | |
| .out-pre{margin:0;padding:.85rem;font-family:var(--mono);font-size:10.5px;line-height:1.6; | |
| color:var(--paragraph);white-space:pre-wrap;word-break:break-word;max-height:300px;overflow-y:auto; | |
| scrollbar-width:thin;scrollbar-color:var(--dim) transparent;} | |
| .out-pre:empty::before{content:"— launch this demo to call the live organ —";color:var(--dim);font-style:italic;} | |
| .footer{border-top:1px solid var(--gold-line);padding:2rem 1.5rem;text-align:center;} | |
| .footer .note{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);} | |
| .honest{max-width:64rem;margin:0 auto 2rem;padding:0 1.25rem;} | |
| .honest-box{border:1px solid var(--teal-line);border-radius:8px;background:var(--teal-soft); | |
| padding:.9rem 1.1rem;font-size:12px;color:var(--paragraph);line-height:1.6;} | |
| .honest-box b{color:var(--teal);} | |
| @media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms ;animation-iteration-count:1 ;}} | |
| </style> | |
| <style> | |
| .tabs-bar{position:sticky;top:0;z-index:40;display:flex;gap:.35rem;flex-wrap:wrap;justify-content:center; | |
| padding:.6rem 1rem;background:rgba(10,10,10,.92);backdrop-filter:blur(10px);border-bottom:1px solid var(--gold-line);} | |
| .tab-btn{font-family:var(--mono);font-size:11px;letter-spacing:.04em;padding:.5rem .9rem;border-radius:7px; | |
| border:1px solid var(--gold-line);background:transparent;color:var(--paragraph);cursor:pointer;transition:all .18s ease;} | |
| .tab-btn:hover{color:var(--gold);border-color:rgba(201,183,135,.35);} | |
| .tab-btn.active{background:var(--gold);color:var(--ground);border-color:var(--gold);font-weight:600;} | |
| .tab-btn .dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--dim);margin-right:.4rem;vertical-align:middle;} | |
| .tab-btn .dot.ok{background:var(--live);box-shadow:0 0 5px var(--live);} | |
| .tab-btn .dot.err{background:var(--err);} | |
| .tab-btn .dot.loading{background:var(--gold);animation:pulseDot 1s ease-in-out infinite;} | |
| .panel-wrap{max-width:60rem;margin:1.75rem auto 3rem;padding:0 1.25rem;} | |
| .panel{display:none;} | |
| .panel.active{display:block;animation:fade .3s ease;} | |
| @keyframes fade{from{opacity:0;transform:translateY(6px);}to{opacity:1;transform:none;}} | |
| .p-head{margin-bottom:1rem;} | |
| .p-title{font-size:1.6rem;font-weight:400;letter-spacing:-.02em;margin:0 0 .35rem;color:var(--cream);} | |
| .p-blurb{font-size:13.5px;line-height:1.6;color:var(--paragraph);max-width:42rem;margin:0;} | |
| .seg{display:inline-flex;gap:.3rem;margin:.75rem 0 1rem;flex-wrap:wrap;} | |
| .seg .r-btn.sel{background:var(--gold);color:var(--ground);border-color:var(--gold);} | |
| textarea.ta{width:100%;min-height:120px;background:var(--panel2);border:1px solid var(--gold-line);border-radius:8px; | |
| color:var(--cream);font-family:var(--mono);font-size:11px;padding:.7rem;resize:vertical;line-height:1.5;} | |
| .tl{list-style:none;margin:.6rem 0 0;padding:0;} | |
| .tl li{display:flex;gap:.6rem;align-items:flex-start;padding:.45rem 0;border-bottom:1px solid var(--gold-soft);font-size:12px;} | |
| .tl .ic{flex:0 0 auto;width:18px;height:18px;border-radius:50%;display:flex;align-items:center;justify-content:center; | |
| font-family:var(--mono);font-size:10px;margin-top:1px;} | |
| .tl .ic.ok{background:rgba(90,138,110,.15);color:var(--live);border:1px solid rgba(90,138,110,.4);} | |
| .tl .ic.no{background:rgba(176,106,90,.15);color:var(--err);border:1px solid rgba(176,106,90,.4);} | |
| .tl .step{color:var(--cream);font-weight:500;} | |
| .tl .det{color:var(--muted);} | |
| .crossed{border:1px solid rgba(176,106,90,.4);background:rgba(176,106,90,.07);border-radius:8px;padding:.7rem .9rem;margin:.7rem 0;} | |
| .crossed h4{margin:0 0 .4rem;font-size:11px;font-family:var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--err);} | |
| .crossed .row{font-size:12px;color:var(--paragraph);padding:.25rem 0;} | |
| .crossed .row b{color:var(--cream);} | |
| table.t{width:100%;border-collapse:collapse;margin-top:.6rem;font-size:11.5px;} | |
| table.t th{text-align:left;font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase; | |
| color:var(--muted);padding:.4rem .5rem;border-bottom:1px solid var(--gold-line);} | |
| table.t td{padding:.4rem .5rem;border-bottom:1px solid var(--gold-soft);color:var(--paragraph);} | |
| .pill{font-family:var(--mono);font-size:10px;padding:.12rem .45rem;border-radius:4px;} | |
| .pill.go,.pill.nominal,.pill.allow{color:var(--live);background:rgba(90,138,110,.12);border:1px solid rgba(90,138,110,.35);} | |
| .pill.review,.pill.insufficient{color:var(--gold);background:var(--gold-soft);border:1px solid var(--gold-line);} | |
| .pill.nogo,.pill.anomalous,.pill.block{color:var(--err);background:rgba(176,106,90,.1);border:1px solid rgba(176,106,90,.35);} | |
| .kpis{display:flex;gap:.6rem;flex-wrap:wrap;margin:.4rem 0 .2rem;} | |
| .kpi{flex:1 1 100px;min-width:90px;border:1px solid var(--gold-line);border-radius:8px;background:var(--panel);padding:.7rem .8rem;} | |
| .kpi .k{font-family:var(--mono);font-size:8.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);} | |
| .kpi .v{font-size:1.5rem;font-weight:500;color:var(--gold);} | |
| .kpi .v.live{color:var(--live);} .kpi .v.err{color:var(--err);} .kpi .v.teal{color:var(--teal);} | |
| #trajCanvas{width:100%;height:340px;background:radial-gradient(ellipse at center,#0d0d12,#060606); | |
| border:1px solid var(--gold-line);border-radius:10px;display:block;margin-top:.6rem;cursor:grab;} | |
| #trajCanvas:active{cursor:grabbing;} | |
| .leg{display:flex;gap:1rem;flex-wrap:wrap;font-family:var(--mono);font-size:10px;color:var(--muted);margin-top:.5rem;} | |
| .leg span b{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:.35rem;vertical-align:middle;} | |
| .field{display:flex;flex-direction:column;gap:.3rem;margin-bottom:.6rem;} | |
| .field label{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);} | |
| .sub{font-family:var(--mono);font-size:10px;color:var(--teal);margin:.3rem 0 0;} | |
| .gap{height:.6rem;} | |
| </style> | |
| <style> | |
| /* --- LIVE STATUS RIBBON (real numbers pulled from live a11oy endpoints) --- */ | |
| .liveribbon{position:sticky;top:0;z-index:60;display:flex;align-items:stretch;gap:0;flex-wrap:wrap; | |
| font-family:var(--mono);background:linear-gradient(90deg,#070707,#0c0c0c 60%,#070707); | |
| border-bottom:1px solid var(--gold-line);overflow:hidden;} | |
| .lr-brand{display:flex;align-items:center;gap:.5rem;padding:.55rem 1rem;border-right:1px solid var(--gold-line); | |
| font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--gold);font-weight:600;white-space:nowrap;} | |
| .lr-cells{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:stretch;} | |
| .lr-cell{display:flex;flex-direction:column;justify-content:center;gap:.1rem;padding:.4rem .9rem; | |
| border-right:1px solid var(--gold-soft);min-width:auto;} | |
| .lr-cell .lk{font-size:8px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);} | |
| .lr-cell .lv{font-size:12.5px;color:var(--cream);font-weight:500;display:flex;align-items:center;gap:.35rem;} | |
| .lr-cell .lv.teal{color:var(--teal);} .lr-cell .lv.gold{color:var(--gold);} .lr-cell .lv.err{color:var(--err);} | |
| .lr-cell .lv.pending{color:var(--dim);} | |
| .lr-tag{font-size:8px;letter-spacing:.1em;padding:.05rem .3rem;border-radius:3px;text-transform:uppercase;} | |
| .lr-tag.measured{color:var(--live);border:1px solid rgba(90,138,110,.4);background:rgba(90,138,110,.1);} | |
| .lr-tag.sample{color:var(--gold);border:1px solid var(--gold-line);background:var(--gold-soft);} | |
| .lr-tag.nolive{color:var(--err);border:1px solid rgba(176,106,90,.4);background:rgba(176,106,90,.08);} | |
| .lr-foot{display:flex;align-items:center;padding:.4rem 1rem;border-left:1px solid var(--gold-line); | |
| font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);white-space:nowrap;margin-left:auto;} | |
| .lr-foot a{color:var(--muted);text-decoration:none;} .lr-foot a:hover{color:var(--gold);} | |
| /* --- WOW BANNER: governed code-as-action --- */ | |
| .wow{max-width:64rem;margin:1.5rem auto .5rem;padding:0 1.25rem;} | |
| .wow-card{border:1px solid var(--gold-line);border-radius:14px;background: | |
| radial-gradient(120% 140% at 0% 0%,rgba(95,179,163,.06),transparent 55%),var(--panel); | |
| padding:1.4rem 1.5rem;} | |
| .wow-eyebrow{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--teal);margin-bottom:.5rem;} | |
| .wow-h{font-size:clamp(1.3rem,3vw,1.9rem);font-weight:400;letter-spacing:-.02em;line-height:1.2;margin:0 0 .6rem;color:var(--cream);} | |
| .wow-h b{font-weight:600;} | |
| .wow-flow{display:flex;align-items:center;gap:.55rem;flex-wrap:wrap;font-family:var(--mono);font-size:12px;margin:.8rem 0;} | |
| .wow-step{padding:.35rem .7rem;border-radius:7px;border:1px solid var(--gold-line);background:var(--panel2);color:var(--paragraph);} | |
| .wow-step.allow{color:var(--live);border-color:rgba(90,138,110,.4);background:rgba(90,138,110,.08);} | |
| .wow-step.block{color:var(--err);border-color:rgba(176,106,90,.4);background:rgba(176,106,90,.08);} | |
| .wow-step.seal{color:var(--teal);border-color:var(--teal-line);background:var(--teal-soft);} | |
| .wow-arr{color:var(--dim);} | |
| .wow-sub{font-size:13px;line-height:1.6;color:var(--paragraph);margin:.3rem 0 0;max-width:46rem;} | |
| .wow-ctas{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:1rem;} | |
| .wow-cta{display:inline-flex;align-items:center;gap:.45rem;padding:.6rem 1.2rem;font-family:var(--mono);font-size:12px; | |
| font-weight:500;border-radius:8px;cursor:pointer;text-decoration:none;letter-spacing:.04em;} | |
| .wow-cta.primary{background:var(--gold);color:var(--ground);border:1px solid var(--gold);} | |
| .wow-cta.primary:hover{background:var(--gold-bright);} | |
| .wow-cta.ghost{background:transparent;color:var(--teal);border:1px solid var(--teal-line);} | |
| .wow-cta.ghost:hover{background:var(--teal-soft);} | |
| /* --- DOMAIN BAND: Army / Navy / Multi-domain --- */ | |
| .domains{max-width:64rem;margin:2rem auto 1rem;padding:0 1.25rem;} | |
| .domains-h{font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted); | |
| text-align:center;margin-bottom:1rem;} | |
| .dgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1rem;} | |
| .dcard{border:1px solid var(--gold-line);border-radius:12px;background:var(--panel);padding:1.1rem 1.2rem; | |
| display:flex;flex-direction:column;text-decoration:none;transition:border-color .18s ease,transform .18s ease;} | |
| .dcard:hover{border-color:rgba(201,183,135,.45);transform:translateY(-2px);} | |
| .dcard .dtag{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--teal);margin-bottom:.5rem;} | |
| .dcard .dt{font-size:1.05rem;font-weight:500;color:var(--cream);margin-bottom:.4rem;letter-spacing:-.01em;} | |
| .dcard .dd{font-size:12.5px;line-height:1.55;color:var(--paragraph);flex:1;} | |
| .dcard .dlink{font-family:var(--mono);font-size:11px;color:var(--gold);margin-top:.8rem;} | |
| .dcard .dlink::after{content:" →";} | |
| .dcard .dmat{font-family:var(--mono);font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-top:.4rem;} | |
| /* --- PROOF strip --- */ | |
| .proof{max-width:64rem;margin:1.5rem auto;padding:0 1.25rem;} | |
| .proof-card{border:1px solid var(--teal-line);border-radius:12px;background:var(--teal-soft);padding:1.2rem 1.4rem; | |
| display:flex;gap:1.25rem;align-items:center;flex-wrap:wrap;} | |
| .proof-card .pc-l{flex:1 1 320px;} | |
| .proof-card .pc-h{font-size:1.05rem;font-weight:500;color:var(--cream);margin:0 0 .35rem;} | |
| .proof-card .pc-h b{color:var(--teal);} | |
| .proof-card .pc-d{font-size:12.5px;line-height:1.6;color:var(--paragraph);margin:0;} | |
| .proof-card .pc-d code{color:var(--gold);font-family:var(--mono);font-size:11px;} | |
| .proof-card .pc-r{display:flex;gap:.6rem;flex-wrap:wrap;} | |
| /* --- 25-DEMO DEPTH SECTION (5 problems x 5 demos) --- */ | |
| .depth{max-width:64rem;margin:2.75rem auto 1rem;padding:0 1.25rem;} | |
| .depth-head{text-align:center;margin-bottom:1.5rem;} | |
| .depth-eyebrow{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--teal);margin-bottom:.5rem;} | |
| .depth-h{font-size:clamp(1.4rem,3.2vw,2rem);font-weight:300;letter-spacing:-.02em;margin:0 0 .5rem;color:var(--cream);} | |
| .depth-h b{font-weight:600;color:var(--gold);} | |
| .depth-sub{font-size:13px;line-height:1.6;color:var(--paragraph);max-width:46rem;margin:0 auto;} | |
| .prob{border:1px solid var(--gold-line);border-radius:12px;background:var(--panel);margin-bottom:1rem;overflow:hidden;} | |
| .prob-head{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;padding:1rem 1.2rem;cursor:pointer; | |
| background:transparent;border:0;width:100%;text-align:left;color:inherit;transition:background .18s ease;} | |
| .prob-head:hover{background:var(--gold-soft);} | |
| .prob-head .chev{font-family:var(--mono);font-size:13px;color:var(--gold);transition:transform .2s ease;flex:0 0 auto;} | |
| .prob.open .prob-head .chev{transform:rotate(90deg);} | |
| .prob-id{font-family:var(--mono);font-size:11px;color:var(--teal);border:1px solid var(--teal-line);border-radius:5px;padding:.1rem .45rem;background:var(--teal-soft);flex:0 0 auto;} | |
| .prob-title{font-size:1.05rem;font-weight:500;color:var(--cream);flex:1 1 auto;letter-spacing:-.01em;} | |
| .lbl{font-family:var(--mono);font-size:9px;letter-spacing:.1em;padding:.12rem .45rem;border-radius:4px;text-transform:uppercase;flex:0 0 auto;white-space:nowrap;} | |
| .lbl.real{color:var(--live);border:1px solid rgba(90,138,110,.45);background:rgba(90,138,110,.1);} | |
| .lbl.roadmap{color:var(--gold);border:1px solid var(--gold-line);background:var(--gold-soft);} | |
| .lbl.exp{color:var(--teal);border:1px solid var(--teal-line);background:var(--teal-soft);} | |
| .prob-count{font-family:var(--mono);font-size:10px;color:var(--muted);flex:0 0 auto;} | |
| .prob-summary{padding:0 1.2rem 0 2.7rem;font-size:12px;color:var(--paragraph);line-height:1.55;margin:-.3rem 0 .4rem;display:none;} | |
| .prob.open .prob-summary{display:block;} | |
| .demos{display:none;padding:.4rem 1.2rem 1.2rem;} | |
| .prob.open .demos{display:block;} | |
| .demo{border:1px solid var(--gold-soft);border-radius:9px;background:var(--panel2);padding:.85rem 1rem;margin-top:.7rem;} | |
| .demo-top{display:flex;align-items:center;gap:.55rem;flex-wrap:wrap;} | |
| .demo-id{font-family:var(--mono);font-size:10px;color:var(--gold);border:1px solid var(--gold-line);border-radius:4px;padding:.08rem .4rem;flex:0 0 auto;} | |
| .demo-title{font-size:13px;color:var(--cream);font-weight:500;flex:1 1 auto;} | |
| .demo-ctrls{display:flex;gap:.4rem;flex-wrap:wrap;margin:.6rem 0 .2rem;} | |
| .demo-verdict{font-family:var(--mono);font-size:11px;margin:.5rem 0 .2rem;display:none;} | |
| .demo-verdict.show{display:block;} | |
| .demo-verdict .ok{color:var(--live);} .demo-verdict .err{color:var(--err);} .demo-verdict .warn{color:var(--gold);} | |
| .demo-receipt{font-family:var(--mono);font-size:10px;color:var(--teal);margin:.3rem 0 0;word-break:break-all;display:none;} | |
| .demo-receipt.show{display:block;} | |
| .demo-out{font-family:var(--mono);font-size:9.5px;line-height:1.5;color:var(--paragraph);white-space:pre-wrap;word-break:break-word; | |
| max-height:220px;overflow-y:auto;margin:.5rem 0 0;padding:.6rem;background:#050505;border:1px solid var(--gold-soft);border-radius:6px;display:none; | |
| scrollbar-width:thin;scrollbar-color:var(--dim) transparent;} | |
| .demo-out.show{display:block;} | |
| </style> | |
| </head> | |
| <body> | |
| <!-- LIVE STATUS RIBBON — every number below is pulled from a live a11oy endpoint | |
| on this Space at page load; honest labels (MEASURED / SAMPLE / NO-LIVE-DATA), | |
| never fabricated. --> | |
| <div class="liveribbon" id="liveRibbon" aria-label="Live a11oy substrate status"> | |
| <span class="lr-brand"><span class="live-dot"></span>a11oy · governed substrate</span> | |
| <div class="lr-cells"> | |
| <div class="lr-cell"><span class="lk">Energy operator</span><span class="lv pending" id="lrOp">probing…</span></div> | |
| <div class="lr-cell"><span class="lk">Jobs done</span><span class="lv pending" id="lrJobs">—</span></div> | |
| <div class="lr-cell"><span class="lk">Joules</span><span class="lv pending" id="lrJoules">—</span></div> | |
| <div class="lr-cell"><span class="lk">Nodes computing</span><span class="lv pending" id="lrNodes">—</span></div> | |
| <div class="lr-cell"><span class="lk">Substrate</span><span class="lv pending" id="lrSub">—</span></div> | |
| <div class="lr-cell"><span class="lk">Λ trust</span><span class="lv gold">Conjecture 1 · advisory</span></div> | |
| <div class="lr-cell"><span class="lk">Locked proofs</span><span class="lv teal" id="lrLocked">8</span></div> | |
| </div> | |
| <div class="lr-foot"><a href="/console">console →</a></div> | |
| </div> | |
| <section class="hero"> | |
| <div class="grid-bg"></div> | |
| <div class="hero-inner"> | |
| <span class="eyebrow"><span class="eyebrow-dot"></span><span class="eyebrow-text">WarHacker · 5 mission surfaces · 25 governed demos · live on this Space</span></span> | |
| <h1 class="headline">Code is action.<br/><span class="accent">Govern it, or it governs you.</span></h1> | |
| <p class="support">a11oy is the <b style="color:var(--cream)">governed substrate</b> beneath the mission: | |
| every autonomous decision is checked against authorized limits, <span style="color:var(--live)">ALLOWED</span> | |
| or <span style="color:var(--err)">BLOCKED</span> at the exact line it crosses, and sealed into a signed, | |
| tamper-evident receipt you can re-verify on screen. <b style="color:var(--cream)">Five mission surfaces</b> | |
| sit over a deeper catalog of <b style="color:var(--cream)">25 governed demos — 5 problems × 5 each</b>: | |
| Cannonico (drone oversight) is <span style="color:var(--live)">REAL TODAY</span>; the other four are honest | |
| <span style="color:var(--gold)">sample / roadmap</span> on the same proven substrate.</p> | |
| <button class="runall" id="runAll">▶ Run all five mission surfaces</button> | |
| <div class="stats"> | |
| <div class="stat"><div class="k">Surfaces live</div><div class="v" id="stLive">0 / 5</div></div> | |
| <div class="stat"><div class="k">Governed demos ran</div><div class="v teal" id="stDemos">0 / 25</div></div> | |
| <div class="stat"><div class="k">Records signed</div><div class="v teal" id="stSigned">0</div></div> | |
| <div class="stat"><div class="k">Re-verified</div><div class="v" id="stVerified">—</div></div> | |
| <div class="stat"><div class="k">Registry</div><div class="v teal" id="stReg">—</div></div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- THE WOW — governed code-as-action: ALLOW vs BLOCK -> signed receipt --> | |
| <div class="wow"> | |
| <div class="wow-card"> | |
| <div class="wow-eyebrow">The wow · governed code-as-action</div> | |
| <h2 class="wow-h">An AI tries to cross a line. <b>a11oy catches it at the line</b> — and signs the proof.</h2> | |
| <div class="wow-flow"> | |
| <span class="wow-step">request</span><span class="wow-arr">→</span> | |
| <span class="wow-step">read the rules</span><span class="wow-arr">→</span> | |
| <span class="wow-step">policy gate</span><span class="wow-arr">→</span> | |
| <span class="wow-step allow">ALLOW</span><span class="wow-arr">/</span><span class="wow-step block">BLOCK</span><span class="wow-arr">→</span> | |
| <span class="wow-step seal">signed receipt</span> | |
| </div> | |
| <p class="wow-sub">The same deny-by-default governed run the platform uses everywhere. Pick a scenario, | |
| watch it cross (or stay inside) an authorized parameter, then <b style="color:var(--cream)">Re-verify</b> | |
| the sealed record and <b style="color:var(--cream)">Tamper test</b> it — a single flipped byte returns | |
| <span class="mono" style="color:var(--err)">verified:false</span>.</p> | |
| <div class="wow-ctas"> | |
| <a class="wow-cta primary" href="#panel-oversight" id="wowJump">▶ See ALLOW vs BLOCK</a> | |
| <a class="wow-cta ghost" href="/signature-is-not-proof">Why a signature is not proof →</a> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- DOMAIN BAND — Army / Navy / Multi-domain, each a live surface --> | |
| <div class="domains"> | |
| <div class="domains-h">One governed core · every defense domain</div> | |
| <div class="dgrid"> | |
| <a class="dcard" href="/counter-uas"> | |
| <span class="dtag">Army · Counter-UAS</span> | |
| <span class="dt">Govern the engagement decision</span> | |
| <span class="dd">A drone is inbound and an autonomous system wants to act. The governed gate holds any | |
| engagement outside the authorized zone or without human authorization — and seals the held decision.</span> | |
| <span class="dmat">LIVE surface · adversary catalog + legal/cyber boundary</span> | |
| <span class="dlink">Open counter-UAS</span> | |
| </a> | |
| <a class="dcard" href="/cued-engagement"> | |
| <span class="dtag">Navy · Maritime</span> | |
| <span class="dt">Cue, assess, and seal the track</span> | |
| <span class="dd">Paste any maritime or orbital track and place it in an operational picture instantly — | |
| assessed against real envelopes, anomalies flagged, no bespoke per-source integration.</span> | |
| <span class="dmat">LIVE surface · cued-engagement + Trajectory Picture below</span> | |
| <span class="dlink">Open cued engagement</span> | |
| </a> | |
| <a class="dcard" href="#panel-edge"> | |
| <span class="dtag">Joint · Multi-domain compute</span> | |
| <span class="dt">Governed decisions at the disconnected edge</span> | |
| <span class="dd">The whole governed run executes in-image with no uplink, the on-device router picks a tier, | |
| and the same container is the UDS bundle that deploys cloud-to-edge with one command.</span> | |
| <span class="dmat">LIVE surface · in-image Edge Run + Deploy Posture</span> | |
| <span class="dlink">Run on the edge</span> | |
| </a> | |
| </div> | |
| </div> | |
| <!-- PROOF — signature is not proof / cosign --> | |
| <div class="proof"> | |
| <div class="proof-card"> | |
| <div class="pc-l"> | |
| <h3 class="pc-h">A signature proves <b>who signed</b>, not <b>what is true</b>.</h3> | |
| <p class="pc-d">a11oy seals every governed decision into a real DSSE envelope signed by an in-image | |
| ECDSA-P256 key — verifiable against <code>/cosign.pub</code>, tamper-evident byte-for-byte. But a | |
| green signature is not a green outcome: re-verification recomputes the hash chain independently, and the | |
| advisory Λ trust score is a research conjecture, not a pass/fail oracle.</p> | |
| </div> | |
| <div class="pc-r"> | |
| <a class="wow-cta ghost" href="/signature-is-not-proof">Read the case study →</a> | |
| <a class="wow-cta ghost" href="/cosign.pub">Fetch the public key →</a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="tabs-bar" id="tabsBar"> | |
| <button class="tab-btn active" data-tab="oversight"><span class="dot" id="dot-oversight"></span>AI Oversight</button> | |
| <button class="tab-btn" data-tab="deploy"><span class="dot" id="dot-deploy"></span>Deploy Posture</button> | |
| <button class="tab-btn" data-tab="health"><span class="dot" id="dot-health"></span>Mission Health</button> | |
| <button class="tab-btn" data-tab="trajectory"><span class="dot" id="dot-trajectory"></span>Trajectory Picture</button> | |
| <button class="tab-btn" data-tab="edge"><span class="dot" id="dot-edge"></span>Edge Run</button> | |
| </div> | |
| <div class="panel-wrap"> | |
| <!-- 1. AI OVERSIGHT --> | |
| <section class="panel active" id="panel-oversight"> | |
| <div class="p-head"> | |
| <h2 class="p-title">AI Oversight</h2> | |
| <p class="p-blurb">Watch an autonomous system make a decision and catch the exact moment it crosses an | |
| authorized limit. Every run is sealed into a signed, tamper-evident record — press <b>Re-verify</b> to | |
| confirm it, then <b>Tamper test</b> to prove a single changed byte is detected.</p> | |
| </div> | |
| <div class="seg" id="ovrSeg"> | |
| <button class="r-btn sel" data-sc="within">Within limits</button> | |
| <button class="r-btn" data-sc="crossing">Crosses the line</button> | |
| <button class="r-btn" data-sc="drift">Borderline</button> | |
| </div> | |
| <div class="card-controls"> | |
| <button class="r-btn r-btn-primary" id="ovrRun">▶ Run governed decision</button> | |
| <button class="r-btn" id="ovrVerify" disabled>✓ Re-verify record</button> | |
| <button class="r-btn" id="ovrTamper" disabled>⚠ Tamper test</button> | |
| </div> | |
| <div id="ovrVerdict" class="verdict"></div> | |
| <div id="ovrCrossed"></div> | |
| <ul class="tl" id="ovrTimeline"></ul> | |
| <div class="out"> | |
| <div class="out-label"><span>Signed record</span> | |
| <span class="out-status"><span class="status-dot" id="ovrDot"></span><span id="ovrStatus">idle</span></span></div> | |
| <pre class="out-pre" id="ovrOut"></pre> | |
| </div> | |
| <p class="sub" id="ovrSub"></p> | |
| </section> | |
| <!-- 2. DEPLOY POSTURE --> | |
| <section class="panel" id="panel-deploy"> | |
| <div class="p-head"> | |
| <h2 class="p-title">Deploy Posture</h2> | |
| <p class="p-blurb">The signed, ready-to-ship deployment package — the same artifact deploys from cloud to | |
| a disconnected edge node with one command. Existence, digest and signature are read <b>live from the public | |
| registry</b> on each click, not asserted from memory.</p> | |
| </div> | |
| <div class="card-controls"> | |
| <button class="r-btn r-btn-primary" id="depRun">▶ Check deploy posture (live)</button> | |
| </div> | |
| <div id="depVerdict" class="verdict"></div> | |
| <div id="depBody"></div> | |
| <div class="out"> | |
| <div class="out-label"><span>Registry response</span> | |
| <span class="out-status"><span class="status-dot" id="depDot"></span><span id="depStatus">idle</span></span></div> | |
| <pre class="out-pre" id="depOut"></pre> | |
| </div> | |
| </section> | |
| <!-- 3. MISSION HEALTH --> | |
| <section class="panel" id="panel-health"> | |
| <div class="p-head"> | |
| <h2 class="p-title">Mission Health</h2> | |
| <p class="p-blurb">A live readiness dashboard that tells you who is ready to deploy and who needs review. | |
| Each verdict is computed in-image from concrete readiness criteria; <b>missing data forces a review</b> — | |
| the system never assumes a member is ready.</p> | |
| </div> | |
| <div class="card-controls"> | |
| <button class="r-btn r-btn-primary" id="hlRun">▶ Generate readiness dashboard</button> | |
| </div> | |
| <div class="kpis" id="hlKpis"></div> | |
| <div id="hlBody"></div> | |
| <div class="out"> | |
| <div class="out-label"><span>Computed in-image</span> | |
| <span class="out-status"><span class="status-dot" id="hlDot"></span><span id="hlStatus">idle</span></span></div> | |
| <pre class="out-pre" id="hlOut"></pre> | |
| </div> | |
| </section> | |
| <!-- 4. TRAJECTORY PICTURE --> | |
| <section class="panel" id="panel-trajectory"> | |
| <div class="p-head"> | |
| <h2 class="p-title">Trajectory Picture</h2> | |
| <p class="p-blurb">Paste any trajectory or orbit data — a JSON array or plain rows — and see it placed | |
| in an operational 3D picture instantly. The system auto-detects the fields, assesses each track against real | |
| orbital-regime envelopes, and flags anomalies. <b>No bespoke per-source integration.</b></p> | |
| </div> | |
| <div class="field"> | |
| <label>Paste tracks (JSON array, or rows: <span class="mono">id alt_km velocity_kms inclination_deg</span>) — or leave blank for a sample</label> | |
| <textarea class="ta" id="trajIn" placeholder='[{"id":"ISS","alt_km":420,"velocity_kms":7.66,"inclination_deg":51.6}] | |
| or | |
| SAT-A 550 7.59 53.0 | |
| SAT-B 35786 3.07 0.0'></textarea> | |
| </div> | |
| <div class="card-controls"> | |
| <button class="r-btn r-btn-primary" id="trajRun">▶ Build trajectory picture</button> | |
| <button class="r-btn" id="trajSample">Load sample</button> | |
| </div> | |
| <div id="trajVerdict" class="verdict"></div> | |
| <canvas id="trajCanvas"></canvas> | |
| <div class="leg"> | |
| <span><b style="background:#5fb3a3"></b>LEO</span> | |
| <span><b style="background:#c9b787"></b>MEO</span> | |
| <span><b style="background:#7aa0d0"></b>GEO</span> | |
| <span><b style="background:#b06a5a"></b>anomalous</span> | |
| <span class="mono">drag to rotate</span> | |
| </div> | |
| <div id="trajBody"></div> | |
| <div class="out"> | |
| <div class="out-label"><span>Assessment</span> | |
| <span class="out-status"><span class="status-dot" id="trajDot"></span><span id="trajStatus">idle</span></span></div> | |
| <pre class="out-pre" id="trajOut"></pre> | |
| </div> | |
| </section> | |
| <!-- 5. EDGE RUN --> | |
| <section class="panel" id="panel-edge"> | |
| <div class="p-head"> | |
| <h2 class="p-title">Edge Run</h2> | |
| <p class="p-blurb">The whole governed decision running on the device itself, with no connection required. The | |
| run executes <b>fully in this container</b> with no outbound call, the on-device model router picks a tier, | |
| and the result is signed and re-verifiable — the same container is the package that deploys to a | |
| disconnected node.</p> | |
| </div> | |
| <div class="card-controls"> | |
| <button class="r-btn r-btn-primary" id="edgeRun">▶ Run on the edge (disconnected)</button> | |
| <button class="r-btn" id="edgeVerify" disabled>✓ Re-verify record</button> | |
| </div> | |
| <div id="edgeVerdict" class="verdict"></div> | |
| <div id="edgeRouter"></div> | |
| <ul class="tl" id="edgeTimeline"></ul> | |
| <div class="out"> | |
| <div class="out-label"><span>In-image governed run</span> | |
| <span class="out-status"><span class="status-dot" id="edgeDot"></span><span id="edgeStatus">idle</span></span></div> | |
| <pre class="out-pre" id="edgeOut"></pre> | |
| </div> | |
| <p class="sub" id="edgeSub"></p> | |
| </section> | |
| </div> | |
| <!-- ==================================================================== | |
| 25-DEMO DEPTH — the 5 mission surfaces above are the polished front | |
| door; this section exposes the FULL governed catalog: 5 approved | |
| problems x 5 demos = 25. Loaded live from /warhacker/index and run | |
| live against /warhacker/run/{problem}/{demo}. Honest labels per the | |
| operator's OWN real_or_roadmap field: CANNONICO = REAL TODAY; the | |
| other four = ROADMAP (proven substrate, SAMPLE vertical). Every demo | |
| emits a signed receipt and is re-verifiable in-browser; the tamper | |
| button flips one byte and the same chain reports the break. | |
| ==================================================================== --> | |
| <section class="depth" id="depth"> | |
| <div class="depth-head"> | |
| <div class="depth-eyebrow">Mission depth · 5 problems × 5 demos</div> | |
| <h2 class="depth-h">Five surfaces. <b>Twenty-five governed demos</b> underneath.</h2> | |
| <p class="depth-sub">Each of the five approved problems carries five governed demos — <b style="color:var(--cream)">25 in total</b>, | |
| loaded live from the platform and runnable right here. Each run computes a real mechanism in-image and seals a signed, | |
| re-verifiable receipt; press <b style="color:var(--cream)">Tamper</b> and one flipped byte returns | |
| <span class="mono" style="color:var(--err)">verified:false</span>. Labels are the operator's own: | |
| <span class="lbl real" style="display:inline-block">real today</span> for Cannonico, | |
| <span class="lbl roadmap" style="display:inline-block">roadmap</span> (proven substrate · sample vertical) for the rest. Nothing here claims more than it is.</p> | |
| </div> | |
| <div id="depthList"> | |
| <p class="mono" id="depthLoading" style="text-align:center;color:var(--dim);font-size:12px;">— loading the 25-demo catalog from the live platform —</p> | |
| </div> | |
| </section> | |
| <div class="honest"> | |
| <div class="honest-box" id="honestBox"> | |
| <b>What is real here (doctrine v11 · honest labels only).</b> Every surface above runs live in this container. | |
| Governed decisions are sealed into real DSSE envelopes signed by an in-image ECDSA-P256 key (verifiable against | |
| <a href="/cosign.pub" style="color:var(--teal)">/cosign.pub</a>); change one byte and re-verify returns false. | |
| The live status ribbon is pulled from real a11oy endpoints on this Space at load — energy figures carry a | |
| <span class="lr-tag measured" style="display:inline">MEASURED</span> / | |
| <span class="lr-tag sample" style="display:inline">SAMPLE</span> label straight from the operator, and a | |
| <span class="lr-tag nolive" style="display:inline">NO-LIVE-DATA</span> label if an endpoint is unreachable. We never | |
| fabricate a joule, a job count, or a 200. The advisory trust score (Λ) is Conjecture 1 — a research | |
| conjecture, not a pass/fail oracle. Locked-proven invariants = 8. Deploy posture is read live from the public | |
| registry. Attestation is honest SLSA L1; the L2 build-provenance .att is emitted (not independently verified here); | |
| L3 is roadmap — not the bundle, not an ATO. Mission Health and Trajectory Picture use clearly-labelled sample | |
| inputs over real logic; plug a real feed into the same shape and they are live. The <b>25-demo depth</b> below | |
| (5 problems × 5 demos) is the full governed catalog: <b>CANNONICO is REAL TODAY</b>; the other four problems | |
| (Tychee, Hangar2Apps, Cyber-RTS, Raven) are <b>ROADMAP</b> — the proven horizontal substrate (hash chain + | |
| Merkle + DSSE + the computed formula) is real, while each vertical runs on clearly-labelled SAMPLE data pending the | |
| operational stand-up (live feed / hardware / ATO). Every one of the 25 emits a real signed receipt and a 1-byte | |
| tamper test that fails cryptographically. We never imply all 25 are fully real. | |
| </div> | |
| </div> | |
| <footer class="footer"><span class="note">a11oy · SZL Holdings · in-image · signed · re-verifiable</span></footer> | |
| <script> | |
| (function(){ | |
| "use strict"; | |
| // API base: the /api/a11oy/v1 form is what the Node proxy forwards; the stripped | |
| // /v1 form is reachable directly. Try /api first, fall back to /v1. | |
| var BASES = ["/api/a11oy/v1", "/v1"]; | |
| function api(path, opts){ | |
| var i = 0; | |
| function attempt(){ | |
| return fetch(BASES[i] + path, opts).then(function(r){ | |
| if(!r.ok && r.status === 404 && i < BASES.length-1){ i++; return attempt(); } | |
| return r.json().then(function(j){ return {ok:r.ok, status:r.status, json:j}; }); | |
| }).catch(function(e){ | |
| if(i < BASES.length-1){ i++; return attempt(); } | |
| throw e; | |
| }); | |
| } | |
| return attempt(); | |
| } | |
| function getJSON(p){ return api(p, {method:"GET"}); } | |
| function postJSON(p, body){ | |
| return api(p, {method:"POST", headers:{"Content-Type":"application/json"}, body:JSON.stringify(body||{})}); | |
| } | |
| var $ = function(id){ return document.getElementById(id); }; | |
| function setDot(id, state){ var d=$(id); if(d){ d.className = "dot" + (state?(" "+state):""); } } | |
| function setStatus(dotId, statusId, state, text){ | |
| var d=$(dotId); if(d) d.className="status-dot"+(state?(" "+state):""); | |
| var s=$(statusId); if(s) s.textContent=text||state||""; | |
| } | |
| function show(el, cls, html){ el.className = el.className.split(" ")[0] + " " + cls + " show"; el.innerHTML = html; } | |
| function pretty(o){ return JSON.stringify(o, null, 2); } | |
| // ---------- tab switching ---------- | |
| var tabBtns = document.querySelectorAll(".tab-btn"); | |
| function activateTab(name){ | |
| var btn = document.querySelector('.tab-btn[data-tab="'+name+'"]'); | |
| if(!btn) return; | |
| tabBtns.forEach(function(x){ x.classList.remove("active"); }); | |
| btn.classList.add("active"); | |
| document.querySelectorAll(".panel").forEach(function(p){ p.classList.remove("active"); }); | |
| var panel = $("panel-"+name); if(panel) panel.classList.add("active"); | |
| if(name === "trajectory") drawTraj(); | |
| } | |
| tabBtns.forEach(function(b){ | |
| b.addEventListener("click", function(){ activateTab(b.dataset.tab); }); | |
| }); | |
| // WOW + domain-band anchors jump to the right tab AND scroll the tab strip into view. | |
| document.querySelectorAll('a[href^="#panel-"]').forEach(function(a){ | |
| a.addEventListener("click", function(e){ | |
| e.preventDefault(); | |
| var name = a.getAttribute("href").replace("#panel-",""); | |
| activateTab(name); | |
| var bar = $("tabsBar"); if(bar) bar.scrollIntoView({behavior:"smooth", block:"start"}); | |
| }); | |
| }); | |
| // ---------- shared run-state for the hero stats ---------- | |
| var state = {live:{}, signed:0, verified:null, demosRan:{}}; | |
| function refreshStats(){ | |
| var n = Object.keys(state.live).filter(function(k){return state.live[k];}).length; | |
| $("stLive").textContent = n + " / 5"; | |
| $("stSigned").textContent = state.signed; | |
| var dcount = Object.keys(state.demosRan).length; | |
| var dEl = $("stDemos"); if(dEl) dEl.textContent = dcount + " / 25"; | |
| if(state.verified !== null){ $("stVerified").textContent = state.verified ? "PASS" : "FAIL"; $("stVerified").className = "v " + (state.verified?"teal":""); } | |
| } | |
| function markLive(tab, ok){ state.live[tab]= ok; setDot("dot-"+tab, ok?"ok":"err"); refreshStats(); } | |
| // ---------- helper: render a governed-run timeline ---------- | |
| function renderTimeline(ulId, timeline){ | |
| var ul = $(ulId); ul.innerHTML = ""; | |
| (timeline||[]).forEach(function(t){ | |
| var li = document.createElement("li"); | |
| li.innerHTML = '<span class="ic '+(t.ok?"ok":"no")+'">'+(t.ok?"✓":"✕")+'</span>'+ | |
| '<span><span class="step">'+t.step+'</span> — <span class="det">'+t.detail+'</span></span>'; | |
| ul.appendChild(li); | |
| }); | |
| } | |
| function renderCrossed(elId, crossed){ | |
| var el = $(elId); | |
| if(!crossed || !crossed.length){ el.innerHTML=""; return; } | |
| var rows = crossed.map(function(c){ | |
| return '<div class="row"><b>'+c.name+'</b> — observed: '+c.observed+'; limit: '+c.limit+'</div>'; | |
| }).join(""); | |
| el.innerHTML = '<div class="crossed"><h4>Lines crossed (caught at the limit-check step)</h4>'+rows+'</div>'; | |
| } | |
| // ========== 1. AI OVERSIGHT ========== | |
| var ovrScenario = "within", lastRun = null; | |
| $("ovrSeg").querySelectorAll(".r-btn").forEach(function(b){ | |
| b.addEventListener("click", function(){ | |
| $("ovrSeg").querySelectorAll(".r-btn").forEach(function(x){x.classList.remove("sel");}); | |
| b.classList.add("sel"); ovrScenario = b.dataset.sc; | |
| }); | |
| }); | |
| function ovrRun(){ | |
| setStatus("ovrDot","ovrStatus","loading","running…"); | |
| $("ovrVerify").disabled=true; $("ovrTamper").disabled=true; | |
| return postJSON("/oversight/run", {scenario: ovrScenario}).then(function(r){ | |
| var d = r.json; lastRun = d; | |
| renderTimeline("ovrTimeline", d.timeline); | |
| renderCrossed("ovrCrossed", d.crossed_lines); | |
| var v = $("ovrVerdict"); | |
| if(d.decision === "ALLOW"){ show(v,"ok", "ALLOW — "+d.headline); } | |
| else { show(v,"err", "BLOCK — "+d.headline); } | |
| $("ovrOut").textContent = pretty(d.signed_record); | |
| setStatus("ovrDot","ovrStatus","ok","sealed + signed"); | |
| $("ovrSub").textContent = d.honesty || ""; | |
| $("ovrVerify").disabled=false; $("ovrTamper").disabled=false; | |
| if(d.signed_record && d.signed_record.signed) state.signed++; | |
| markLive("oversight", true); refreshStats(); | |
| return d; | |
| }).catch(function(e){ setStatus("ovrDot","ovrStatus","err","error"); $("ovrOut").textContent=String(e); markLive("oversight",false); }); | |
| } | |
| function ovrVerify(tamper){ | |
| if(!lastRun) return; | |
| var run = JSON.parse(JSON.stringify(lastRun)); | |
| if(tamper){ | |
| // flip a byte in a receipt body to prove detection | |
| if(run.receipt_chain && run.receipt_chain.length>2){ run.receipt_chain[2].body.allow = !run.receipt_chain[2].body.allow; } | |
| } | |
| setStatus("ovrDot","ovrStatus","loading","verifying…"); | |
| return postJSON("/oversight/verify", {run: run}).then(function(r){ | |
| var v = r.json; var vd = $("ovrVerdict"); | |
| if(tamper){ | |
| show(vd, "err", "TAMPER TEST — verified:false (chain break at receipt #"+v.chain_break_at_seq+"). A single changed byte is caught."); | |
| setStatus("ovrDot","ovrStatus","err","tamper detected"); | |
| state.verified = false; | |
| } else { | |
| show(vd, "ok", "RE-VERIFIED — verified:"+v.verified+" · chain intact:"+v.chain_intact+" · signature valid:"+v.signature_valid); | |
| setStatus("ovrDot","ovrStatus","ok","verified PASS"); | |
| state.verified = v.verified; | |
| } | |
| $("ovrOut").textContent = pretty(v); refreshStats(); | |
| }).catch(function(e){ setStatus("ovrDot","ovrStatus","err","error"); $("ovrOut").textContent=String(e); }); | |
| } | |
| $("ovrRun").addEventListener("click", function(){ ovrRun(); }); | |
| $("ovrVerify").addEventListener("click", function(){ ovrVerify(false); }); | |
| $("ovrTamper").addEventListener("click", function(){ ovrVerify(true); }); | |
| // ========== 2. DEPLOY POSTURE ========== | |
| function depRun(){ | |
| setStatus("depDot","depStatus","loading","reading registry…"); | |
| return getJSON("/deploy/posture").then(function(r){ | |
| var d = r.json; | |
| var pub = (d.bundles||[]).filter(function(b){return b.published;}).length; | |
| var rows = (d.bundles||[]).map(function(b){ | |
| return '<tr><td><b>'+b.name+'</b><br><span class="mono" style="color:var(--muted);font-size:10px">'+b.ref+'</span></td>'+ | |
| '<td><span class="pill '+(b.published?"go":"nogo")+'">'+(b.published?"HTTP "+b.registry_status:"unreachable")+'</span></td>'+ | |
| '<td class="mono" style="font-size:9.5px;color:var(--teal)">'+((b.digest||"").slice(0,23))+'…</td>'+ | |
| '<td>'+(b.cosign_signature_tag?'<span class="pill go">signed</span>':'—')+'</td></tr>'; | |
| }).join(""); | |
| $("depBody").innerHTML = | |
| '<table class="t"><thead><tr><th>Bundle</th><th>Registry</th><th>Digest</th><th>Cosign</th></tr></thead><tbody>'+rows+'</tbody></table>'+ | |
| '<div class="gap"></div>'+ | |
| '<div class="kpis">'+ | |
| '<div class="kpi"><div class="k">One-command deploy</div><div class="v teal mono" style="font-size:11px;line-height:1.5">'+d.deploy_one_command+'</div></div>'+ | |
| '</div>'+ | |
| '<div class="gap"></div>'+ | |
| '<table class="t"><tbody>'+ | |
| '<tr><td>Package CR</td><td>'+d.package_cr.apiVersion+' · '+d.package_cr.kind+'</td></tr>'+ | |
| '<tr><td>SBOM</td><td>'+d.sbom.formats.join(" + ")+'</td></tr>'+ | |
| '<tr><td>Image attestation</td><td>'+d.attestation.image_level+'</td></tr>'+ | |
| '<tr><td>Bundle provenance</td><td>'+d.attestation.bundle_level+'</td></tr>'+ | |
| '<tr><td>Not claimed</td><td class="mono" style="font-size:10px">'+d.attestation.not_claimed.join(" · ")+'</td></tr>'+ | |
| '<tr><td>UDS Core compat</td><td>'+d.uds_core_compat+'</td></tr>'+ | |
| '</tbody></table>'; | |
| show($("depVerdict"), pub>=1?"ok":"err", pub+" / "+(d.bundles||[]).length+" bundles published & signed on the registry"); | |
| $("depOut").textContent = pretty(d.bundles); | |
| setStatus("depDot","depStatus","ok","live from registry"); | |
| $("stReg").textContent = pub>=1 ? "200 OK" : "down"; | |
| markLive("deploy", pub>=1); | |
| }).catch(function(e){ setStatus("depDot","depStatus","err","error"); $("depOut").textContent=String(e); markLive("deploy",false); }); | |
| } | |
| $("depRun").addEventListener("click", function(){ depRun(); }); | |
| // ========== 3. MISSION HEALTH ========== | |
| function hlRun(){ | |
| setStatus("hlDot","hlStatus","loading","computing…"); | |
| return getJSON("/mission/health").then(function(r){ | |
| var d = r.json, s = d.summary; | |
| $("hlKpis").innerHTML = | |
| '<div class="kpi"><div class="k">Ready (GO)</div><div class="v live">'+s.go+'</div></div>'+ | |
| '<div class="kpi"><div class="k">Review</div><div class="v">'+s.review+'</div></div>'+ | |
| '<div class="kpi"><div class="k">Not ready</div><div class="v err">'+s.no_go+'</div></div>'+ | |
| '<div class="kpi"><div class="k">% Ready</div><div class="v teal">'+s.percent_ready+'%</div></div>'; | |
| var rows = (d.members||[]).map(function(m){ | |
| var pc = m.verdict==="GO"?"go":(m.verdict==="REVIEW"?"review":"nogo"); | |
| var gaps = (m.gaps||[]).map(function(g){return g.criterion+": "+g.result;}).join("; ") || "all current"; | |
| return '<tr><td class="mono">'+m.id+'</td><td>'+m.unit+'</td><td>'+m.role+'</td>'+ | |
| '<td><span class="pill '+pc+'">'+m.verdict+'</span></td><td style="font-size:10.5px">'+gaps+'</td></tr>'; | |
| }).join(""); | |
| $("hlBody").innerHTML = '<table class="t"><thead><tr><th>ID</th><th>Unit</th><th>Role</th><th>Verdict</th><th>Gaps</th></tr></thead><tbody>'+rows+'</tbody></table>'; | |
| $("hlOut").textContent = pretty(d.summary)+"\n\nby unit: "+pretty(d.by_unit); | |
| setStatus("hlDot","hlStatus","ok","computed in-image"); | |
| markLive("health", true); | |
| }).catch(function(e){ setStatus("hlDot","hlStatus","err","error"); $("hlOut").textContent=String(e); markLive("health",false); }); | |
| } | |
| $("hlRun").addEventListener("click", function(){ hlRun(); }); | |
| // ========== 4. TRAJECTORY PICTURE ========== | |
| var trajTracks = [], rot = {x: -0.5, y: 0.6}, dragging=false, lastXY=null; | |
| function trajRun(){ | |
| setStatus("trajDot","trajStatus","loading","ingesting…"); | |
| var raw = $("trajIn").value.trim(); | |
| var body = raw ? {data: raw} : {}; | |
| return postJSON("/trajectory/ingest", body).then(function(r){ | |
| var d = r.json; trajTracks = d.tracks || []; | |
| var rows = trajTracks.map(function(t){ | |
| var a = t.assessment || {}; var pc = a.verdict==="NOMINAL"?"nominal":(a.verdict==="ANOMALOUS"?"anomalous":"insufficient"); | |
| return '<tr><td class="mono">'+t.id+'</td><td>'+(t.alt_km!=null?t.alt_km+" km":"—")+'</td>'+ | |
| '<td>'+(t.velocity_kms!=null?t.velocity_kms+" km/s":"—")+'</td><td>'+(a.regime||"—")+'</td>'+ | |
| '<td><span class="pill '+pc+'">'+(a.verdict||"—")+'</span></td>'+ | |
| '<td style="font-size:10px">'+((a.flags||[]).join("; ")||"—")+'</td></tr>'; | |
| }).join(""); | |
| $("trajBody").innerHTML = '<table class="t"><thead><tr><th>Track</th><th>Alt</th><th>Velocity</th><th>Regime</th><th>Verdict</th><th>Flags</th></tr></thead><tbody>'+rows+'</tbody></table>'; | |
| show($("trajVerdict"), (d.summary.ANOMALOUS>0?"warn":"ok"), d.headline); | |
| $("trajOut").textContent = pretty(d.summary); | |
| setStatus("trajDot","trajStatus","ok","assessed"); | |
| markLive("trajectory", true); | |
| drawTraj(); | |
| }).catch(function(e){ setStatus("trajDot","trajStatus","err","error"); $("trajOut").textContent=String(e); markLive("trajectory",false); }); | |
| } | |
| // sovereign 3D: orthographic projection on canvas, no external libs | |
| function drawTraj(){ | |
| var cv = $("trajCanvas"); if(!cv) return; | |
| var dpr = window.devicePixelRatio||1; | |
| var w = cv.clientWidth, h = cv.clientHeight; | |
| cv.width = w*dpr; cv.height = h*dpr; | |
| var ctx = cv.getContext("2d"); ctx.scale(dpr,dpr); | |
| ctx.clearRect(0,0,w,h); | |
| var cx=w/2, cy=h/2, Rearth=38; | |
| function proj(x,y,z){ | |
| var cyaw=Math.cos(rot.y), syaw=Math.sin(rot.y), cp=Math.cos(rot.x), sp=Math.sin(rot.x); | |
| var x1=x*cyaw - z*syaw, z1=x*syaw + z*cyaw; | |
| var y1=y*cp - z1*sp, z2=y*sp + z1*cp; | |
| var scale = 320/(320+z2); | |
| return [cx + x1*scale, cy - y1*scale, z2]; | |
| } | |
| // earth sphere | |
| var ep = proj(0,0,0); | |
| var g = ctx.createRadialGradient(ep[0]-10, ep[1]-10, 4, ep[0], ep[1], Rearth); | |
| g.addColorStop(0,"#2a4a6a"); g.addColorStop(1,"#0a1828"); | |
| ctx.beginPath(); ctx.arc(ep[0],ep[1],Rearth,0,2*Math.PI); ctx.fillStyle=g; ctx.fill(); | |
| ctx.strokeStyle="rgba(95,179,163,0.3)"; ctx.stroke(); | |
| // regime rings (radii scaled by log of altitude) | |
| function ringR(alt){ return Rearth + 26*Math.log10(1 + alt/300); } | |
| [{a:1000,c:"rgba(95,179,163,0.25)"},{a:20000,c:"rgba(201,183,135,0.22)"},{a:35786,c:"rgba(122,160,208,0.25)"}].forEach(function(rg){ | |
| var rr=ringR(rg.a); ctx.beginPath(); | |
| for(var t=0;t<=64;t++){ var th=t/64*2*Math.PI; var p=proj(rr*Math.cos(th),0,rr*Math.sin(th)); if(t===0)ctx.moveTo(p[0],p[1]);else ctx.lineTo(p[0],p[1]); } | |
| ctx.strokeStyle=rg.c; ctx.lineWidth=1; ctx.stroke(); | |
| }); | |
| // tracks: place each on its regime ring by inclination + a hash of id for spread | |
| (trajTracks||[]).forEach(function(t,i){ | |
| if(t.alt_km==null) return; | |
| var rr = ringR(t.alt_km); | |
| var inc = (t.inclination_deg!=null? t.inclination_deg: 30) * Math.PI/180; | |
| var ang = (i/Math.max(1,trajTracks.length))*2*Math.PI + 0.3; | |
| var x = rr*Math.cos(ang), z = rr*Math.sin(ang), y = rr*Math.sin(inc)*0.4*Math.sin(ang*1.3); | |
| var p = proj(x,y,z); | |
| var a = t.assessment||{}; | |
| var col = a.verdict==="ANOMALOUS" ? "#b06a5a" : | |
| (a.regime==="LEO"?"#5fb3a3": a.regime==="MEO"?"#c9b787": a.regime==="GEO"?"#7aa0d0":"#9a9a9a"); | |
| ctx.beginPath(); ctx.arc(p[0],p[1],4.5,0,2*Math.PI); ctx.fillStyle=col; ctx.fill(); | |
| ctx.shadowColor=col; ctx.shadowBlur=8; ctx.fill(); ctx.shadowBlur=0; | |
| ctx.fillStyle="rgba(245,245,245,0.85)"; ctx.font="9px 'JetBrains Mono',monospace"; | |
| ctx.fillText(t.id, p[0]+7, p[1]+3); | |
| }); | |
| } | |
| (function bindDrag(){ | |
| var cv = $("trajCanvas"); | |
| cv.addEventListener("mousedown", function(e){ dragging=true; lastXY=[e.clientX,e.clientY]; }); | |
| window.addEventListener("mouseup", function(){ dragging=false; }); | |
| window.addEventListener("mousemove", function(e){ | |
| if(!dragging||!lastXY) return; | |
| rot.y += (e.clientX-lastXY[0])*0.01; rot.x += (e.clientY-lastXY[1])*0.01; | |
| lastXY=[e.clientX,e.clientY]; drawTraj(); | |
| }); | |
| window.addEventListener("resize", function(){ drawTraj(); }); | |
| })(); | |
| $("trajRun").addEventListener("click", function(){ trajRun(); }); | |
| $("trajSample").addEventListener("click", function(){ | |
| getJSON("/trajectory/sample").then(function(r){ $("trajIn").value = JSON.stringify(r.json.sample, null, 2); }); | |
| }); | |
| // ========== 5. EDGE RUN ========== | |
| var edgeLast = null; | |
| function edgeRun(){ | |
| setStatus("edgeDot","edgeStatus","loading","running on edge…"); | |
| $("edgeVerify").disabled=true; | |
| return postJSON("/edge/run", {connected:false}).then(function(r){ | |
| var d = r.json; edgeLast = d; | |
| renderTimeline("edgeTimeline", d.timeline); | |
| var ed = d.edge || {}; | |
| var mr = ed.model_router || {}; | |
| $("edgeRouter").innerHTML = | |
| '<div class="kpis">'+ | |
| '<div class="kpi"><div class="k">Ran where</div><div class="v teal" style="font-size:12px;line-height:1.4">in-image · no uplink</div></div>'+ | |
| '<div class="kpi"><div class="k">Model tier</div><div class="v" style="font-size:13px">'+(mr.picked||"—")+'</div></div>'+ | |
| '<div class="kpi"><div class="k">Decision</div><div class="v '+(d.decision==="ALLOW"?"live":"err")+'" style="font-size:14px">'+d.decision+'</div></div>'+ | |
| '</div>'+ | |
| '<table class="t"><tbody>'+ | |
| '<tr><td>Router policy</td><td>'+(mr.policy||"")+'</td></tr>'+ | |
| '<tr><td>Deploy command</td><td class="mono" style="font-size:10px;color:var(--teal)">'+(ed.deploy_command||"")+'</td></tr>'+ | |
| '</tbody></table>'; | |
| show($("edgeVerdict"), d.decision==="ALLOW"?"ok":"err", | |
| (d.decision==="ALLOW"?"ALLOW":"BLOCK")+" — governed run completed fully in-image, no outbound call"); | |
| $("edgeOut").textContent = pretty({decision:d.decision, edge:ed, signed:!!(d.signed_record&&d.signed_record.signed)}); | |
| $("edgeSub").textContent = ed.honesty || ""; | |
| setStatus("edgeDot","edgeStatus","ok","in-image · signed"); | |
| $("edgeVerify").disabled=false; | |
| if(d.signed_record && d.signed_record.signed) state.signed++; | |
| markLive("edge", true); refreshStats(); | |
| }).catch(function(e){ setStatus("edgeDot","edgeStatus","err","error"); $("edgeOut").textContent=String(e); markLive("edge",false); }); | |
| } | |
| function edgeVerify(){ | |
| if(!edgeLast) return; | |
| setStatus("edgeDot","edgeStatus","loading","verifying…"); | |
| return postJSON("/oversight/verify", {run: edgeLast}).then(function(r){ | |
| var v = r.json; | |
| show($("edgeVerdict"), v.verified?"ok":"err", "RE-VERIFIED — verified:"+v.verified+" · signature valid:"+v.signature_valid); | |
| $("edgeOut").textContent = pretty(v); | |
| setStatus("edgeDot","edgeStatus", v.verified?"ok":"err", v.verified?"verified PASS":"FAIL"); | |
| }); | |
| } | |
| $("edgeRun").addEventListener("click", function(){ edgeRun(); }); | |
| $("edgeVerify").addEventListener("click", function(){ edgeVerify(); }); | |
| // ========== RUN ALL ========== | |
| $("runAll").addEventListener("click", function(){ | |
| var btn = $("runAll"); btn.disabled = true; btn.textContent = "running all five…"; | |
| ovrScenario = "crossing"; // show the dramatic line-crossing catch by default in run-all | |
| Promise.resolve() | |
| .then(ovrRun).then(function(){ return ovrVerify(false); }) | |
| .then(depRun).then(hlRun).then(function(){ $("trajIn").value=""; return trajRun(); }).then(edgeRun) | |
| .then(function(){ btn.disabled=false; btn.textContent="✓ all five ran — click any tab"; }) | |
| .catch(function(){ btn.disabled=false; btn.textContent="▶ Run all five"; }); | |
| }); | |
| // mark surfaces present on load (index probe) + size canvas | |
| getJSON("/warhacker-tabs/index").then(function(r){ | |
| if(r.json && r.json.ok){ /* surfaces present */ } | |
| }).catch(function(){}); | |
| // ========== LIVE STATUS RIBBON ========== | |
| // Pulls REAL numbers from live a11oy endpoints. Honest labels only: energy | |
| // figures carry the operator's own MEASURED/SAMPLE label; an unreachable | |
| // endpoint shows NO-LIVE-DATA. No value is ever fabricated. | |
| function lrSet(id, cls, html){ var e=$(id); if(!e) return; e.className = "lv "+(cls||""); e.innerHTML = html; } | |
| function fmtJ(v){ | |
| v = Number(v)||0; | |
| if(v >= 1e9) return (v/1e9).toFixed(2)+" GJ"; | |
| if(v >= 1e6) return (v/1e6).toFixed(2)+" MJ"; | |
| if(v >= 1e3) return (v/1e3).toFixed(2)+" kJ"; | |
| return v.toFixed(2)+" J"; | |
| } | |
| function loadRibbon(){ | |
| // Energy operator: running?, jobs_done, joules_measured_total (+label), nodes_computing. | |
| getJSON("/energy/operator/status").then(function(r){ | |
| var d = (r && r.json) || {}; | |
| if(!r || !r.ok || d.running === undefined){ throw new Error("no status"); } | |
| var running = !!d.running; | |
| lrSet("lrOp", running?"teal":"gold", | |
| (running?'<span class="live-dot"></span>RUNNING':"STANDBY")); | |
| lrSet("lrJobs", "teal", String(d.jobs_done!=null?d.jobs_done:0)); | |
| // Measured joules are the billable figure; show the operator's own label. | |
| var jm = Number(d.joules_measured_total)||0; | |
| var js = Number(d.joules_sample_total)||0; | |
| if(jm > 0){ | |
| lrSet("lrJoules", "teal", fmtJ(jm)+' <span class="lr-tag measured">'+(d.joules_measured_label||"MEASURED")+'</span>'); | |
| } else if(js > 0){ | |
| lrSet("lrJoules", "gold", fmtJ(js)+' <span class="lr-tag sample">'+(d.joules_sample_label||"SAMPLE")+'</span>'); | |
| } else { | |
| lrSet("lrJoules", "gold", '0 J <span class="lr-tag sample">none billed yet</span>'); | |
| } | |
| var nc = (d.nodes_computing||[]).length; | |
| lrSet("lrNodes", nc>0?"teal":"gold", String(nc)); | |
| lrSet("lrSub", running?"teal":"gold", | |
| (d.stub_mode? 'in-image <span class="lr-tag sample">STUB</span>' : "live operator")); | |
| }).catch(function(){ | |
| lrSet("lrOp","err",'<span class="lr-tag nolive">NO-LIVE-DATA</span>'); | |
| lrSet("lrJobs","pending","—"); lrSet("lrJoules","pending","—"); | |
| lrSet("lrNodes","pending","—"); lrSet("lrSub","pending","—"); | |
| }); | |
| // Locked proofs + doctrine: read the live healthz doctrine block to annotate the | |
| // locked-proofs cell with the canonical 749/14/163 @ c7c0ba17 lock. Locked-proven | |
| // count is the doctrine constant 8. Two shapes exist in the wild: | |
| // in-process: {"lock":"749/14/163","commit":"c7c0ba17"} | |
| // v1 proxy: {"doctrine":{"declarations":749,"axioms":14,"sorries":163,"replay_hash":"c7c0ba17"}} | |
| getJSON("/healthz").then(function(r){ | |
| var j = (r && r.json) || {}; | |
| var lock = j.lock, commit = j.commit; | |
| if(!lock && j.doctrine){ | |
| var d = j.doctrine; | |
| if(d.declarations!=null){ lock = d.declarations+"/"+d.axioms+"/"+d.sorries; } | |
| commit = commit || d.replay_hash; | |
| } | |
| var cell = $("lrLocked"); | |
| if(cell && lock){ cell.title = "doctrine v11 · "+lock+(commit?(" · replay "+commit):"")+" · Λ = Conjecture 1"; } | |
| }).catch(function(){ /* locked=8 is the doctrine constant; leave the cell as-is */ }); | |
| } | |
| loadRibbon(); | |
| // ========== 25-DEMO DEPTH (5 problems x 5 demos) ========== | |
| // Loads the live catalog from /warhacker/index and renders 5 collapsible | |
| // problem groups, each with its 5 demos. Each demo runs live against | |
| // /warhacker/run/{problem}/{demo}, shows the decision + signed receipt id, | |
| // and offers a tamper test (the API's own always-on 1-byte-flip negative | |
| // test). Honest labels come straight from the operator's real_or_roadmap. | |
| function esc(s){ return String(s==null?"":s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''').replace(/"/g,"""); } | |
| function lblClass(rr){ | |
| var s = String(rr||"").toUpperCase(); | |
| if(s.indexOf("REAL")===0 || s.indexOf("REAL TODAY")>=0) return "real"; | |
| if(s.indexOf("EXPERIMENTAL")>=0) return "exp"; | |
| return "roadmap"; | |
| } | |
| function lblText(rr){ | |
| var s = String(rr||"").toUpperCase(); | |
| if(s.indexOf("REAL")===0 || s.indexOf("REAL TODAY")>=0) return "REAL TODAY"; | |
| if(s.indexOf("EXPERIMENTAL")>=0) return "EXPERIMENTAL"; | |
| return "ROADMAP \u00b7 SAMPLE"; | |
| } | |
| function shortRR(rr){ | |
| // first sentence / clause, for the demo-level honesty line | |
| var s = String(rr||""); | |
| var cut = s.split(/[;\u2014]/)[0]; | |
| return cut.length>140 ? cut.slice(0,138)+"\u2026" : cut; | |
| } | |
| function depthRunDemo(prob, demo, mode, els){ | |
| els.verdict.className = "demo-verdict show"; | |
| els.verdict.innerHTML = '<span class="warn">' + (mode==="tamper"?"tamper run\u2026":"running\u2026") + '</span>'; | |
| els.runBtn.disabled = true; els.tamperBtn.disabled = true; | |
| return postJSON("/warhacker/run/"+prob+"/"+demo, {mode: mode}).then(function(r){ | |
| var d = r.json || {}; | |
| if(!d.ok){ | |
| els.verdict.innerHTML = '<span class="err">error \u2014 ' + esc(d.error || ("HTTP "+r.status)) + '</span>'; | |
| els.runBtn.disabled=false; els.tamperBtn.disabled=false; return; | |
| } | |
| // signed receipt id from the sealed DSSE envelope / chain | |
| var sealed = d.sealed || {}; | |
| var chainHash = (sealed.chain_hash || "").slice(0,16); | |
| var merkle = (sealed.merkle_root || "").slice(0,16); | |
| var signed = !!(sealed.envelope && sealed.envelope.signed); | |
| var tt = d.tamper_test || {}; | |
| var cs = d.chain_self || {}; | |
| var decClass = d.authorized ? "ok" : "err"; | |
| if(mode==="tamper"){ | |
| // surface the API's negative test result: a 1-byte flip breaks the chain | |
| els.verdict.innerHTML = '<span class="err">TAMPER \u2014 verified:false \u00b7 chain break at seq ' + | |
| esc(tt.chain_break_at_seq) + ' (field: ' + esc(tt.tamper && tt.tamper.field) + | |
| ', bytes changed: ' + esc(tt.tamper && tt.tamper.bytes_changed) + '). One flipped byte is caught.</span>'; | |
| state.verified = false; | |
| } else { | |
| els.verdict.innerHTML = '<span class="' + decClass + '">' + esc(d.decision || (d.authorized?"ALLOW":"BLOCK")) + | |
| '</span> \u2014 ' + esc(d.headline || "") + | |
| ' <span class="' + (cs.chain_intact?"ok":"err") + '">[re-verify: chain ' + (cs.chain_intact?"intact":"BROKEN") + ']</span>'; | |
| if(state.verified===null) state.verified = !!cs.chain_intact; | |
| } | |
| els.receipt.className = "demo-receipt show"; | |
| els.receipt.textContent = "signed receipt \u00b7 chain=" + chainHash + "\u2026 \u00b7 merkle=" + merkle + "\u2026 \u00b7 signed=" + signed + " \u00b7 mode=" + esc(d.mode); | |
| els.out.className = "demo-out show"; | |
| els.out.textContent = pretty({problem:d.problem, demo:d.demo, mode:d.mode, decision:d.decision, | |
| authorized:d.authorized, real_or_roadmap:d.real_or_roadmap, headline:d.headline, | |
| sealed:{signed:signed, chain_hash:sealed.chain_hash, merkle_root:sealed.merkle_root, chain_seq:sealed.chain_seq}, | |
| chain_self:cs, tamper_test:tt, honesty:d.honesty}); | |
| // count the demo as run (once, by key) and tally signed receipts | |
| var key = prob+"/"+demo; | |
| if(!state.demosRan[key]){ state.demosRan[key]=true; } | |
| if(mode!=="tamper" && signed){ state.signed++; } | |
| refreshStats(); | |
| els.runBtn.disabled=false; els.tamperBtn.disabled=false; | |
| }).catch(function(e){ | |
| els.verdict.innerHTML = '<span class="err">error \u2014 ' + esc(String(e)) + '</span>'; | |
| els.runBtn.disabled=false; els.tamperBtn.disabled=false; | |
| }); | |
| } | |
| function renderDepth(idx){ | |
| var problems = (idx && idx.problems) || []; | |
| var host = $("depthList"); | |
| host.innerHTML = ""; | |
| problems.forEach(function(p, pi){ | |
| var probEl = document.createElement("div"); | |
| probEl.className = "prob" + (pi===0 ? " open" : ""); // first (Cannonico) open by default | |
| var lc = lblClass(p.real_or_roadmap), lt = lblText(p.real_or_roadmap); | |
| var head = document.createElement("button"); | |
| head.type = "button"; head.className = "prob-head"; | |
| head.setAttribute("aria-expanded", pi===0 ? "true" : "false"); | |
| head.innerHTML = '<span class="chev">\u25b6</span>' + | |
| '<span class="prob-id">' + esc(p.id) + '</span>' + | |
| '<span class="prob-title">' + esc(p.title) + '</span>' + | |
| '<span class="lbl ' + lc + '">' + lt + '</span>' + | |
| '<span class="prob-count">' + esc(p.demo_count) + ' demos</span>'; | |
| head.addEventListener("click", function(){ | |
| var open = probEl.classList.toggle("open"); | |
| head.setAttribute("aria-expanded", open ? "true" : "false"); | |
| }); | |
| probEl.appendChild(head); | |
| var summary = document.createElement("div"); | |
| summary.className = "prob-summary"; | |
| summary.textContent = p.summary || ""; | |
| probEl.appendChild(summary); | |
| var demosWrap = document.createElement("div"); | |
| demosWrap.className = "demos"; | |
| (p.demos||[]).forEach(function(dm){ | |
| var demoEl = document.createElement("div"); | |
| demoEl.className = "demo"; | |
| var top = document.createElement("div"); top.className = "demo-top"; | |
| top.innerHTML = '<span class="demo-id">' + esc(dm.id) + '</span>' + | |
| '<span class="demo-title">' + esc(dm.title) + '</span>' + | |
| '<span class="lbl ' + lc + '">' + lt + '</span>'; | |
| var ctrls = document.createElement("div"); ctrls.className = "demo-ctrls"; | |
| var runBtn = document.createElement("button"); runBtn.className="r-btn r-btn-primary"; runBtn.textContent="\u25b6 Run"; | |
| var tamperBtn = document.createElement("button"); tamperBtn.className="r-btn"; tamperBtn.textContent="\u26a0 Tamper"; | |
| ctrls.appendChild(runBtn); ctrls.appendChild(tamperBtn); | |
| var verdict = document.createElement("div"); verdict.className="demo-verdict"; | |
| var receipt = document.createElement("div"); receipt.className="demo-receipt"; | |
| var out = document.createElement("pre"); out.className="demo-out"; | |
| var els = {runBtn:runBtn, tamperBtn:tamperBtn, verdict:verdict, receipt:receipt, out:out}; | |
| runBtn.addEventListener("click", function(){ depthRunDemo(p.key, dm.id, "nominal", els); }); | |
| tamperBtn.addEventListener("click", function(){ depthRunDemo(p.key, dm.id, "tamper", els); }); | |
| demoEl.appendChild(top); demoEl.appendChild(ctrls); | |
| demoEl.appendChild(verdict); demoEl.appendChild(receipt); demoEl.appendChild(out); | |
| demosWrap.appendChild(demoEl); | |
| }); | |
| probEl.appendChild(demosWrap); | |
| host.appendChild(probEl); | |
| }); | |
| } | |
| getJSON("/warhacker/index").then(function(r){ | |
| var idx = r.json; | |
| if(idx && idx.ok && idx.problems && idx.problems.length){ | |
| renderDepth(idx); | |
| } else { | |
| var ld = $("depthLoading"); if(ld) ld.textContent = "\u2014 25-demo catalog endpoint reachable but returned no problems \u2014"; | |
| } | |
| }).catch(function(){ | |
| var ld = $("depthLoading"); if(ld){ ld.style.color="var(--err)"; ld.textContent = "\u2014 NO-LIVE-DATA: 25-demo catalog endpoint unreachable \u2014"; } | |
| }); | |
| drawTraj(); | |
| })(); | |
| </script> | |
| </body> | |
| </html> | |