File size: 31,952 Bytes
4d8b8ef
 
 
05f6964
4d8b8ef
 
 
 
0c39450
4d8b8ef
 
 
 
 
05f6964
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05f6964
4d8b8ef
 
 
4b2fcaa
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
0c39450
 
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0c39450
4d8b8ef
 
 
 
 
 
4b2fcaa
4d8b8ef
 
 
 
 
 
 
 
 
 
05f6964
4d8b8ef
 
05f6964
4d8b8ef
 
 
05f6964
4d8b8ef
05f6964
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0c39450
 
 
 
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4b2fcaa
4d8b8ef
 
 
 
4b2fcaa
 
 
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05f6964
 
 
 
 
 
 
 
 
 
 
 
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05f6964
4d8b8ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
<!doctype html>
<html lang="en">
<head>
<!-- KILLINCHU / UDS EDITION — Command Center (ADDITIVE, self-contained, DESKTOP-FIRST).
     Sign: Yachay <yachay@szlholdings.dev> · Co-Authored-By: Perplexity Computer Agent.
     Optimized for 1280px+ workstation + the RTX 4060 Ti tower display. Single UDS
     front door: every call hits /api/killinchu/uds/v1/*. No build step, no external CDN
     (Cesium loaded from the Space's own /cesium/ bundle, same as the SPA). Honesty
     preserved: drone positions SIMULATED, geofence STATIC SNAPSHOT, Reasoning role
     organ_signed=false, Rekor not_submitted, fail-WARNING never fail-open.
     Doctrine v11 LOCKED 749/14/163. Λ Conjecture 1 is NOT a theorem. -->
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#0a0f1e">
<title>Killinchu / UDS Edition — Command Center</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M16 3 L27 27 L16 21 L5 27 Z' fill='%23d7b96b'/%3E%3C/svg%3E"/>
<link rel="stylesheet" href="/cesium/Widgets/widgets.css">
<script src="/cesium/Cesium.js"></script>
<style>
  :root{
    --bg:#070b14; --panel:#10151c; --panel2:#0d1119; --line:#3c4757; --line2:#1d2533;
    --txt:#f5f7fa; --muted:#9aa7b8; --faint:#5b6a7e;
    --gold:#d7b96b; --gold-2:#e4cf99; --teal:#5cc4bf; --green:#1f9d57; --warn:#d8932f; --red:#d65a5a;
    --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
    --sans:"Inter","IBM Plex Sans",ui-sans-serif,system-ui,sans-serif;
  }
  *{box-sizing:border-box}
  html,body{margin:0;background:var(--bg);color:var(--txt);font-family:var(--sans);font-size:14px;height:100%}
  body{height:100vh;overflow:hidden}
  a{color:var(--teal);text-decoration:none}
  .mono{font-family:var(--mono)}
  ::-webkit-scrollbar{width:9px;height:9px}::-webkit-scrollbar-thumb{background:#26303f;border-radius:5px}
  ::-webkit-scrollbar-track{background:transparent}

  /* App shell — desktop grid */
  .app{display:grid;grid-template-rows:52px 1fr;height:100vh}
  header{display:flex;align-items:center;gap:12px;padding:0 18px;background:linear-gradient(180deg,#0c1322,#0a0f1e);
    border-bottom:1px solid var(--line2);z-index:20}
  header .logo{width:24px;height:24px}
  header .ttl{font-weight:700;font-size:15px;letter-spacing:-.01em}
  header .ttl b{color:var(--gold)}
  header .chip{font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
    border:1px solid var(--line2);border-radius:7px;padding:4px 9px}
  header .chip .dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--green);margin-right:6px;
    vertical-align:middle;box-shadow:0 0 0 0 rgba(31,157,87,.6);animation:pulse 2.4s infinite}
  @keyframes pulse{0%{box-shadow:0 0 0 0 rgba(31,157,87,.55)}70%{box-shadow:0 0 0 8px rgba(31,157,87,0)}100%{box-shadow:0 0 0 0 rgba(31,157,87,0)}}
  header .sp{margin-left:auto}
  header .doc{font-family:var(--mono);font-size:10.5px;color:var(--muted)}
  header .doc b{color:var(--gold)}

  /* Main 3-column workstation layout: heroes/field LEFT-CENTER, globe CENTER, compliance RIGHT rail */
  .body{display:grid;grid-template-columns:340px 1fr 420px;height:100%;overflow:hidden}
  .col{overflow:auto;padding:14px}
  .col.center{padding:0;position:relative;border-left:1px solid var(--line2);border-right:1px solid var(--line2);display:grid;grid-template-rows:1fr auto}

  h2.sec{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:2px 0 11px;font-weight:700}

  /* Command Center superhero cards (top-left) */
  .heroes{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-bottom:16px}
  .hero{background:linear-gradient(158deg,var(--panel),var(--panel2));border:1px solid var(--line2);border-radius:12px;
    padding:11px;position:relative;overflow:hidden;transition:.18s}
  .hero::before{content:"";position:absolute;inset:0;background:radial-gradient(120% 80% at 88% -12%,rgba(92,196,191,.10),transparent 60%);pointer-events:none}
  .hero .ic{font-size:22px;line-height:1}
  .hero .nm{font-weight:700;font-size:13px;margin-top:6px}
  .hero .role{font-family:var(--mono);font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-top:2px}
  .hero .st{display:inline-flex;align-items:center;gap:5px;margin-top:8px;font-family:var(--mono);font-size:10px;color:var(--muted)}
  .hero .st .d{width:7px;height:7px;border-radius:50%;background:var(--faint)}
  .hero.ok{border-color:rgba(31,157,87,.35)} .hero.ok .st .d{background:var(--green)} .hero.ok .st{color:var(--teal)}
  .hero.amber .st .d{background:var(--warn)} .hero.red{border-color:rgba(214,90,90,.4)} .hero.red .st .d{background:var(--red)}
  .hero .lat{font-family:var(--mono);font-size:9px;color:var(--faint);margin-top:2px}
  .hero .badge{position:absolute;top:10px;right:10px;font-family:var(--mono);font-size:8px;padding:2px 5px;border-radius:5px;border:1px solid var(--line);color:var(--muted)}
  .hero .badge.signed{color:var(--green);border-color:rgba(31,157,87,.4)}
  .hero .badge.placeholder{color:var(--warn);border-color:rgba(216,147,47,.4)}

  /* Action panel */
  .panel{background:var(--panel);border:1px solid var(--line2);border-radius:12px;padding:13px;margin-bottom:14px}
  .field{margin-bottom:10px}
  .field label{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);margin-bottom:5px}
  select,input{width:100%;background:var(--panel2);border:1px solid var(--line2);color:var(--txt);border-radius:8px;padding:9px 10px;font-family:var(--sans);font-size:13px}
  .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;font-family:var(--sans);font-size:13px;font-weight:600;
    border-radius:9px;padding:10px 14px;border:1px solid var(--line);background:var(--panel);color:var(--txt);cursor:pointer;width:100%}
  .btn.primary{background:var(--gold);color:#10151c;border-color:var(--gold)}
  .btn.primary:hover{background:var(--gold-2)}
  .btn.ghost:hover{border-color:var(--teal);color:var(--teal)}
  .btn:disabled{opacity:.5;cursor:default}
  .btnrow{display:grid;gap:8px;margin-top:6px}

  .receipt{margin-top:11px;background:var(--panel2);border:1px solid var(--line2);border-radius:10px;padding:11px}
  .receipt .kv{display:flex;gap:8px;font-family:var(--mono);font-size:10.5px;padding:3px 0;border-bottom:1px solid var(--line2)}
  .receipt .kv:last-child{border-bottom:0}
  .receipt .kv .k{color:var(--muted);flex:0 0 92px}
  .receipt .kv .vl{color:var(--txt);word-break:break-all;flex:1}
  .receipt .kv .vl.sha{color:var(--teal)} .receipt .kv .vl.sig{color:var(--gold)}

  /* CENTER — Cesium globe + kill-move chain strip at bottom */
  #cesiumContainer{position:relative;width:100%;height:100%}
  .globe-tag{position:absolute;top:12px;left:12px;z-index:5;font-family:var(--mono);font-size:10px;color:var(--muted);
    background:rgba(7,11,20,.72);border:1px solid var(--line2);border-radius:8px;padding:7px 11px;backdrop-filter:blur(4px)}
  .globe-tag b{color:var(--gold)}
  .globe-fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:10px;
    color:var(--muted);font-family:var(--mono);font-size:12px;text-align:center;padding:30px}
  .killstrip{background:linear-gradient(180deg,#0a0f1e,#0c1322);border-top:1px solid var(--line2);padding:12px 16px}
  .killstrip .hd{display:flex;align-items:center;gap:9px;margin-bottom:10px}
  .killstrip .hd .t{font-weight:700;font-size:13px}
  .killstrip .hd .v{margin-left:auto;font-family:var(--mono);font-size:11px;padding:3px 10px;border-radius:7px;border:1px solid var(--line);color:var(--muted)}
  .killstrip .hd .v.allow{color:var(--green);border-color:rgba(31,157,87,.45);background:rgba(31,157,87,.08)}
  .killstrip .hd .v.warn{color:var(--warn);border-color:rgba(216,147,47,.45);background:rgba(216,147,47,.08)}
  .killstrip .hd .v.block{color:var(--red);border-color:rgba(214,90,90,.45);background:rgba(214,90,90,.08)}
  .chain{display:flex;align-items:stretch;gap:0}
  .link{flex:1;text-align:center;position:relative}
  .link .o{font-size:20px;line-height:1}
  .link .n{font-family:var(--mono);font-size:9px;color:var(--muted);margin-top:4px;text-transform:uppercase;letter-spacing:.05em}
  .link .vv{font-family:var(--mono);font-size:9.5px;margin-top:3px;padding:2px 7px;border-radius:5px;display:inline-block}
  .link .vv.allow{color:var(--green);background:rgba(31,157,87,.12)}
  .link .vv.warn{color:var(--warn);background:rgba(216,147,47,.12)}
  .link .vv.block{color:var(--red);background:rgba(214,90,90,.12)}
  .link .vv.pending{color:var(--faint);background:rgba(91,106,126,.12)}
  .link:not(:last-child)::after{content:"→";position:absolute;right:-7px;top:6px;color:var(--line);font-size:14px}

  /* Field operative + GPU (bottom-left below action) */
  .gpu{background:linear-gradient(158deg,var(--panel),var(--panel2));border:1px solid var(--line2);border-radius:12px;padding:12px;margin-top:4px}
  .gpu .hd{display:flex;align-items:center;gap:7px;font-weight:700;font-size:12.5px}
  .gpu .meta{font-family:var(--mono);font-size:10px;color:var(--muted);margin-top:7px}
  .gpu .bar{margin:7px 0}
  .gpu .bar .lab{font-family:var(--mono);font-size:9px;color:var(--muted);display:flex;justify-content:space-between}
  .gpu .bar .track{height:6px;background:var(--panel2);border-radius:4px;margin-top:3px;overflow:hidden;border:1px solid var(--line2)}
  .gpu .bar .fill{height:100%;background:linear-gradient(90deg,var(--teal),var(--gold));width:0%;transition:width .6s ease}
  .honest{font-size:10px;color:var(--faint);margin-top:8px;line-height:1.5;font-style:italic}

  /* RIGHT rail — compliance tabs + audit */
  .rail-tabs{display:flex;gap:4px;margin-bottom:12px}
  .rail-tabs button{flex:1;background:var(--panel2);border:1px solid var(--line2);color:var(--muted);font-family:var(--sans);
    font-size:11px;font-weight:600;padding:8px 4px;border-radius:8px;cursor:pointer}
  .rail-tabs button[aria-selected="true"]{color:var(--gold);border-color:rgba(215,185,107,.4);background:rgba(215,185,107,.08)}
  .rail-panel{display:none}.rail-panel.on{display:block}
  .ccard{background:var(--panel);border:1px solid var(--line2);border-radius:11px;padding:11px;margin-bottom:9px}
  .ccard .ct{font-weight:700;font-size:12.5px;display:flex;align-items:center;gap:7px}
  .ccard .ce{font-family:var(--mono);font-size:8px;padding:2px 6px;border-radius:5px;border:1px solid var(--line);color:var(--muted);margin-left:auto}
  .ccard .cd{color:var(--muted);font-size:11px;margin-top:6px;line-height:1.45}
  .ccard .run{margin-top:8px;font-family:var(--sans);font-size:11px;font-weight:600;color:var(--teal);background:none;border:1px solid var(--line2);
    border-radius:7px;padding:6px 10px;cursor:pointer}
  .ccard .run:hover{border-color:var(--teal)}
  .ccard .out{margin-top:9px;font-family:var(--mono);font-size:10px;color:var(--teal);background:var(--panel2);border-radius:7px;
    padding:9px;max-height:200px;overflow:auto;white-space:pre-wrap;display:none;line-height:1.5}
  .ccard .out.on{display:block}

  /* Verify modal */
  .modal{position:fixed;inset:0;z-index:60;display:none;align-items:center;justify-content:center}
  .modal.on{display:flex}
  .modal .ov{position:absolute;inset:0;background:rgba(4,7,13,.74)}
  .sheet{position:relative;width:680px;max-width:92vw;max-height:84vh;overflow:auto;background:var(--panel);
    border:1px solid var(--line);border-radius:16px;padding:22px;box-shadow:0 24px 80px rgba(0,0,0,.55)}
  .sheet .x{position:absolute;top:16px;right:18px;color:var(--muted);cursor:pointer;font-size:20px;line-height:1}
  .sheet h3{margin:0 0 4px;font-size:17px;font-weight:700}
  .sheet .verdict-big{display:inline-flex;align-items:center;gap:7px;font-family:var(--mono);font-size:12px;padding:5px 11px;border-radius:8px;margin:8px 0 12px}
  .sheet .verdict-big.allow{color:var(--green);background:rgba(31,157,87,.1);border:1px solid rgba(31,157,87,.4)}
  .sheet pre{background:var(--panel2);border:1px solid var(--line2);border-radius:10px;padding:13px;font-family:var(--mono);
    font-size:11px;color:var(--teal);overflow:auto;white-space:pre-wrap;word-break:break-all;line-height:1.6}
  .sheet .ok{color:var(--green);font-weight:700}
  .spin{display:inline-block;width:12px;height:12px;border:2px solid var(--line);border-top-color:var(--gold);border-radius:50%;
    animation:sp .7s linear infinite;vertical-align:middle}
  @keyframes sp{to{transform:rotate(360deg)}}
  .foot{font-family:var(--mono);font-size:9px;color:var(--faint);letter-spacing:.04em;margin-top:12px;line-height:1.6}
</style>
</head>
<body>
<div class="app">
  <header>
    <svg class="logo" viewBox="0 0 32 32"><path d="M16 3 L27 27 L16 21 L5 27 Z" fill="#d7b96b"/></svg>
    <div class="ttl">Killinchu <b>/ UDS Edition</b> — Command Center</div>
    <span class="chip"><span class="dot"></span>4 ORGANS LIVE</span>
    <span class="chip">SOLE FRONT DOOR · /api/killinchu/uds/v1/*</span>
    <span class="sp"></span>
    <span class="doc">DOCTRINE <b>v11</b> LOCKED · 749 · 14 · 163 · SLSA L1 honest · L2 attested · L3 roadmap · Λ Conjecture (not a theorem)</span>
  </header>

  <div class="body">
    <!-- ============ LEFT: Command Center + Action + GPU ============ -->
    <div class="col left">
      <h2 class="sec">Command Center — four brains</h2>
      <div class="heroes" id="heroes"></div>

      <div class="panel">
        <div class="field">
          <label for="actsel">Operator action</label>
          <select id="actsel">
            <option value="threat_assess">Threat assess — classify track</option>
            <option value="effector_recommend">Effector recommend — Policy dual-use gate</option>
            <option value="mission_plan">Mission plan — Reasoning F7 + Yuyay-13</option>
            <option value="swarm_coordinate">Swarm coordinate — boids + ORCA</option>
            <option value="geofence_check">Geofence check — airspace class</option>
          </select>
        </div>
        <div class="btnrow">
          <button class="btn primary" id="execBtn">▶ Execute mission</button>
          <button class="btn ghost" id="verifyBtn" disabled>🔏 Verify aggregated receipt</button>
        </div>
        <div class="receipt" id="receipt" style="display:none"></div>
      </div>

      <div class="gpu" id="gpupanel">
        <div class="hd"><span style="font-size:16px">🎮</span> GPU substrate — RTX 4060 Ti (airgap tower)</div>
        <div class="meta" id="gpumeta"><span class="spin"></span> querying nvidia-smi…</div>
        <div id="gpubars"></div>
        <div class="honest" id="gpuhonest"></div>
      </div>

      <div class="foot">drone positions SIMULATED (seeded) · geofence STATIC SNAPSHOT · Reasoning per-role signature PLACEHOLDER (honest) · fail-WARNING never fail-open</div>
    </div>

    <!-- ============ CENTER: Cesium globe + kill-move chain ============ -->
    <div class="col center">
      <div style="position:relative">
        <div id="cesiumContainer"></div>
        <div class="globe-tag" id="globetag">🦅 <b>Killinchu</b> in the field · airspace <b id="gt-class">awaiting init</b> · tracks <b id="gt-tracks">simulated snapshot</b></div>
      </div>
      <div class="killstrip">
        <div class="hd">
          <span style="font-size:16px">🦅</span><span class="t">Kill-move chain</span>
          <span class="v" id="killverdict">idle</span>
        </div>
        <div class="chain" id="chain"></div>
      </div>
    </div>

    <!-- ============ RIGHT rail: Compliance + Audit ============ -->
    <div class="col right">
      <div class="rail-tabs">
        <button data-rail="compliance" aria-selected="true">🛡️ Compliance</button>
        <button data-rail="audit">📜 Audit</button>
      </div>
      <div class="rail-panel on" id="rail-compliance">
        <h2 class="sec">Every UDS pain-point — real signed endpoint</h2>
        <div id="complist"></div>
        <div class="foot">Honest status everywhere — no fabricated Iron Bank PASS, no fabricated Rekor inclusion, no FedRAMP ATO claimed. When the UDS-HARDENING real-data module is present, the fusion synthetic stubs DEFER to it.</div>
      </div>
      <div class="rail-panel" id="rail-audit">
        <h2 class="sec">Khipu transparency log</h2>
        <button class="btn ghost" id="refreshAudit" style="margin-bottom:12px">↻ Refresh recent chain</button>
        <div id="auditlist"></div>
        <div class="foot">Append-only hash-chained DAG. Public Sigstore Rekor cross-submission is not_submitted (honest); Khipu is our private transparency log.</div>
      </div>
    </div>
  </div>
</div>

<!-- Verify modal -->
<div class="modal" id="modal">
  <div class="ov" id="modalov"></div>
  <div class="sheet">
    <span class="x" id="modalx"></span>
    <h3>🔏 Aggregated receipt — cosign verify-blob</h3>
    <div id="verifybody"></div>
  </div>
</div>

<script>
(function(){
  "use strict";
  var BASE = "/api/killinchu/uds/v1";
  var ORGANS = [
    {k:"policy",      ic:"📜", nm:"Policy",                role:"Policy gate", badge:"signed"},
    {k:"reasoning",   ic:"🧠", nm:"Reasoning",             role:"13-axis Λ cortex", badge:"placeholder"},
    {k:"orchestrator",ic:"🎛️", nm:"Orchestrator (a11oy)",  role:"Policy orchestration", badge:"signed"},
    {k:"field_node",  ic:"🦅", nm:"Field Node (killinchu)",role:"Field surface", badge:"signed"}
  ];
  var lastSha = null;
  function el(id){return document.getElementById(id);}
  function esc(s){return String(s==null?"":s).replace(/[&<>]/g,function(c){return {"&":"&amp;","<":"&lt;",">":"&gt;"}[c];});}
  function kv(k,v,cls){return '<div class="kv"><span class="k">'+esc(k)+'</span><span class="vl '+(cls||"")+'">'+esc(v)+'</span></div>';}

  function renderHeroes(){
    el("heroes").innerHTML = ORGANS.map(function(o){
      var b = o.badge==="signed"?["signed","DSSE signed"]:["placeholder","placeholder"];
      return '<div class="hero" id="hero-'+o.k+'"><span class="badge '+b[0]+'">'+b[1]+'</span>'+
        '<div class="ic">'+o.ic+'</div><div class="nm">'+o.nm+'</div><div class="role">'+o.role+'</div>'+
        '<div class="st"><span class="d"></span><span class="t">standby</span></div><div class="lat" id="lat-'+o.k+'"></div></div>';
    }).join("");
  }
  function renderChain(links){
    el("chain").innerHTML = ORGANS.map(function(o){
      var lk=(links||[]).filter(function(l){return l.organ===o.k;})[0]; var v=lk?lk.verdict:"pending";
      return '<div class="link"><div class="o">'+o.ic+'</div><div class="n">'+o.nm+'</div><div class="vv '+v+'">'+v+'</div></div>';
    }).join("");
  }
  function setHero(k,status,latency){
    var c=el("hero-"+k); if(!c) return;
    c.className="hero "+(status==="ok"||status==="allow"?"ok":(status==="block"||status==="red"?"red":"amber"));
    var t=c.querySelector(".st .t"); if(t) t.textContent=status;
    if(latency!=null){var L=el("lat-"+k); if(L) L.textContent=latency.toFixed(1)+" ms";}
  }

  function execMission(){
    var action=el("actsel").value, btn=el("execBtn");
    btn.disabled=true; btn.innerHTML='<span class="spin"></span> executing 4-organ chain…'; el("verifyBtn").disabled=true;
    el("killverdict").className="v"; el("killverdict").textContent="running…";
    ORGANS.forEach(function(o){setHero(o.k,"running…");}); renderChain([]);
    var body={action:action,payload:{severity:"high",confidence:0.95,target:"fpv7in"},
      context:{operator_id:"op-yachay",mission_id:"M-"+Date.now().toString().slice(-5),roe:"defensive-only"}};
    fetch(BASE+"/mission/execute",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(body)})
      .then(function(r){return r.json();})
      .then(function(j){
        var links=(j.aggregated_receipt&&j.aggregated_receipt.chain)||[];
        renderChain(links); links.forEach(function(l){setHero(l.organ,l.verdict,l.latency_ms);});
        ORGANS.forEach(function(o){ if(!links.filter(function(l){return l.organ===o.k;})[0]) setHero(o.k,"not-run"); });
        var v=j.verdict||"warn"; el("killverdict").className="v "+v; el("killverdict").textContent=v.toUpperCase();
        lastSha=j.receipt_sha256;
        var agg=j.aggregated_receipt||{}, sig=(agg.aggregate_signature||"").slice(0,42);
        var R=el("receipt"); R.style.display="block";
        R.innerHTML=kv("mission",j.uds_mission_id||"unavailable")+kv("verdict",(j.verdict||"warn").toUpperCase())+
          kv("sha256",j.receipt_sha256||"unavailable","sha")+kv("signed",String(agg.aggregate_signed))+
          kv("keyid",agg.keyid||"szlholdings-cosign")+kv("sig",sig?sig+"…":"unsigned (no key in runtime)","sig");
        el("verifyBtn").disabled=false;
        if(action==="geofence_check"){ el("gt-class").textContent="checked"; }
      })
      .catch(function(e){ el("killverdict").textContent="error"; el("receipt").style.display="block";
        el("receipt").innerHTML=kv("error",e.message); })
      .finally(function(){ btn.disabled=false; btn.innerHTML="▶ Execute mission"; });
  }

  function openVerify(){
    if(!lastSha) return; el("modal").classList.add("on");
    el("verifybody").innerHTML='<p class="mono" style="color:var(--muted)"><span class="spin"></span> verifying '+esc(lastSha.slice(0,16))+'…</p>';
    fetch(BASE+"/receipt/"+lastSha+"/verify").then(function(r){return r.json();}).then(function(v){
      var cmd=v.cosign_verify_blob_cmd||"(command unavailable)";
      el("verifybody").innerHTML='<span class="verdict-big '+(v.verified?"allow":"")+'">'+(v.verified?"✓ in-process verify: TRUE":"verify: "+v.verified)+'</span>'+
        '<div class="receipt" style="margin-top:0">'+kv("sha256",v.sha||lastSha,"sha")+kv("keyid",v.keyid_expected||"szlholdings-cosign")+
        kv("pae sha256",(v.pae_sha256||"").slice(0,40)+"…","sha")+kv("pubkey",v.verify_key_url||"")+'</div>'+
        '<p class="mono" style="color:var(--muted);margin:14px 0 6px">Reproduce offline — expected output <span class="ok">Verified OK</span>:</p><pre>'+esc(cmd)+'</pre>';
    }).catch(function(e){ el("verifybody").innerHTML='<pre>'+esc(e.message)+'</pre>'; });
  }

  function loadHealth(){
    fetch(BASE+"/healthz").then(function(r){return r.json();}).then(function(h){
      var organs=h.organs||{};
      ORGANS.forEach(function(o){ if(organs[o.k]){ var st=organs[o.k].status; setHero(o.k, st, organs[o.k].latency_ms); } });
    }).catch(function(){});
  }
  function loadGpu(){
    fetch(BASE+"/gpu/stats").then(function(r){return r.json();}).then(function(g){
      el("gpuhonest").textContent=g.honesty||"";
      if(g.gpu_present&&g.gpus&&g.gpus.length){
        var u=parseFloat(g.gpus[0].utilization_pct)||0, mU=parseFloat(g.gpus[0].memory_used_mib)||0, mT=parseFloat(g.gpus[0].memory_total_mib)||1;
        var mp=Math.round(mU/mT*100);
        el("gpumeta").textContent=g.gpus[0].name+" · "+g.gpus[0].temperature_c+"°C · source "+g.source;
        el("gpubars").innerHTML=bar("GPU util",u,u+"%")+bar("VRAM",mp,mU+" / "+mT+" MiB");
        setTimeout(function(){var f=document.querySelectorAll("#gpubars .fill"); if(f[0])f[0].style.width=u+"%"; if(f[1])f[1].style.width=mp+"%";},60);
      } else { el("gpumeta").textContent="no live GPU in this runtime · source "+esc(g.source||"honest-fallback"); }
    }).catch(function(e){ el("gpumeta").textContent="gpu query error: "+e.message; });
  }
  function bar(l,p,v){return '<div class="bar"><div class="lab"><span>'+esc(l)+'</span><span>'+esc(v)+'</span></div><div class="track"><div class="fill"></div></div></div>';}

  function loadAudit(){
    el("auditlist").innerHTML='<p class="honest"><span class="spin"></span> loading…</p>';
    fetch(BASE+"/chain/recent").then(function(r){return r.json();}).then(function(d){
      var items=d.recent||[];
      if(!items.length){ el("auditlist").innerHTML='<p class="honest">No missions executed in this runtime yet. Run one from Command.</p>'; return; }
      el("auditlist").innerHTML=items.map(function(it){
        var chain=(it.chain||[]).map(function(c){return c.icon;}).join(" → ");
        return '<div class="ccard"><div class="ct">'+esc((it.verdict||"").toUpperCase())+'<span class="ce">'+(it.aggregate_signed?"signed":"unsigned")+'</span></div>'+
          '<div class="cd mono">'+chain+'</div><div class="cd mono" style="color:var(--teal);word-break:break-all">'+esc((it.receipt_sha256||"").slice(0,44))+'…</div>'+
          '<div class="cd mono" style="font-size:9px">'+esc(it.ts||"")+'</div></div>';
      }).join("");
    }).catch(function(e){ el("auditlist").innerHTML='<p class="honest">audit error: '+esc(e.message)+'</p>'; });
  }

  var COMPLIANCE=[
    {nm:"STIG / SCAP scan",ic:"🔍",ep:"/stig/scan-report/registry1.dso.mil%2Fkillinchu%3Av11",m:"GET",d:"DISA STIG / OpenSCAP pass/fail. Defers to UDS-HARDENING real-data when present."},
    {nm:"Big Bang lint",ic:"💥",ep:"/big-bang/lint",m:"POST",b:{values:{istio:{enabled:true},pepr:true,monitoring:{enabled:true}}},d:"Lints values.yaml; fail-WARNING on high-severity gaps."},
    {nm:"Big Bang parity",ic:"🧩",ep:"/big-bang/parity",m:"GET",d:"Feature parity map; Flux GitOps on roadmap (honest)."},
    {nm:"Tradewinds listing",ic:"🛒",ep:"/tradewinds/listing",m:"GET",d:"Marketplace listing data. No awarded-contract claim."},
    {nm:"NIST AI RMF map",ic:"🧭",ep:"/nist-ai-rmf/map",m:"GET",d:"GOVERN/MAP/MEASURE/MANAGE mapping. Λ stays a Conjecture."},
    {nm:"EU AI Act Art.12",ic:"🇪🇺",ep:"/eu-ai-act/article-12",m:"GET",d:"Record-keeping primitives. Engineering mapping, not conformity."},
    {nm:"Pepr admission",ic:"🚧",ep:"/pepr/test-admission",m:"POST",b:{object:{kind:"Pod",spec:{hostNetwork:true,containers:[]},metadata:{labels:{}}}},d:"Admission decision, fail-CLOSED defaults."},
    {nm:"Airgap verify-deploy",ic:"✈️",ep:"/airgap/verify-deploy",m:"POST",b:{inventory:[{image:"registry1.dso.mil/killinchu:v11",signed:true}],cluster:"k3d-uds-core"},d:"Signed-bundle inventory check. Never fail-open."},
    {nm:"SBOM diff",ic:"📦",ep:"/sbom/diff/v10/v11",m:"GET",d:"Package-level SBOM diff (deterministic given tags)."},
    {nm:"JADC2 event",ic:"📡",ep:"/jadc2/event",m:"POST",b:{event:{type:"track",mission_id:"jadc2-1"}},d:"C2 event routed through the live 4-organ chain; verdict signed."},
    {nm:"Rekor log",ic:"🪵",ep:"/rekor/log",m:"GET",d:"Khipu private transparency log. Public Rekor not_submitted (honest)."},
    {nm:"Rekor cross-verify",ic:"🔗",ep:"/rekor/cross-verify",m:"POST",b:{receipt_sha256:""},d:"Khipu membership verified; Rekor not_submitted."},
    {nm:"Yuyay-Rego compile",ic:"⚖️",ep:"/policy/yuyay-rego",m:"POST",b:{rego:"package x\ndeny[m]{input.priv}\nallow{input.ok}"},d:"OPA Rego → 13-axis Yuyay constraints (syntactic map)."},
    {nm:"D3FEND map",ic:"🗺️",ep:"/d3fend/map",m:"GET",d:"SZL primitives → MITRE D3FEND techniques (interpretive)."}
  ];
  function renderCompliance(){
    el("complist").innerHTML=COMPLIANCE.map(function(c,i){
      return '<div class="ccard"><div class="ct">'+c.ic+' '+esc(c.nm)+'<span class="ce">'+c.m+'</span></div><div class="cd">'+esc(c.d)+'</div>'+
        '<button class="run" data-ci="'+i+'">Run &amp; sign →</button><div class="out mono" id="cout-'+i+'"></div></div>';
    }).join("");
    Array.prototype.forEach.call(document.querySelectorAll("[data-ci]"),function(b){
      b.addEventListener("click",function(){ runCompliance(parseInt(b.getAttribute("data-ci"),10)); });
    });
  }
  function runCompliance(i){
    var c=COMPLIANCE[i], out=el("cout-"+i); out.classList.add("on"); out.textContent="running…";
    var opt={method:c.m,headers:{"Content-Type":"application/json"}};
    var bodyObj=c.b; if(c.ep==="/rekor/cross-verify"&&lastSha){ bodyObj={receipt_sha256:lastSha}; }
    if(c.m==="POST") opt.body=JSON.stringify(bodyObj||{});
    fetch(BASE+c.ep,opt).then(function(r){return r.json().then(function(j){return {s:r.status,j:j};});}).then(function(res){
      var j=res.j, signed=j.signed!=null?j.signed:(j.aggregate_signed!=null?j.aggregate_signed:"-");
      var keys=["verdict","finding_count","allowed","score_pct","rules_passed","in_khipu_dag","sigstore_rekor","authorization_status","honesty"];
      var lines=keys.filter(function(k){return j[k]!=null;}).map(function(k){return k+": "+(typeof j[k]==="object"?JSON.stringify(j[k]):j[k]);});
      out.textContent="HTTP "+res.s+" · signed="+signed+"\n"+lines.join("\n")+"\nsha256: "+(j.receipt_sha256||"-");
    }).catch(function(e){ out.textContent="error: "+e.message; });
  }

  // Cesium globe (uses the Space's own /cesium bundle; honest fallback if unavailable)
  function initGlobe(){
    try{
      if(typeof Cesium==="undefined"){ throw new Error("Cesium bundle not loaded"); }
      var viewer=new Cesium.Viewer("cesiumContainer",{
        baseLayerPicker:false,geocoder:false,homeButton:false,sceneModePicker:false,navigationHelpButton:false,
        animation:false,timeline:false,fullscreenButton:false,infoBox:false,selectionIndicator:false,
        imageryProvider:new Cesium.TileMapServiceImageryProvider({url:Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII")})
      });
      viewer.scene.globe.baseColor=Cesium.Color.fromCssColorString("#0a1422");
      viewer.scene.skyBox.show=false; viewer.scene.backgroundColor=Cesium.Color.fromCssColorString("#070b14");
      viewer.scene.globe.showGroundAtmosphere=true;
      // SIMULATED (seeded) tracks — labeled honest.
      var seed=[[47.05,35.10,"fpv7in","STRIKE"],[47.91,35.05,"djimavic3","RECON"],[46.50,34.20,"wingloong2","ISR"],[47.10,35.80,"tb2","PATROL"]];
      seed.forEach(function(t,i){
        viewer.entities.add({position:Cesium.Cartesian3.fromDegrees(t[1],t[0],1200+i*800),
          point:{pixelSize:11,color:Cesium.Color.fromCssColorString(i===0?"#d65a5a":"#5cc4bf"),outlineColor:Cesium.Color.fromCssColorString("#d7b96b"),outlineWidth:2},
          label:{text:t[2]+" · "+t[3],font:"11px JetBrains Mono",fillColor:Cesium.Color.WHITE,style:Cesium.LabelStyle.FILL,
            verticalOrigin:Cesium.VerticalOrigin.BOTTOM,pixelOffset:new Cesium.Cartesian2(0,-14),showBackground:true,
            backgroundColor:Cesium.Color.fromCssColorString("rgba(7,11,20,.7)")}});
      });
      viewer.camera.flyTo({destination:Cesium.Cartesian3.fromDegrees(35.2,47.0,520000),duration:0});
      el("gt-class").textContent="B"; el("gt-tracks").textContent=seed.length+" simulated (seeded)";
    }catch(e){
      el("cesiumContainer").innerHTML='<div class="globe-fallback">🌐 Cesium globe unavailable in this runtime ('+esc(e.message)+').<br>Tracks are SIMULATED (seeded) — honest fallback, no live telemetry.<br>On the 4060 Ti tower the globe renders the airspace picture.</div>';
    }
  }

  function showRail(name){
    Array.prototype.forEach.call(document.querySelectorAll(".rail-panel"),function(p){p.classList.toggle("on",p.id==="rail-"+name);});
    Array.prototype.forEach.call(document.querySelectorAll(".rail-tabs button"),function(b){b.setAttribute("aria-selected",b.getAttribute("data-rail")===name?"true":"false");});
    if(name==="audit") loadAudit();
  }

  // Wire up
  renderHeroes(); renderChain([]); renderCompliance(); initGlobe();
  el("execBtn").addEventListener("click",execMission);
  el("verifyBtn").addEventListener("click",openVerify);
  el("modalov").addEventListener("click",function(){el("modal").classList.remove("on");});
  el("modalx").addEventListener("click",function(){el("modal").classList.remove("on");});
  el("refreshAudit").addEventListener("click",loadAudit);
  Array.prototype.forEach.call(document.querySelectorAll(".rail-tabs button"),function(b){
    b.addEventListener("click",function(){showRail(b.getAttribute("data-rail"));});
  });
  loadHealth(); loadGpu();
  setInterval(loadHealth,20000);
})();
</script>
</body>
</html>