Spaces:
Running
feat(mission-globe): Palantir-class 3D mission globe + Navy Edition polish
Browse filesADDITIVE Palantir-class backend — one synchronized canvas, not dashboards.
NEW routes (registered before SPA catch-all; never touch v1/v2/v3/v4 data):
GET /mission-globe 3D earth + MQ-9 trajectory + space-weather cone
+ USGS seismic field + N2YO satellite orbits;
camera orbit/drag/zoom; click-any-element cards.
GET /threat-cone-3d a cone per active threat (space weather + seismic
+ drone health); color=severity, length=reach;
click -> threat detail card w/ Khipu receipt.
GET /api/killinchu/v4/seismic USGS significant-week quakes (free, no key).
GET /api/killinchu/v4/mission-feed SSE merge of all sources (?once=1 = snapshot).
Navy Edition (/navy) enhanced: 3D mission-globe hero, 3 BIG live numbers
(drones tracked / space-weather alert / seismic 24h), Pace-Setting Alignment
(Open Arsenal + Enterprise Agents), compliance badges row, 'UDS Edition ·
Navy-Ready · CDAO-aligned' gold serif subhead, Hickok 2007 + Hickok 2025
citations, and an independent Khipu-chain receipt verify curl.
Patterns stolen (concepts/words only, cited in code comments; NO logos/marks):
Palantir Gotham -> mission globe + multi-source synchronized canvas
Esri ArcGIS -> geospatial + temporal + network on one view
Anduril Lattice -> drone health + threat overlay
CrowdStrike Falcon -> threat-globe pattern (mirrored from Sentra)
Honest: health/space-weather/seismic are REAL; drone position track is
seed-reproducible (Codex-Kernel) until live ADS-B position stream is wired.
Doctrine v11 LOCKED 749/14/163 · Λ Conjecture 1. ADDITIVE. DCO. No force-push.
Sovereign. Sign: Yachay <yachay@szlholdings.dev>
Co-Authored-By: Perplexity Computer Agent <agent@perplexity.ai>
- Dockerfile +10 -0
- killinchu_mission_globe.py +536 -0
- serve.py +50 -0
- szl_navy_edition.py +304 -0
|
@@ -135,5 +135,15 @@ COPY killinchu_fusion.py ./killinchu_fusion.py
|
|
| 135 |
# /api/killinchu/v4/* route 404s. The /drone-3d page (static/drone-3d.html) and the operator
|
| 136 |
# tab (static/uds.html) are already COPY'd by the `COPY static/ ./static/` line above.
|
| 137 |
COPY killinchu_drone_3d_health.py ./killinchu_drone_3d_health.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
COPY serve.py ./serve.py
|
| 139 |
CMD ["python", "serve.py"]
|
|
|
|
| 135 |
# /api/killinchu/v4/* route 404s. The /drone-3d page (static/drone-3d.html) and the operator
|
| 136 |
# tab (static/uds.html) are already COPY'd by the `COPY static/ ./static/` line above.
|
| 137 |
COPY killinchu_drone_3d_health.py ./killinchu_drone_3d_health.py
|
| 138 |
+
# ADDITIVE (Navy Edition + Palantir-class Mission Globe, Yachay 2026-06-02 /
|
| 139 |
+
# Co-Authored-By: Perplexity Computer Agent): bake the Navy surface and the 3D
|
| 140 |
+
# mission-globe / threat-cone modules into the image. Explicit per-file COPY
|
| 141 |
+
# (this Dockerfile never uses `COPY . .`); without these `import szl_navy_edition`
|
| 142 |
+
# and `import killinchu_mission_globe` fail and /navy, /mission-globe,
|
| 143 |
+
# /threat-cone-3d, /api/killinchu/v4/{seismic,mission-feed} 404. The mission-globe
|
| 144 |
+
# module reuses killinchu_drone_3d_health (already COPY'd above) for fusion fetch.
|
| 145 |
+
# Doctrine v11 LOCKED 749/14/163 · Λ Conjecture 1.
|
| 146 |
+
COPY szl_navy_edition.py ./szl_navy_edition.py
|
| 147 |
+
COPY killinchu_mission_globe.py ./killinchu_mission_globe.py
|
| 148 |
COPY serve.py ./serve.py
|
| 149 |
CMD ["python", "serve.py"]
|
|
@@ -0,0 +1,536 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# © 2026 Lutar, Stephen P. — SZL Holdings · ORCID 0009-0001-0110-4173
|
| 3 |
+
# Doctrine v11 LOCKED 749/14/163. Λ Conjecture 1.
|
| 4 |
+
"""
|
| 5 |
+
killinchu_mission_globe.py — Palantir-class 3D Mission Globe (ADDITIVE, Doctrine v11).
|
| 6 |
+
|
| 7 |
+
Founder mandate (Yachay, CTO): NOT dashboards. ONE synchronized canvas where a 3D
|
| 8 |
+
earth, live MQ-9 drone trajectories, a NOAA space-weather cone, a USGS seismic
|
| 9 |
+
field, and (optional) N2YO satellite orbits all share the same coordinate frame and
|
| 10 |
+
the same clock. Click any element → its signed detail card.
|
| 11 |
+
|
| 12 |
+
Patterns stolen (cited, not copied — no logos/trademarks):
|
| 13 |
+
- Palantir Gotham → the mission globe + multi-source synchronized canvas idea:
|
| 14 |
+
fuse heterogeneous feeds onto ONE geospatial-temporal scene.
|
| 15 |
+
- Esri ArcGIS → geospatial + temporal + network layers composited on a single
|
| 16 |
+
3D view rather than separate panels.
|
| 17 |
+
- Anduril Lattice → drone-health telemetry rendered AS a threat/health overlay on
|
| 18 |
+
the same world the threats live in.
|
| 19 |
+
- CrowdStrike Falcon → the rotating "threat globe" pattern (already used in Sentra;
|
| 20 |
+
mirrored here for the threat-cone view).
|
| 21 |
+
|
| 22 |
+
NEW routes (all ADDITIVE; never touch v1/v2/v3/v4 data routes or the SPA catch-all):
|
| 23 |
+
GET /mission-globe — Three.js 3D mission globe HTML page
|
| 24 |
+
GET /threat-cone-3d — Three.js 3D threat-cone HTML page
|
| 25 |
+
GET /api/killinchu/v4/seismic — USGS significant-week quakes (free, no key)
|
| 26 |
+
GET /api/killinchu/v4/mission-feed — Server-Sent-Events merge of ALL sources
|
| 27 |
+
|
| 28 |
+
Data sources are the ALREADY-LIVE killinchu primitives (no new upstreams beyond the
|
| 29 |
+
USGS feed the drone-health module already fuses):
|
| 30 |
+
/api/killinchu/v4/spaceweather (NOAA SWPC Kp + DSCOVR solar wind)
|
| 31 |
+
/api/killinchu/v4/drones/{id}/health (live drone health + nearest quake)
|
| 32 |
+
/api/killinchu/v4/drones/{id}/3d-model (per-component Three.js scene JSON)
|
| 33 |
+
/api/killinchu/v4/satellites/visible (N2YO, degrades honestly without key)
|
| 34 |
+
USGS earthquakes GeoJSON (significant_week, free, no key)
|
| 35 |
+
|
| 36 |
+
Honest: drone GPS track is the drone-health operating_area + a deterministic,
|
| 37 |
+
seed-reproducible synthetic last-hour trajectory (Codex-Kernel) UNTIL a live ADS-B
|
| 38 |
+
position stream is wired; this is labelled in the UI and in the feed payload. The
|
| 39 |
+
space-weather cone severity, seismic magnitudes, and drone health are all REAL.
|
| 40 |
+
|
| 41 |
+
Self-contained: Three.js is loaded from a pinned CDN (r128, unpkg). No build step.
|
| 42 |
+
try/except-guarded by the host. NEVER crashes the existing app. DCO. Sign: Yachay.
|
| 43 |
+
Co-Authored-By: Perplexity Computer Agent.
|
| 44 |
+
"""
|
| 45 |
+
from __future__ import annotations
|
| 46 |
+
|
| 47 |
+
import asyncio
|
| 48 |
+
import json
|
| 49 |
+
import math
|
| 50 |
+
import time
|
| 51 |
+
from typing import Any
|
| 52 |
+
|
| 53 |
+
from fastapi import Request
|
| 54 |
+
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
|
| 55 |
+
|
| 56 |
+
# Reuse the ALREADY-LIVE fusion fetchers — no new upstreams, no duplicated logic.
|
| 57 |
+
try:
|
| 58 |
+
import killinchu_drone_3d_health as _d3d
|
| 59 |
+
except Exception: # pragma: no cover
|
| 60 |
+
_d3d = None
|
| 61 |
+
|
| 62 |
+
DOCTRINE = "Doctrine v11 LOCKED 749/14/163 · Λ Conjecture 1"
|
| 63 |
+
_USGS_WEEK = (
|
| 64 |
+
"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_week.geojson"
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
# --------------------------------------------------------------------------- #
|
| 69 |
+
# Data helpers (server-side merge for the SSE feed + seismic endpoint) #
|
| 70 |
+
# --------------------------------------------------------------------------- #
|
| 71 |
+
def _spaceweather() -> dict[str, Any]:
|
| 72 |
+
if _d3d is None:
|
| 73 |
+
return {"live": False, "error": "drone-3d module unavailable"}
|
| 74 |
+
try:
|
| 75 |
+
return _d3d.fetch_spaceweather()
|
| 76 |
+
except Exception as e: # pragma: no cover
|
| 77 |
+
return {"live": False, "error": repr(e)}
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def fetch_seismic(limit: int = 60) -> dict[str, Any]:
|
| 81 |
+
"""USGS significant-week quakes -> compact list of epicentres + magnitudes.
|
| 82 |
+
|
| 83 |
+
Free, no key. Degrades honestly to an empty list on any upstream failure.
|
| 84 |
+
"""
|
| 85 |
+
out: dict[str, Any] = {
|
| 86 |
+
"source": {
|
| 87 |
+
"name": "USGS earthquakes (significant, past week)",
|
| 88 |
+
"url": _USGS_WEEK,
|
| 89 |
+
"free_tier": "public, no key",
|
| 90 |
+
},
|
| 91 |
+
"live": False,
|
| 92 |
+
"count": 0,
|
| 93 |
+
"events": [],
|
| 94 |
+
"doctrine": DOCTRINE,
|
| 95 |
+
}
|
| 96 |
+
if _d3d is None:
|
| 97 |
+
out["error"] = "drone-3d module unavailable"
|
| 98 |
+
return out
|
| 99 |
+
try:
|
| 100 |
+
d = _d3d._get_json(_USGS_WEEK) # reuse the module's guarded fetcher
|
| 101 |
+
feats = (d or {}).get("features", []) or []
|
| 102 |
+
events = []
|
| 103 |
+
for f in feats[:limit]:
|
| 104 |
+
geom = (f.get("geometry") or {}).get("coordinates") or [None, None, None]
|
| 105 |
+
props = f.get("properties") or {}
|
| 106 |
+
mag = props.get("mag")
|
| 107 |
+
events.append(
|
| 108 |
+
{
|
| 109 |
+
"id": f.get("id"),
|
| 110 |
+
"lon": geom[0],
|
| 111 |
+
"lat": geom[1],
|
| 112 |
+
"depth_km": geom[2],
|
| 113 |
+
"mag": mag,
|
| 114 |
+
"place": props.get("place"),
|
| 115 |
+
"time_ms": props.get("time"),
|
| 116 |
+
"url": props.get("url"),
|
| 117 |
+
# severity 0..1 from magnitude (M2.5 floor .. M8 ceiling)
|
| 118 |
+
"severity": max(
|
| 119 |
+
0.0, min(1.0, ((mag or 0.0) - 2.5) / (8.0 - 2.5))
|
| 120 |
+
),
|
| 121 |
+
}
|
| 122 |
+
)
|
| 123 |
+
out["events"] = events
|
| 124 |
+
out["count"] = len(events)
|
| 125 |
+
out["live"] = True
|
| 126 |
+
except Exception as e: # pragma: no cover
|
| 127 |
+
out["error"] = repr(e)
|
| 128 |
+
return out
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def _drone_health(drone_id: str = "mq9") -> dict[str, Any]:
|
| 132 |
+
"""Live drone health via the already-shipped compute_health() fusion."""
|
| 133 |
+
if _d3d is None:
|
| 134 |
+
return {"live": False, "error": "drone-3d module unavailable"}
|
| 135 |
+
try:
|
| 136 |
+
# Default Denver-area test zone, same defaults the v4 /health route uses.
|
| 137 |
+
return _d3d.compute_health(drone_id, 39.7392, -104.9903, "KDEN", live=True)
|
| 138 |
+
except Exception as e: # pragma: no cover
|
| 139 |
+
return {"live": False, "error": repr(e), "drone_id": drone_id}
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def _trajectory_last_hour(drone_id: str, health: dict[str, Any]) -> dict[str, Any]:
|
| 143 |
+
"""Deterministic, seed-reproducible last-hour track around operating_area.
|
| 144 |
+
|
| 145 |
+
HONEST: synthetic until a live ADS-B position stream is wired. Labelled as
|
| 146 |
+
such in the payload (`live_position: false`). Codex-Kernel: bit-exact from the
|
| 147 |
+
drone_id seed so two clients render the identical track.
|
| 148 |
+
"""
|
| 149 |
+
area = (health or {}).get("operating_area") or {}
|
| 150 |
+
lat0 = area.get("lat", 39.7392)
|
| 151 |
+
lon0 = area.get("lon", -104.9903)
|
| 152 |
+
# 60 points over the last hour, gentle loiter pattern, seeded by drone_id.
|
| 153 |
+
seed = sum(ord(c) for c in drone_id) or 7
|
| 154 |
+
pts = []
|
| 155 |
+
now_ms = int(time.time() * 1000)
|
| 156 |
+
for i in range(60):
|
| 157 |
+
t = i / 59.0
|
| 158 |
+
ang = (seed * 0.013 + t * math.tau) % math.tau
|
| 159 |
+
r = 0.18 + 0.06 * math.sin(seed * 0.7 + t * 6.28) # ~ up to 0.24 deg radius
|
| 160 |
+
lat = lat0 + r * math.sin(ang)
|
| 161 |
+
lon = lon0 + r * math.cos(ang) * 1.3
|
| 162 |
+
pts.append(
|
| 163 |
+
{
|
| 164 |
+
"lat": round(lat, 5),
|
| 165 |
+
"lon": round(lon, 5),
|
| 166 |
+
"t_ms": now_ms - int((59 - i) * 60_000),
|
| 167 |
+
}
|
| 168 |
+
)
|
| 169 |
+
return {
|
| 170 |
+
"drone_id": drone_id,
|
| 171 |
+
"current": pts[-1],
|
| 172 |
+
"track": pts,
|
| 173 |
+
"live_position": False,
|
| 174 |
+
"note": "Last-hour loiter track is deterministic/seed-reproducible "
|
| 175 |
+
"(Codex-Kernel) until live ADS-B position stream is wired. "
|
| 176 |
+
"Health, space-weather, and seismic data are REAL.",
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
def build_mission_state(drone_id: str = "mq9") -> dict[str, Any]:
|
| 181 |
+
"""One synchronized snapshot merging every source for the canvas."""
|
| 182 |
+
sw = _spaceweather()
|
| 183 |
+
seismic = fetch_seismic()
|
| 184 |
+
health = _drone_health(drone_id)
|
| 185 |
+
traj = _trajectory_last_hour(drone_id, health)
|
| 186 |
+
sats: dict[str, Any] = {"live": False, "count": 0, "satellites": []}
|
| 187 |
+
if _d3d is not None:
|
| 188 |
+
try:
|
| 189 |
+
area = (health or {}).get("operating_area") or {}
|
| 190 |
+
sats = _d3d.fetch_satellites(
|
| 191 |
+
area.get("lat", 39.7392), area.get("lon", -104.9903)
|
| 192 |
+
)
|
| 193 |
+
except Exception:
|
| 194 |
+
pass
|
| 195 |
+
|
| 196 |
+
# Threat synthesis (drives the threat-cone view): space weather + seismic + drone.
|
| 197 |
+
threats = []
|
| 198 |
+
kp = sw.get("kp_index")
|
| 199 |
+
if kp is not None:
|
| 200 |
+
sev = max(0.0, min(1.0, float(kp) / 9.0))
|
| 201 |
+
threats.append(
|
| 202 |
+
{
|
| 203 |
+
"kind": "space_weather",
|
| 204 |
+
"label": f"Geomagnetic Kp {kp}",
|
| 205 |
+
"severity": sev,
|
| 206 |
+
"reach_units": 0.6 + sev * 0.9,
|
| 207 |
+
"lat": 0.0,
|
| 208 |
+
"lon": (sw.get("solar_wind_speed_kms") or 400) / 10.0 % 360 - 180,
|
| 209 |
+
"detail": sw,
|
| 210 |
+
}
|
| 211 |
+
)
|
| 212 |
+
for ev in seismic.get("events", [])[:24]:
|
| 213 |
+
threats.append(
|
| 214 |
+
{
|
| 215 |
+
"kind": "seismic",
|
| 216 |
+
"label": f"M{ev.get('mag')} {ev.get('place')}",
|
| 217 |
+
"severity": ev.get("severity", 0.0),
|
| 218 |
+
"reach_units": 0.3 + (ev.get("severity") or 0.0) * 0.8,
|
| 219 |
+
"lat": ev.get("lat"),
|
| 220 |
+
"lon": ev.get("lon"),
|
| 221 |
+
"detail": ev,
|
| 222 |
+
}
|
| 223 |
+
)
|
| 224 |
+
hscore = (health or {}).get("drone_health_score")
|
| 225 |
+
if hscore is not None:
|
| 226 |
+
risk = 1.0 - float(hscore)
|
| 227 |
+
cur = traj["current"]
|
| 228 |
+
threats.append(
|
| 229 |
+
{
|
| 230 |
+
"kind": "drone_health",
|
| 231 |
+
"label": f"{drone_id.upper()} health {round(float(hscore)*100)}%",
|
| 232 |
+
"severity": max(0.0, min(1.0, risk)),
|
| 233 |
+
"reach_units": 0.3 + risk * 0.7,
|
| 234 |
+
"lat": cur["lat"],
|
| 235 |
+
"lon": cur["lon"],
|
| 236 |
+
"detail": {
|
| 237 |
+
"drone_health_score": hscore,
|
| 238 |
+
"lambda_combined_risk": (health or {}).get("lambda_combined_risk"),
|
| 239 |
+
"prediction": (health or {}).get("prediction"),
|
| 240 |
+
"receipt": (health or {}).get("receipt"),
|
| 241 |
+
},
|
| 242 |
+
}
|
| 243 |
+
)
|
| 244 |
+
|
| 245 |
+
return {
|
| 246 |
+
"ts_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
| 247 |
+
"doctrine": DOCTRINE,
|
| 248 |
+
"spaceweather": sw,
|
| 249 |
+
"seismic": seismic,
|
| 250 |
+
"drone": {"health": health, "trajectory": traj},
|
| 251 |
+
"satellites": sats,
|
| 252 |
+
"threats": threats,
|
| 253 |
+
"honesty": "Synchronized canvas. Health/space-weather/seismic are REAL; "
|
| 254 |
+
"drone position track is seed-reproducible synthetic until live ADS-B.",
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
# --------------------------------------------------------------------------- #
|
| 259 |
+
# HTML pages (Three.js, pinned CDN, self-contained) #
|
| 260 |
+
# --------------------------------------------------------------------------- #
|
| 261 |
+
_THREE = "https://unpkg.com/three@0.128.0/build/three.min.js"
|
| 262 |
+
_ORBIT = "https://unpkg.com/three@0.128.0/examples/js/controls/OrbitControls.js"
|
| 263 |
+
# Web Mercator earth texture (NASA Blue Marble, public domain, via Three.js examples).
|
| 264 |
+
_EARTH_TEX = "https://unpkg.com/three-globe@2.24.4/example/img/earth-blue-marble.jpg"
|
| 265 |
+
|
| 266 |
+
_MISSION_GLOBE_HTML = (
|
| 267 |
+
"""<!doctype html><html lang="en"><head>
|
| 268 |
+
<meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/>
|
| 269 |
+
<title>Killinchu — 3D Mission Globe</title>
|
| 270 |
+
<!-- Palantir Gotham + Esri ArcGIS + Anduril Lattice patterns (concepts only, no marks). -->
|
| 271 |
+
<style>
|
| 272 |
+
html,body{margin:0;height:100%;background:#05080f;color:#cfe7ff;font-family:Inter,ui-sans-serif,system-ui,sans-serif;overflow:hidden}
|
| 273 |
+
#c{position:fixed;inset:0}
|
| 274 |
+
#hud{position:fixed;left:14px;top:12px;z-index:5;max-width:340px}
|
| 275 |
+
.eyebrow{letter-spacing:.22em;text-transform:uppercase;font-size:11px;color:#7dd3fc;font-weight:700}
|
| 276 |
+
h1{font-size:18px;margin:4px 0 2px}
|
| 277 |
+
.sub{font-size:12px;color:#9fb3c8}
|
| 278 |
+
.legend{margin-top:10px;display:flex;flex-direction:column;gap:5px;font-size:12px}
|
| 279 |
+
.legend i{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:7px;vertical-align:middle}
|
| 280 |
+
.nums{position:fixed;right:14px;top:12px;z-index:5;display:flex;gap:10px}
|
| 281 |
+
.num{background:rgba(10,18,32,.78);border:1px solid #23364d;border-radius:10px;padding:9px 12px;text-align:center;min-width:74px}
|
| 282 |
+
.num b{display:block;font-size:22px;color:#7dd3fc;line-height:1}
|
| 283 |
+
.num span{font-size:10px;color:#9fb3c8;letter-spacing:.08em;text-transform:uppercase}
|
| 284 |
+
#card{position:fixed;right:14px;bottom:14px;z-index:6;width:330px;max-height:46vh;overflow:auto;display:none;
|
| 285 |
+
background:rgba(8,14,26,.95);border:1px solid #2b4a6b;border-radius:12px;padding:14px 15px;box-shadow:0 10px 40px rgba(0,0,0,.5)}
|
| 286 |
+
#card.show{display:block;border-color:#2b4a6b}
|
| 287 |
+
#card h3{margin:0 0 6px;font-size:13px;color:#7dd3fc;text-transform:uppercase;letter-spacing:.08em}
|
| 288 |
+
#card pre{white-space:pre-wrap;word-break:break-word;font-size:11px;color:#bcd;margin:0;font-family:ui-monospace,Menlo,monospace}
|
| 289 |
+
#card .x{position:absolute;top:8px;right:11px;cursor:pointer;color:#9fb3c8}
|
| 290 |
+
.foot{position:fixed;left:14px;bottom:10px;z-index:5;font-size:10px;color:#62788f}
|
| 291 |
+
a{color:#7dd3fc}
|
| 292 |
+
</style></head><body>
|
| 293 |
+
<div id="c"></div>
|
| 294 |
+
<div id="hud">
|
| 295 |
+
<div class="eyebrow">Killinchu · UDS Edition</div>
|
| 296 |
+
<h1>3D Mission Globe</h1>
|
| 297 |
+
<div class="sub">One synchronized canvas — earth · drone · space-weather cone · seismic field · satellites.</div>
|
| 298 |
+
<div class="legend">
|
| 299 |
+
<div><i style="background:#7dd3fc"></i>MQ-9 drone + last-hour track</div>
|
| 300 |
+
<div><i style="background:#ffd166"></i>Space-weather cone (Kp severity)</div>
|
| 301 |
+
<div><i style="background:#ff4d5e"></i>Seismic events (USGS, M-scaled)</div>
|
| 302 |
+
<div><i style="background:#9be9a8"></i>Satellite orbits (N2YO, if key)</div>
|
| 303 |
+
</div>
|
| 304 |
+
</div>
|
| 305 |
+
<div class="nums" id="nums"></div>
|
| 306 |
+
<div id="card"><span class="x" onclick="document.getElementById('card').classList.remove('show')">✕</span>
|
| 307 |
+
<h3 id="cardt">Detail</h3><pre id="cardb"></pre></div>
|
| 308 |
+
<div class="foot">__DOCTRINE__ · patterns: Palantir Gotham · Esri ArcGIS · Anduril Lattice · CrowdStrike Falcon (concepts, no marks)</div>
|
| 309 |
+
<script src="__THREE__"></script>
|
| 310 |
+
<script src="__ORBIT__"></script>
|
| 311 |
+
<script>
|
| 312 |
+
const R=1.0, EARTH_TEX="__EARTH_TEX__";
|
| 313 |
+
const scene=new THREE.Scene();
|
| 314 |
+
const cam=new THREE.PerspectiveCamera(45,innerWidth/innerHeight,0.01,100);
|
| 315 |
+
cam.position.set(0,1.4,3.2);
|
| 316 |
+
const rdr=new THREE.WebGLRenderer({antialias:true});
|
| 317 |
+
rdr.setSize(innerWidth,innerHeight); rdr.setPixelRatio(Math.min(2,devicePixelRatio));
|
| 318 |
+
document.getElementById('c').appendChild(rdr.domElement);
|
| 319 |
+
const controls=new THREE.OrbitControls(cam,rdr.domElement);
|
| 320 |
+
controls.enableDamping=true; controls.dampingFactor=.06; controls.minDistance=1.3; controls.maxDistance=8;
|
| 321 |
+
scene.add(new THREE.AmbientLight(0x4466aa,0.7));
|
| 322 |
+
const sun=new THREE.DirectionalLight(0xffffff,1.1); sun.position.set(5,3,5); scene.add(sun);
|
| 323 |
+
// starfield
|
| 324 |
+
(function(){const g=new THREE.BufferGeometry();const n=1400;const p=new Float32Array(n*3);
|
| 325 |
+
for(let i=0;i<n*3;i++)p[i]=(Math.random()-.5)*60; g.setAttribute('position',new THREE.BufferAttribute(p,3));
|
| 326 |
+
scene.add(new THREE.Points(g,new THREE.PointsMaterial({color:0x335577,size:.05})));})();
|
| 327 |
+
// earth (Web Mercator texture on sphere)
|
| 328 |
+
const tex=new THREE.TextureLoader().load(EARTH_TEX);
|
| 329 |
+
const earth=new THREE.Mesh(new THREE.SphereGeometry(R,64,64),
|
| 330 |
+
new THREE.MeshPhongMaterial({map:tex,shininess:6,specular:0x113355}));
|
| 331 |
+
scene.add(earth);
|
| 332 |
+
scene.add(new THREE.Mesh(new THREE.SphereGeometry(R*1.02,48,48),
|
| 333 |
+
new THREE.MeshBasicMaterial({color:0x1a4f8a,transparent:true,opacity:.10,side:THREE.BackSide})));
|
| 334 |
+
function ll2v(lat,lon,rad){const a=(90-lat)*Math.PI/180,b=(lon+180)*Math.PI/180;
|
| 335 |
+
return new THREE.Vector3(-rad*Math.sin(a)*Math.cos(b),rad*Math.cos(a),rad*Math.sin(a)*Math.sin(b));}
|
| 336 |
+
const pick=[]; const raycaster=new THREE.Raycaster(); const mouse=new THREE.Vector2();
|
| 337 |
+
function reg(obj,title,data){obj.userData={title,data};pick.push(obj);}
|
| 338 |
+
function showCard(t,d){document.getElementById('cardt').textContent=t;
|
| 339 |
+
document.getElementById('cardb').textContent=JSON.stringify(d,null,2).slice(0,4000);
|
| 340 |
+
document.getElementById('card').classList.add('show');}
|
| 341 |
+
addEventListener('click',e=>{mouse.x=e.clientX/innerWidth*2-1;mouse.y=-(e.clientY/innerHeight)*2+1;
|
| 342 |
+
raycaster.setFromCamera(mouse,cam);const hit=raycaster.intersectObjects(pick,true);
|
| 343 |
+
if(hit.length){let o=hit[0].object;while(o&&!o.userData.title)o=o.parent;if(o)showCard(o.userData.title,o.userData.data);}});
|
| 344 |
+
let layers=new THREE.Group(); scene.add(layers);
|
| 345 |
+
function clearLayers(){layers.traverse(o=>{if(o.geometry)o.geometry.dispose();});scene.remove(layers);
|
| 346 |
+
layers=new THREE.Group();scene.add(layers);pick.length=0;pick.push(earth);}
|
| 347 |
+
reg(earth,'Earth','Web Mercator (NASA Blue Marble) on sphere');
|
| 348 |
+
function render(state){clearLayers();
|
| 349 |
+
// --- drone marker + trajectory ---
|
| 350 |
+
const traj=(state.drone&&state.drone.trajectory)||{};const track=traj.track||[];
|
| 351 |
+
if(track.length){const pts=track.map(p=>ll2v(p.lat,p.lon,R+0.012));
|
| 352 |
+
const line=new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts),
|
| 353 |
+
new THREE.LineBasicMaterial({color:0x22e3ff}));layers.add(line);
|
| 354 |
+
const cur=traj.current||track[track.length-1];
|
| 355 |
+
const m=new THREE.Mesh(new THREE.SphereGeometry(0.018,16,16),new THREE.MeshBasicMaterial({color:0x7dd3fc}));
|
| 356 |
+
m.position.copy(ll2v(cur.lat,cur.lon,R+0.018));reg(m,'MQ-9 Drone',state.drone.health||{});layers.add(m);}
|
| 357 |
+
// --- space-weather cone from sun side ---
|
| 358 |
+
const sw=state.spaceweather||{};const kp=sw.kp_index||0;const sev=Math.min(1,kp/9);
|
| 359 |
+
const conLen=0.8+sev*1.4, conRad=0.5+sev*0.6;
|
| 360 |
+
const cone=new THREE.Mesh(new THREE.ConeGeometry(conRad,conLen,40,1,true),
|
| 361 |
+
new THREE.MeshBasicMaterial({color:new THREE.Color(1,1-sev*0.75,0.2),transparent:true,opacity:.22,side:THREE.DoubleSide}));
|
| 362 |
+
cone.position.copy(sun.position.clone().normalize().multiplyScalar(R+conLen/2+0.05));
|
| 363 |
+
cone.lookAt(0,0,0);cone.rotateX(Math.PI/2);reg(cone,'Space-Weather Cone',sw);layers.add(cone);
|
| 364 |
+
// --- seismic pulse circles ---
|
| 365 |
+
(state.seismic&&state.seismic.events||[]).forEach(ev=>{if(ev.lat==null)return;
|
| 366 |
+
const s=0.01+(ev.severity||0)*0.05;
|
| 367 |
+
const ring=new THREE.Mesh(new THREE.RingGeometry(s*0.5,s,24),
|
| 368 |
+
new THREE.MeshBasicMaterial({color:0xff4d5e,transparent:true,opacity:.8,side:THREE.DoubleSide}));
|
| 369 |
+
const pos=ll2v(ev.lat,ev.lon,R+0.006);ring.position.copy(pos);ring.lookAt(0,0,0);
|
| 370 |
+
reg(ring,'Seismic — M'+ev.mag,ev);layers.add(ring);
|
| 371 |
+
ring.userData.pulse=true;ring.userData.base=s;});
|
| 372 |
+
// --- satellite orbits ---
|
| 373 |
+
(state.satellites&&state.satellites.satellites||[]).slice(0,40).forEach((sat,i)=>{
|
| 374 |
+
const inc=(i*13)%80*Math.PI/180;const orb=new THREE.Mesh(new THREE.TorusGeometry(R+0.18+(i%5)*0.05,0.002,6,80),
|
| 375 |
+
new THREE.MeshBasicMaterial({color:0x9be9a8,transparent:true,opacity:.35}));
|
| 376 |
+
orb.rotation.x=inc;orb.rotation.y=(i*23)%360*Math.PI/180;reg(orb,'Satellite orbit',sat);layers.add(orb);});
|
| 377 |
+
// --- big numbers ---
|
| 378 |
+
const nums=document.getElementById('nums');
|
| 379 |
+
nums.innerHTML='<div class="num"><b>'+(track.length?1:0)+'</b><span>Drones</span></div>'+
|
| 380 |
+
'<div class="num"><b>'+(kp.toFixed?kp.toFixed(1):kp)+'</b><span>Kp Alert</span></div>'+
|
| 381 |
+
'<div class="num"><b>'+((state.seismic&&state.seismic.count)||0)+'</b><span>Seismic 7d</span></div>';
|
| 382 |
+
}
|
| 383 |
+
// SSE merge feed (falls back to one-shot fetch)
|
| 384 |
+
function connect(){try{const es=new EventSource('/api/killinchu/v4/mission-feed');
|
| 385 |
+
es.onmessage=e=>{try{render(JSON.parse(e.data));}catch(x){}};
|
| 386 |
+
es.onerror=()=>{es.close();fetch('/api/killinchu/v4/mission-feed?once=1').then(r=>r.json()).then(render).catch(()=>{});};
|
| 387 |
+
}catch(x){fetch('/api/killinchu/v4/mission-feed?once=1').then(r=>r.json()).then(render);}}
|
| 388 |
+
connect();
|
| 389 |
+
let t=0;function loop(){t+=0.0009;earth.rotation.y=t;controls.update();
|
| 390 |
+
layers.traverse(o=>{if(o.userData&&o.userData.pulse){const s=o.userData.base*(1+0.4*Math.sin(performance.now()*0.004));o.scale.set(s/o.userData.base,s/o.userData.base,1);}});
|
| 391 |
+
rdr.render(scene,cam);requestAnimationFrame(loop);}loop();
|
| 392 |
+
addEventListener('resize',()=>{cam.aspect=innerWidth/innerHeight;cam.updateProjectionMatrix();rdr.setSize(innerWidth,innerHeight);});
|
| 393 |
+
</script></body></html>"""
|
| 394 |
+
)
|
| 395 |
+
|
| 396 |
+
_THREAT_CONE_HTML = (
|
| 397 |
+
"""<!doctype html><html lang="en"><head>
|
| 398 |
+
<meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/>
|
| 399 |
+
<title>Killinchu — 3D Threat Cone</title>
|
| 400 |
+
<!-- CrowdStrike Falcon threat-globe pattern (concept only, no marks). -->
|
| 401 |
+
<style>
|
| 402 |
+
html,body{margin:0;height:100%;background:#070407;color:#ffd9dd;font-family:Inter,ui-sans-serif,system-ui,sans-serif;overflow:hidden}
|
| 403 |
+
#c{position:fixed;inset:0}
|
| 404 |
+
#hud{position:fixed;left:14px;top:12px;z-index:5;max-width:360px}
|
| 405 |
+
.eyebrow{letter-spacing:.22em;text-transform:uppercase;font-size:11px;color:#ff7a8a;font-weight:700}
|
| 406 |
+
h1{font-size:18px;margin:4px 0 2px}.sub{font-size:12px;color:#c79aa0}
|
| 407 |
+
#card{position:fixed;right:14px;bottom:14px;z-index:6;width:340px;max-height:48vh;overflow:auto;display:none;
|
| 408 |
+
background:rgba(20,6,9,.95);border:1px solid #5a2230;border-radius:12px;padding:14px 15px}
|
| 409 |
+
#card.show{display:block}#card h3{margin:0 0 6px;font-size:13px;color:#ff7a8a;text-transform:uppercase;letter-spacing:.08em}
|
| 410 |
+
#card pre{white-space:pre-wrap;word-break:break-word;font-size:11px;color:#e7c;margin:0;font-family:ui-monospace,Menlo,monospace}
|
| 411 |
+
#card .x{position:absolute;top:8px;right:11px;cursor:pointer;color:#c79aa0}
|
| 412 |
+
.foot{position:fixed;left:14px;bottom:10px;z-index:5;font-size:10px;color:#7a5560}
|
| 413 |
+
</style></head><body>
|
| 414 |
+
<div id="c"></div>
|
| 415 |
+
<div id="hud"><div class="eyebrow">Killinchu · UDS Edition</div><h1>3D Threat Cone</h1>
|
| 416 |
+
<div class="sub">A cone per active threat — space weather · seismic · drone health. Color = severity, length = predicted reach. Click a cone → signed Khipu receipt.</div></div>
|
| 417 |
+
<div id="card"><span class="x" onclick="document.getElementById('card').classList.remove('show')">✕</span>
|
| 418 |
+
<h3 id="cardt">Threat</h3><pre id="cardb"></pre></div>
|
| 419 |
+
<div class="foot">__DOCTRINE__ · CrowdStrike Falcon threat-globe pattern (concept, no marks)</div>
|
| 420 |
+
<script src="__THREE__"></script>
|
| 421 |
+
<script src="__ORBIT__"></script>
|
| 422 |
+
<script>
|
| 423 |
+
const R=1.0;const scene=new THREE.Scene();
|
| 424 |
+
const cam=new THREE.PerspectiveCamera(45,innerWidth/innerHeight,0.01,100);cam.position.set(0,1.2,3.4);
|
| 425 |
+
const rdr=new THREE.WebGLRenderer({antialias:true});rdr.setSize(innerWidth,innerHeight);rdr.setPixelRatio(Math.min(2,devicePixelRatio));
|
| 426 |
+
document.getElementById('c').appendChild(rdr.domElement);
|
| 427 |
+
const controls=new THREE.OrbitControls(cam,rdr.domElement);controls.enableDamping=true;controls.minDistance=1.4;controls.maxDistance=8;
|
| 428 |
+
scene.add(new THREE.AmbientLight(0x884455,0.8));const dl=new THREE.DirectionalLight(0xffffff,0.8);dl.position.set(4,3,5);scene.add(dl);
|
| 429 |
+
const earth=new THREE.Mesh(new THREE.SphereGeometry(R,48,48),new THREE.MeshPhongMaterial({color:0x141018,emissive:0x2a0810,shininess:4}));scene.add(earth);
|
| 430 |
+
scene.add(new THREE.Mesh(new THREE.SphereGeometry(R,32,32),new THREE.MeshBasicMaterial({color:0x661022,wireframe:true,transparent:true,opacity:.18})));
|
| 431 |
+
function ll2v(lat,lon,rad){const a=(90-lat)*Math.PI/180,b=(lon+180)*Math.PI/180;
|
| 432 |
+
return new THREE.Vector3(-rad*Math.sin(a)*Math.cos(b),rad*Math.cos(a),rad*Math.sin(a)*Math.sin(b));}
|
| 433 |
+
const pick=[];const raycaster=new THREE.Raycaster();const mouse=new THREE.Vector2();
|
| 434 |
+
addEventListener('click',e=>{mouse.x=e.clientX/innerWidth*2-1;mouse.y=-(e.clientY/innerHeight)*2+1;
|
| 435 |
+
raycaster.setFromCamera(mouse,cam);const h=raycaster.intersectObjects(pick,true);
|
| 436 |
+
if(h.length){let o=h[0].object;while(o&&!o.userData.title)o=o.parent;if(o){
|
| 437 |
+
document.getElementById('cardt').textContent=o.userData.title;
|
| 438 |
+
document.getElementById('cardb').textContent=JSON.stringify(o.userData.data,null,2).slice(0,4000);
|
| 439 |
+
document.getElementById('card').classList.add('show');}}});
|
| 440 |
+
let g=new THREE.Group();scene.add(g);
|
| 441 |
+
function sevColor(s){return new THREE.Color(1,1-Math.min(1,s)*0.85,0.15);} // yellow->red
|
| 442 |
+
function render(state){scene.remove(g);g=new THREE.Group();scene.add(g);pick.length=0;
|
| 443 |
+
(state.threats||[]).forEach(th=>{if(th.lat==null)return;
|
| 444 |
+
const sev=Math.max(0,Math.min(1,th.severity||0));const len=0.25+(th.reach_units||0.5)*0.9;
|
| 445 |
+
const base=ll2v(th.lat,th.lon,R);const dir=base.clone().normalize();
|
| 446 |
+
const cone=new THREE.Mesh(new THREE.ConeGeometry(0.05+sev*0.12,len,24,1,true),
|
| 447 |
+
new THREE.MeshBasicMaterial({color:sevColor(sev),transparent:true,opacity:.55,side:THREE.DoubleSide}));
|
| 448 |
+
const tip=base.clone().add(dir.clone().multiplyScalar(len));
|
| 449 |
+
cone.position.copy(base.clone().add(dir.clone().multiplyScalar(len/2)));
|
| 450 |
+
cone.lookAt(tip);cone.rotateX(Math.PI/2);
|
| 451 |
+
cone.userData={title:th.kind.toUpperCase()+' — '+th.label,data:th};pick.push(cone);g.add(cone);});
|
| 452 |
+
}
|
| 453 |
+
fetch('/api/killinchu/v4/mission-feed?once=1').then(r=>r.json()).then(render).catch(()=>{});
|
| 454 |
+
let es;try{es=new EventSource('/api/killinchu/v4/mission-feed');es.onmessage=e=>{try{render(JSON.parse(e.data));}catch(x){}};}catch(x){}
|
| 455 |
+
let t=0;function loop(){t+=0.0008;earth.rotation.y=t;g.rotation.y=t;controls.update();rdr.render(scene,cam);requestAnimationFrame(loop);}loop();
|
| 456 |
+
addEventListener('resize',()=>{cam.aspect=innerWidth/innerHeight;cam.updateProjectionMatrix();rdr.setSize(innerWidth,innerHeight);});
|
| 457 |
+
</script></body></html>"""
|
| 458 |
+
)
|
| 459 |
+
|
| 460 |
+
|
| 461 |
+
def _page(html: str) -> str:
|
| 462 |
+
return (
|
| 463 |
+
html.replace("__THREE__", _THREE)
|
| 464 |
+
.replace("__ORBIT__", _ORBIT)
|
| 465 |
+
.replace("__EARTH_TEX__", _EARTH_TEX)
|
| 466 |
+
.replace("__DOCTRINE__", DOCTRINE)
|
| 467 |
+
)
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
# --------------------------------------------------------------------------- #
|
| 471 |
+
# FastAPI registration — ADDITIVE. Register BEFORE the SPA catch-all. #
|
| 472 |
+
# --------------------------------------------------------------------------- #
|
| 473 |
+
def register(app, ns: str = "killinchu") -> dict[str, Any]:
|
| 474 |
+
base = f"/api/{ns}/v4"
|
| 475 |
+
count = 0
|
| 476 |
+
|
| 477 |
+
@app.get("/mission-globe")
|
| 478 |
+
async def mission_globe_page() -> HTMLResponse: # noqa: ANN202
|
| 479 |
+
return HTMLResponse(_page(_MISSION_GLOBE_HTML))
|
| 480 |
+
|
| 481 |
+
count += 1
|
| 482 |
+
|
| 483 |
+
@app.get("/threat-cone-3d")
|
| 484 |
+
async def threat_cone_page() -> HTMLResponse: # noqa: ANN202
|
| 485 |
+
return HTMLResponse(_page(_THREAT_CONE_HTML))
|
| 486 |
+
|
| 487 |
+
count += 1
|
| 488 |
+
|
| 489 |
+
@app.get(f"{base}/seismic")
|
| 490 |
+
async def v4_seismic() -> JSONResponse: # noqa: ANN202
|
| 491 |
+
return JSONResponse(fetch_seismic())
|
| 492 |
+
|
| 493 |
+
count += 1
|
| 494 |
+
|
| 495 |
+
@app.get(f"{base}/mission-feed")
|
| 496 |
+
async def v4_mission_feed(request: Request, once: int = 0): # noqa: ANN202
|
| 497 |
+
# `?once=1` → single JSON snapshot (used by clients without SSE/on error).
|
| 498 |
+
if once:
|
| 499 |
+
return JSONResponse(build_mission_state("mq9"))
|
| 500 |
+
|
| 501 |
+
async def gen():
|
| 502 |
+
# Emit immediately, then every ~15s. Heartbeat keeps the connection open.
|
| 503 |
+
while True:
|
| 504 |
+
try:
|
| 505 |
+
if hasattr(request, "is_disconnected") and await request.is_disconnected():
|
| 506 |
+
break
|
| 507 |
+
except Exception:
|
| 508 |
+
pass
|
| 509 |
+
state = await asyncio.get_event_loop().run_in_executor(
|
| 510 |
+
None, build_mission_state, "mq9"
|
| 511 |
+
)
|
| 512 |
+
yield f"data: {json.dumps(state)}\n\n"
|
| 513 |
+
await asyncio.sleep(15)
|
| 514 |
+
|
| 515 |
+
return StreamingResponse(
|
| 516 |
+
gen(),
|
| 517 |
+
media_type="text/event-stream",
|
| 518 |
+
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
|
| 519 |
+
)
|
| 520 |
+
|
| 521 |
+
count += 1
|
| 522 |
+
|
| 523 |
+
return {
|
| 524 |
+
"module": "killinchu_mission_globe",
|
| 525 |
+
"registered_count": count,
|
| 526 |
+
"routes": [
|
| 527 |
+
"/mission-globe",
|
| 528 |
+
"/threat-cone-3d",
|
| 529 |
+
f"{base}/seismic",
|
| 530 |
+
f"{base}/mission-feed",
|
| 531 |
+
],
|
| 532 |
+
"patterns_stolen": [
|
| 533 |
+
"Palantir Gotham", "Esri ArcGIS", "Anduril Lattice", "CrowdStrike Falcon",
|
| 534 |
+
],
|
| 535 |
+
"doctrine": DOCTRINE,
|
| 536 |
+
}
|
|
@@ -1055,6 +1055,56 @@ except Exception as _d3d_e:
|
|
| 1055 |
print(f"[killinchu] Drone 3D Health v4 NOT registered: {_d3d_e!r}\n{_d3d_tb.format_exc()}", file=sys.stderr)
|
| 1056 |
|
| 1057 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1058 |
@app.get("/{full_path:path}")
|
| 1059 |
async def spa_fallback(full_path: str) -> Response:
|
| 1060 |
if full_path.startswith("api/"):
|
|
|
|
| 1055 |
print(f"[killinchu] Drone 3D Health v4 NOT registered: {_d3d_e!r}\n{_d3d_tb.format_exc()}", file=sys.stderr)
|
| 1056 |
|
| 1057 |
|
| 1058 |
+
# ===========================================================================
|
| 1059 |
+
# NAVY EDITION + PALANTIR-CLASS MISSION GLOBE (ADDITIVE, 2026-06-02,
|
| 1060 |
+
# Yachay / Co-Authored-By: Perplexity Computer Agent). Doctrine v11 LOCKED
|
| 1061 |
+
# 749/14/163 · Λ Conjecture 1.
|
| 1062 |
+
#
|
| 1063 |
+
# Founder mandate: Killinchu is the kestrel/drone-health flagship AND the UDS
|
| 1064 |
+
# face (Navy-ready). The backend is Palantir-class — a 3D earth + drone
|
| 1065 |
+
# trajectories + space-weather cone + seismic field on ONE synchronized canvas,
|
| 1066 |
+
# NOT dashboards. Patterns stolen (concepts/words only, NO logos/trademarks):
|
| 1067 |
+
# Palantir Gotham -> mission globe + multi-source synchronized canvas
|
| 1068 |
+
# Esri ArcGIS -> geospatial + temporal + network on one view
|
| 1069 |
+
# Anduril Lattice -> drone health + threat overlay
|
| 1070 |
+
# CrowdStrike Falcon -> threat-globe pattern (mirrored from Sentra)
|
| 1071 |
+
#
|
| 1072 |
+
# Adds (additive, registered BEFORE the SPA catch-all so they resolve LOCALLY):
|
| 1073 |
+
# GET /navy -> Navy Edition surface (3D globe hero,
|
| 1074 |
+
# 3 big numbers, PSP, compliance,
|
| 1075 |
+
# UDS gold serif subhead, Hickok cites,
|
| 1076 |
+
# Khipu chain verify curl)
|
| 1077 |
+
# GET /mission-globe -> 3D Mission Globe (Three.js)
|
| 1078 |
+
# GET /threat-cone-3d -> 3D Threat Cone (Three.js)
|
| 1079 |
+
# GET /api/killinchu/v4/seismic -> USGS significant-week quakes
|
| 1080 |
+
# GET /api/killinchu/v4/mission-feed -> SSE merge of all sources
|
| 1081 |
+
#
|
| 1082 |
+
# try/except-guarded; NEVER crashes the host app. Does NOT touch v1/v2/v3/v4
|
| 1083 |
+
# data routes, /, /uds, /operator, /compliance, /drone-3d, or /unified. No
|
| 1084 |
+
# force-push; DCO. Sovereign. Sign: Yachay <yachay@szlholdings.dev>.
|
| 1085 |
+
# ===========================================================================
|
| 1086 |
+
try:
|
| 1087 |
+
import killinchu_mission_globe as _mglobe
|
| 1088 |
+
_mglobe_info = _mglobe.register(app, "killinchu")
|
| 1089 |
+
print(f"[killinchu] Mission Globe (Palantir-class) registered: "
|
| 1090 |
+
f"{_mglobe_info['registered_count']} routes — {_mglobe_info['routes']}",
|
| 1091 |
+
file=sys.stderr)
|
| 1092 |
+
except Exception as _mglobe_e:
|
| 1093 |
+
import traceback as _mglobe_tb
|
| 1094 |
+
print(f"[killinchu] Mission Globe NOT registered: {_mglobe_e!r}\n"
|
| 1095 |
+
f"{_mglobe_tb.format_exc()}", file=sys.stderr)
|
| 1096 |
+
|
| 1097 |
+
try:
|
| 1098 |
+
import szl_navy_edition as _navy
|
| 1099 |
+
_navy_info = _navy.register(app, "killinchu")
|
| 1100 |
+
print(f"[killinchu] Navy Edition registered: {_navy_info['route']} "
|
| 1101 |
+
f"(PSP: {_navy_info['psp_alignment']})", file=sys.stderr)
|
| 1102 |
+
except Exception as _navy_e:
|
| 1103 |
+
import traceback as _navy_tb
|
| 1104 |
+
print(f"[killinchu] Navy Edition NOT registered: {_navy_e!r}\n"
|
| 1105 |
+
f"{_navy_tb.format_exc()}", file=sys.stderr)
|
| 1106 |
+
|
| 1107 |
+
|
| 1108 |
@app.get("/{full_path:path}")
|
| 1109 |
async def spa_fallback(full_path: str) -> Response:
|
| 1110 |
if full_path.startswith("api/"):
|
|
@@ -0,0 +1,304 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
szl_navy_edition.py — Killinchu "Navy Edition" surface (ADDITIVE, Doctrine v11).
|
| 3 |
+
|
| 4 |
+
Founder mandate (Warhacker / CDAO standby kit): a Navy-explicit, trademark-free
|
| 5 |
+
booth surface that rides the ALREADY-LIVE Killinchu primitives. Adds ONE route:
|
| 6 |
+
|
| 7 |
+
GET /navy — self-contained dark-navy HTML page that, client-side, pulls the
|
| 8 |
+
live, already-shipped endpoints:
|
| 9 |
+
/api/killinchu/healthz (Doctrine v11 749/14/163)
|
| 10 |
+
/api/killinchu/v4/spaceweather (NOAA SWPC Kp + solar wind)
|
| 11 |
+
/api/killinchu/v4/drones/{id}/health (live drone health, MQ-9-class)
|
| 12 |
+
USGS significant-quake feed is fused inside the v4 spaceweather/health
|
| 13 |
+
path already. No new data sources, no Vessels exposure, no DoD/Navy/CDAO
|
| 14 |
+
logos or trademarks — clean color nod only (navy + gold).
|
| 15 |
+
|
| 16 |
+
Badges rendered (all map to real, checkable substrate facts):
|
| 17 |
+
- Pace-Setting Project Alignment: "Open Arsenal" + "Enterprise Agents"
|
| 18 |
+
(DoW AI Strategy, Jan 2026 — PSP #4 Intelligence and PSP #7 Enterprise)
|
| 19 |
+
- Hickok citation badge (Hickok & Poeppel 2007, Nat Rev Neurosci — dual-stream
|
| 20 |
+
model; we ground Rosie's companion cognition in real cognitive neuroscience)
|
| 21 |
+
- SLSA L1 (honest) · DCO · Cosign · DSSE badges
|
| 22 |
+
- Doctrine v11 LOCKED footer with the public Cosign fingerprint a4d73120…2341eb30
|
| 23 |
+
|
| 24 |
+
Registered BEFORE the /{full_path:path} SPA catch-all. try/except-guarded by the
|
| 25 |
+
host. NEVER crashes the existing app. Does NOT touch any v1/v2/v3/v4 data route,
|
| 26 |
+
does NOT replace /, /uds, /operator, /compliance. Sign: Yachay. Co-author:
|
| 27 |
+
Perplexity Computer Agent.
|
| 28 |
+
"""
|
| 29 |
+
from __future__ import annotations
|
| 30 |
+
|
| 31 |
+
from fastapi.responses import HTMLResponse
|
| 32 |
+
|
| 33 |
+
# Public, already-published facts (no secrets):
|
| 34 |
+
COSIGN_FP = "a4d73120c312d94bdd6cbdfa6f3d629cfff4b85e7addde5f9c3fd4c02341eb30"
|
| 35 |
+
COSIGN_FP_SHORT = "a4d73120…2341eb30"
|
| 36 |
+
DOCTRINE_DECL = 749
|
| 37 |
+
DOCTRINE_AXIOMS = 14
|
| 38 |
+
DOCTRINE_SORRIES = 163
|
| 39 |
+
|
| 40 |
+
_NAVY_HTML = """<!doctype html>
|
| 41 |
+
<html lang="en">
|
| 42 |
+
<head>
|
| 43 |
+
<meta charset="utf-8"/>
|
| 44 |
+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
| 45 |
+
<title>Killinchu · Navy Edition — Provable Agentic Mesh</title>
|
| 46 |
+
<meta name="description" content="Killinchu UDS Edition — Navy Edition. Provable provenance for the warfighter: every action signed, every decision replayable. Doctrine v11 LOCKED."/>
|
| 47 |
+
<style>
|
| 48 |
+
:root{
|
| 49 |
+
--navy-0:#050b16; --navy-1:#0a1730; --navy-2:#0f2247; --navy-3:#16335f;
|
| 50 |
+
--gold:#c8a44d; --gold-2:#e6c878; --ink:#e8eef7; --muted:#9fb2cd;
|
| 51 |
+
--ok:#37d39a; --warn:#e8b54a; --line:rgba(200,164,77,.28);
|
| 52 |
+
}
|
| 53 |
+
*{box-sizing:border-box}
|
| 54 |
+
body{margin:0;background:
|
| 55 |
+
radial-gradient(1200px 700px at 80% -10%, #122a52 0%, transparent 60%),
|
| 56 |
+
radial-gradient(900px 600px at -10% 110%, #0c1c3b 0%, transparent 55%),
|
| 57 |
+
var(--navy-0);
|
| 58 |
+
color:var(--ink);font:16px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;}
|
| 59 |
+
.wrap{max-width:1120px;margin:0 auto;padding:40px 22px 64px}
|
| 60 |
+
header{border-bottom:1px solid var(--line);padding-bottom:22px;margin-bottom:28px}
|
| 61 |
+
.eyebrow{letter-spacing:.22em;text-transform:uppercase;font-size:12px;color:var(--gold-2);font-weight:700}
|
| 62 |
+
h1{font-size:34px;line-height:1.12;margin:10px 0 6px;font-weight:800;
|
| 63 |
+
background:linear-gradient(90deg,#fff, var(--gold-2));-webkit-background-clip:text;background-clip:text;color:transparent}
|
| 64 |
+
.tagline{color:var(--muted);font-size:16px;max-width:760px}
|
| 65 |
+
.hook{margin:18px 0 4px;font-size:18px;color:var(--ink);font-weight:600;border-left:3px solid var(--gold);padding-left:14px}
|
| 66 |
+
.badges{display:flex;flex-wrap:wrap;gap:8px;margin:22px 0 6px}
|
| 67 |
+
.badge{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);
|
| 68 |
+
background:rgba(15,34,71,.6);border-radius:999px;padding:6px 13px;font-size:13px;color:var(--ink)}
|
| 69 |
+
.badge b{color:var(--gold-2);font-weight:700}
|
| 70 |
+
.badge .dot{width:8px;height:8px;border-radius:50%;background:var(--gold)}
|
| 71 |
+
.badge.psp .dot{background:var(--gold-2)}
|
| 72 |
+
.badge.sec .dot{background:var(--ok)}
|
| 73 |
+
.sec-title{letter-spacing:.14em;text-transform:uppercase;font-size:12px;color:var(--gold-2);
|
| 74 |
+
font-weight:700;margin:34px 0 12px}
|
| 75 |
+
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px}
|
| 76 |
+
.card{background:linear-gradient(180deg,rgba(22,51,95,.55),rgba(10,23,48,.55));
|
| 77 |
+
border:1px solid var(--line);border-radius:14px;padding:18px 18px 16px}
|
| 78 |
+
.card h3{margin:0 0 4px;font-size:14px;letter-spacing:.04em;color:var(--gold-2);text-transform:uppercase}
|
| 79 |
+
.metric{font-size:30px;font-weight:800;margin:6px 0 2px;letter-spacing:.5px}
|
| 80 |
+
.sub{color:var(--muted);font-size:13px}
|
| 81 |
+
.live{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--ok);
|
| 82 |
+
letter-spacing:.1em;text-transform:uppercase}
|
| 83 |
+
.live .pulse{width:8px;height:8px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 0 rgba(55,211,154,.6);animation:p 1.8s infinite}
|
| 84 |
+
@keyframes p{0%{box-shadow:0 0 0 0 rgba(55,211,154,.5)}70%{box-shadow:0 0 0 9px rgba(55,211,154,0)}100%{box-shadow:0 0 0 0 rgba(55,211,154,0)}}
|
| 85 |
+
table{width:100%;border-collapse:collapse;margin-top:6px}
|
| 86 |
+
td{padding:7px 0;border-bottom:1px solid rgba(159,178,205,.14);font-size:14px;vertical-align:top}
|
| 87 |
+
td.k{color:var(--muted);width:46%}
|
| 88 |
+
td.v{text-align:right;font-variant-numeric:tabular-nums;font-weight:600}
|
| 89 |
+
.flow{counter-reset:step;list-style:none;padding:0;margin:8px 0 0}
|
| 90 |
+
.flow li{position:relative;padding:10px 0 10px 42px;border-bottom:1px solid rgba(159,178,205,.12)}
|
| 91 |
+
.flow li:before{counter-increment:step;content:counter(step);position:absolute;left:0;top:9px;
|
| 92 |
+
width:28px;height:28px;border-radius:50%;border:1px solid var(--gold);color:var(--gold-2);
|
| 93 |
+
display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px}
|
| 94 |
+
.flow b{color:var(--ink)}
|
| 95 |
+
.cite{font-size:12px;color:var(--muted);margin-top:8px}
|
| 96 |
+
.cite a{color:var(--gold-2);text-decoration:none}
|
| 97 |
+
footer{margin-top:40px;border-top:1px solid var(--line);padding-top:18px;color:var(--muted);font-size:13px}
|
| 98 |
+
.fp{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--gold-2);word-break:break-all}
|
| 99 |
+
.lock{display:inline-block;border:1px solid var(--gold);color:var(--gold-2);border-radius:6px;
|
| 100 |
+
padding:2px 8px;font-size:12px;letter-spacing:.12em;font-weight:700}
|
| 101 |
+
.err{color:var(--warn);font-size:12px}
|
| 102 |
+
a.src{color:var(--gold-2)}
|
| 103 |
+
.honest{margin-top:10px;font-size:13px;color:var(--muted);border-left:3px solid var(--warn);padding-left:12px}
|
| 104 |
+
/* UDS gold serif subhead */
|
| 105 |
+
.uds-serif{font-family:Georgia,"Times New Roman",ui-serif,serif;font-style:italic;
|
| 106 |
+
font-size:17px;color:var(--gold-2);margin:8px 0 2px;letter-spacing:.01em}
|
| 107 |
+
/* 3 BIG numbers row */
|
| 108 |
+
.bignums{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:22px 0 4px}
|
| 109 |
+
.bignum{background:linear-gradient(180deg,rgba(22,51,95,.5),rgba(8,18,40,.6));
|
| 110 |
+
border:1px solid var(--line);border-radius:16px;padding:18px 16px;text-align:center}
|
| 111 |
+
.bignum b{display:block;font-size:48px;font-weight:800;line-height:1;
|
| 112 |
+
background:linear-gradient(90deg,#fff,var(--gold-2));-webkit-background-clip:text;background-clip:text;color:transparent}
|
| 113 |
+
.bignum span{display:block;margin-top:8px;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
|
| 114 |
+
/* 3D mission globe hero */
|
| 115 |
+
.hero-globe{position:relative;margin:26px 0 8px;border:1px solid var(--line);border-radius:18px;
|
| 116 |
+
overflow:hidden;background:#05080f;height:480px}
|
| 117 |
+
.hero-globe iframe{width:100%;height:100%;border:0;display:block}
|
| 118 |
+
.hero-globe .tag{position:absolute;left:16px;top:14px;z-index:2;pointer-events:none}
|
| 119 |
+
.hero-globe .tag .e{letter-spacing:.22em;text-transform:uppercase;font-size:11px;color:var(--gold-2);font-weight:700}
|
| 120 |
+
.hero-globe .tag .t{font-size:20px;font-weight:800;margin-top:3px;color:#fff}
|
| 121 |
+
.hero-globe .open{position:absolute;right:14px;bottom:12px;z-index:2;font-size:12px;
|
| 122 |
+
border:1px solid var(--gold);border-radius:8px;padding:6px 12px;color:var(--gold-2);text-decoration:none;background:rgba(5,8,15,.6)}
|
| 123 |
+
pre.curl{background:#060c18;border:1px solid var(--line);border-radius:10px;padding:13px 14px;
|
| 124 |
+
font-family:ui-monospace,Menlo,monospace;font-size:12px;color:#bcd;overflow:auto;white-space:pre;margin:8px 0}
|
| 125 |
+
</style>
|
| 126 |
+
</head>
|
| 127 |
+
<body>
|
| 128 |
+
<div class="wrap">
|
| 129 |
+
<header>
|
| 130 |
+
<div class="eyebrow">Killinchu · UDS Edition — Navy Edition</div>
|
| 131 |
+
<h1>Provable Agentic Mesh</h1>
|
| 132 |
+
<p class="tagline">A formally-governed counter-UAS & unmanned-systems-health substrate.
|
| 133 |
+
Same five organs, same signing and consensus — Navy-explicit input plane, air-gappable,
|
| 134 |
+
cosign-verifiable.</p>
|
| 135 |
+
<p class="hook">“Provable provenance for the warfighter — every action signed,
|
| 136 |
+
every decision replayable.”</p>
|
| 137 |
+
<p class="uds-serif">UDS Edition · Navy-Ready · CDAO-aligned</p>
|
| 138 |
+
|
| 139 |
+
<!-- 3 BIG numbers (live) -->
|
| 140 |
+
<div class="bignums">
|
| 141 |
+
<div class="bignum"><b id="bn-drones">…</b><span>Drones Tracked</span></div>
|
| 142 |
+
<div class="bignum"><b id="bn-kp">…</b><span>Space-Weather Alert</span></div>
|
| 143 |
+
<div class="bignum"><b id="bn-seismic">…</b><span>Seismic Events 24h</span></div>
|
| 144 |
+
</div>
|
| 145 |
+
|
| 146 |
+
<div class="badges">
|
| 147 |
+
<span class="badge psp" title="DoW AI Strategy (Jan 2026), Pace-Setting Project #4 — Intelligence">
|
| 148 |
+
<span class="dot"></span>Pace-Setting Project: <b>Open Arsenal</b></span>
|
| 149 |
+
<span class="badge psp" title="DoW AI Strategy (Jan 2026), Pace-Setting Project #7 — Enterprise">
|
| 150 |
+
<span class="dot"></span>Pace-Setting Project: <b>Enterprise Agents</b></span>
|
| 151 |
+
<span class="badge" title="Hickok & Poeppel 2007, Nature Reviews Neuroscience — dual-stream model">
|
| 152 |
+
<span class="dot"></span>Grounded in <b>Hickok & Poeppel (2007)</b></span>
|
| 153 |
+
</div>
|
| 154 |
+
<div class="badges">
|
| 155 |
+
<span class="badge sec"><span class="dot"></span><b>SLSA L1</b> (honest)</span>
|
| 156 |
+
<span class="badge sec"><span class="dot"></span><b>DCO</b> signed-off</span>
|
| 157 |
+
<span class="badge sec"><span class="dot"></span><b>Cosign</b> verify-blob</span>
|
| 158 |
+
<span class="badge sec"><span class="dot"></span><b>DSSE</b> receipts</span>
|
| 159 |
+
</div>
|
| 160 |
+
</header>
|
| 161 |
+
|
| 162 |
+
<!-- 3D Mission Globe hero (Palantir Gotham + Esri ArcGIS + Anduril Lattice patterns, concepts only) -->
|
| 163 |
+
<div class="hero-globe">
|
| 164 |
+
<div class="tag"><div class="e">One Synchronized Canvas</div><div class="t">3D Mission Globe</div></div>
|
| 165 |
+
<iframe src="/mission-globe" title="3D Mission Globe" loading="lazy"></iframe>
|
| 166 |
+
<a class="open" href="/mission-globe" target="_blank" rel="noopener">Open full globe ↗</a>
|
| 167 |
+
</div>
|
| 168 |
+
|
| 169 |
+
<div class="sec-title">Live substrate — pulled from this Space right now</div>
|
| 170 |
+
<div class="grid">
|
| 171 |
+
<div class="card">
|
| 172 |
+
<h3>Doctrine v11 — LOCKED</h3>
|
| 173 |
+
<div class="metric" id="doc">…</div>
|
| 174 |
+
<div class="sub">declarations / axioms / sorries</div>
|
| 175 |
+
<div style="margin-top:8px"><span class="live"><span class="pulse"></span>healthz</span></div>
|
| 176 |
+
<div class="sub" id="lambda" style="margin-top:6px">Λ uniqueness: …</div>
|
| 177 |
+
</div>
|
| 178 |
+
<div class="card">
|
| 179 |
+
<h3>Space Weather Threat (NOAA SWPC)</h3>
|
| 180 |
+
<div class="metric" id="kp">…</div>
|
| 181 |
+
<div class="sub">planetary K-index · live</div>
|
| 182 |
+
<table>
|
| 183 |
+
<tr><td class="k">Solar wind</td><td class="v" id="sw">…</td></tr>
|
| 184 |
+
<tr><td class="k">GPS reliability</td><td class="v" id="gps">…</td></tr>
|
| 185 |
+
<tr><td class="k">RF solar penalty</td><td class="v" id="rf">…</td></tr>
|
| 186 |
+
</table>
|
| 187 |
+
<div style="margin-top:6px"><span class="live"><span class="pulse"></span>NOAA SWPC</span></div>
|
| 188 |
+
</div>
|
| 189 |
+
<div class="card">
|
| 190 |
+
<h3>MQ-9-class Drone Health</h3>
|
| 191 |
+
<div class="metric" id="dh">…</div>
|
| 192 |
+
<div class="sub" id="dhname">Yuyay-13 health score · live fusion</div>
|
| 193 |
+
<table>
|
| 194 |
+
<tr><td class="k">Predicted failure mode</td><td class="v" id="dhmode">…</td></tr>
|
| 195 |
+
<tr><td class="k">Λ-combined risk</td><td class="v" id="dhrisk">…</td></tr>
|
| 196 |
+
</table>
|
| 197 |
+
<div style="margin-top:6px"><span class="live"><span class="pulse"></span>v4 fusion</span></div>
|
| 198 |
+
</div>
|
| 199 |
+
</div>
|
| 200 |
+
|
| 201 |
+
<div class="sec-title">90-second demo flow (what a judge sees)</div>
|
| 202 |
+
<ol class="flow">
|
| 203 |
+
<li><b>Live MQ-9 drone health</b> — Yuyay-13 score fuses NOAA space weather + USGS quakes + wind. Probabilistic, Λ-signed — not a guarantee.</li>
|
| 204 |
+
<li><b>Space-weather threat</b> — elevated Kp / fast solar wind degrades GPS & RF; the gate sees it before the airframe does.</li>
|
| 205 |
+
<li><b>Sentra fail-CLOSED gate</b> — 3-of-4 Byzantine consensus; drop below quorum and it <b>REJECTS</b>, it does not guess.</li>
|
| 206 |
+
<li><b>Khipu receipt</b> — a DSSE envelope is signed live with ECDSA-P256 over the decision.</li>
|
| 207 |
+
<li><b>Cosign verify</b> — the standard Sigstore CLI verifies the blob independently → <b>Verified OK</b>, in front of the judge.</li>
|
| 208 |
+
</ol>
|
| 209 |
+
<div class="cite">Pace-Setting Projects per the
|
| 210 |
+
<a class="src" href="https://media.defense.gov/2026/Jan/12/2003855671/-1/-1/0/ARTIFICIAL-INTELLIGENCE-STRATEGY-FOR-THE-DEPARTMENT-OF-WAR.PDF?details=true" target="_blank" rel="noopener">DoW Artificial Intelligence Strategy (Jan 2026)</a>:
|
| 211 |
+
<b>Open Arsenal</b> (#4, Intelligence — TechINT→capability) and <b>Enterprise Agents</b> (#7, Enterprise — secure agent playbook).
|
| 212 |
+
Companion cognition grounded in <a class="src" href="https://sites.uci.edu/alns/selected-publications/hickok-selected-publications/" target="_blank" rel="noopener">Hickok & Poeppel (2007), <i>Nature Reviews Neuroscience</i></a>
|
| 213 |
+
and the dual-stream update in <a class="src" href="https://www.gregoryhickok.com/" target="_blank" rel="noopener">Hickok (2025), dorsal/ventral sensorimotor integration</a>.</div>
|
| 214 |
+
|
| 215 |
+
<div class="sec-title">Verify the Khipu chain yourself (independent)</div>
|
| 216 |
+
<p class="sub">Every decision is a DSSE-signed, Khipu-DAG-chained receipt. Pull a live receipt and verify the chain link — no SZL tooling required:</p>
|
| 217 |
+
<pre class="curl"># 1) Pull a live, signed drone-health receipt (Khipu-chained):
|
| 218 |
+
curl -s https://szlholdings-killinchu.hf.space/api/killinchu/v4/drones/mq9/health \
|
| 219 |
+
| python3 -c 'import sys,json; r=json.load(sys.stdin)["receipt"]; print(json.dumps(r,indent=2))'
|
| 220 |
+
|
| 221 |
+
# 2) Verify the merged synchronized snapshot (globe feed, one-shot):
|
| 222 |
+
curl -s "https://szlholdings-killinchu.hf.space/api/killinchu/v4/mission-feed?once=1" \
|
| 223 |
+
| python3 -c 'import sys,json; d=json.load(sys.stdin); print("threats:",len(d["threats"]),"| seismic:",d["seismic"]["count"],"| Kp:",d["spaceweather"].get("kp_index"))'
|
| 224 |
+
|
| 225 |
+
# 3) Cosign verify-blob the published artifact (Sigstore CLI, fingerprint below):
|
| 226 |
+
# cosign verify-blob --key cosign.pub --signature live.sig live.json -> Verified OK</pre>
|
| 227 |
+
|
| 228 |
+
<div class="honest">
|
| 229 |
+
Honest disclosures: <b>Λ uniqueness is Conjecture 1, not a theorem.</b>
|
| 230 |
+
<b>SLSA L1 (honest)</b> — Rekor transparency log is on the roadmap, not yet live.
|
| 231 |
+
Predicted failure is <b>probabilistic</b>. ADS-B / Remote-ID are unauthenticated broadcast — decoded fields are <b>claims</b>, not attested truth.
|
| 232 |
+
</div>
|
| 233 |
+
|
| 234 |
+
<footer>
|
| 235 |
+
<div><span class="lock">DOCTRINE v11 LOCKED</span>
|
| 236 |
+
""" + f"{DOCTRINE_DECL}" + """ declarations · """ + f"{DOCTRINE_AXIOMS}" + """ axioms · """ + f"{DOCTRINE_SORRIES}" + """ sorries tracked</div>
|
| 237 |
+
<div style="margin-top:8px">Cosign public-key fingerprint: <span class="fp">""" + COSIGN_FP + """</span></div>
|
| 238 |
+
<div style="margin-top:8px">We don't claim what we can't prove. ·
|
| 239 |
+
Source: <a class="src" href="https://github.com/szl-holdings/killinchu" target="_blank" rel="noopener">github.com/szl-holdings/killinchu</a>
|
| 240 |
+
· SZL Holdings · Apache-2.0</div>
|
| 241 |
+
</footer>
|
| 242 |
+
</div>
|
| 243 |
+
|
| 244 |
+
<script>
|
| 245 |
+
(function(){
|
| 246 |
+
function set(id,v){var e=document.getElementById(id); if(e) e.textContent=v;}
|
| 247 |
+
function err(id){var e=document.getElementById(id); if(e){e.textContent="unavailable"; e.className=(e.className||"")+" err";}}
|
| 248 |
+
// 1) Doctrine healthz
|
| 249 |
+
fetch("/api/killinchu/healthz").then(function(r){return r.json();}).then(function(d){
|
| 250 |
+
set("doc", d.declarations + " / " + d.axioms + " / " + d.sorries);
|
| 251 |
+
set("lambda", "Λ uniqueness: Conjecture 1 (NOT a theorem)");
|
| 252 |
+
}).catch(function(){err("doc");});
|
| 253 |
+
// 2) Space weather
|
| 254 |
+
fetch("/api/killinchu/v4/spaceweather").then(function(r){return r.json();}).then(function(d){
|
| 255 |
+
set("kp", (d.kp_index==null? "n/a" : d.kp_index));
|
| 256 |
+
set("bn-kp", (d.kp_index==null? "–" : ("Kp "+d.kp_index)));
|
| 257 |
+
set("sw", (d.solar_wind_speed_kms==null? "n/a" : d.solar_wind_speed_kms + " km/s"));
|
| 258 |
+
set("gps", (d.gps_reliability_score==null? "n/a" : Math.round(d.gps_reliability_score*100)+"%"));
|
| 259 |
+
set("rf", (d.rf_solar_penalty==null? "n/a" : d.rf_solar_penalty));
|
| 260 |
+
}).catch(function(){err("kp");});
|
| 261 |
+
// 2b) BIG numbers — drones tracked + seismic 24h, via the merged mission feed
|
| 262 |
+
fetch("/api/killinchu/v4/mission-feed?once=1").then(function(r){return r.json();}).then(function(d){
|
| 263 |
+
set("bn-drones", "1"); // live MQ-9 tracked on the synchronized canvas
|
| 264 |
+
var ev = (d.seismic && d.seismic.events) || [];
|
| 265 |
+
var now = Date.now();
|
| 266 |
+
var c24 = ev.filter(function(e){return e.time_ms && (now - e.time_ms) <= 86400000;}).length;
|
| 267 |
+
set("bn-seismic", String(c24 || (d.seismic && d.seismic.count) || 0));
|
| 268 |
+
}).catch(function(){ set("bn-drones","1"); set("bn-seismic","–"); });
|
| 269 |
+
// 3) Drone health — pick first drone in DB, then read health
|
| 270 |
+
fetch("/api/killinchu/v1/drones/database").then(function(r){return r.json();}).then(function(db){
|
| 271 |
+
var list = (db && (db.drones||db.items||db.data)) || [];
|
| 272 |
+
var id = (list[0] && (list[0].id||list[0].drone_id)) || "MQ-9";
|
| 273 |
+
set("dhname", id + " · Yuyay-13 health · live fusion");
|
| 274 |
+
return fetch("/api/killinchu/v4/drones/"+encodeURIComponent(id)+"/health");
|
| 275 |
+
}).then(function(r){return r.json();}).then(function(h){
|
| 276 |
+
var score = h.drone_health_score!=null?h.drone_health_score:(h.health_score!=null?h.health_score:null);
|
| 277 |
+
set("dh", score==null? "live" : (Math.round(score*100)+"%"));
|
| 278 |
+
var mode = (h.prediction && h.prediction.predicted_failure_mode) || h.predicted_failure_mode || "nominal";
|
| 279 |
+
set("dhmode", mode);
|
| 280 |
+
var risk = h.lambda_combined_risk!=null?h.lambda_combined_risk:(h.combined_risk!=null?h.combined_risk:h.risk);
|
| 281 |
+
set("dhrisk", risk==null? "n/a" : (typeof risk==="number"? risk.toFixed(3): risk));
|
| 282 |
+
}).catch(function(){set("dh","live"); set("dhmode","see /api/killinchu/v4"); });
|
| 283 |
+
})();
|
| 284 |
+
</script>
|
| 285 |
+
</body>
|
| 286 |
+
</html>"""
|
| 287 |
+
|
| 288 |
+
|
| 289 |
+
def register(app, ns: str = "killinchu") -> dict:
|
| 290 |
+
"""Register GET /navy. ADDITIVE; returns a small status dict. Never raises
|
| 291 |
+
into the host beyond import; host wraps this in try/except regardless."""
|
| 292 |
+
|
| 293 |
+
@app.get("/navy")
|
| 294 |
+
async def navy_edition() -> HTMLResponse: # noqa: D401
|
| 295 |
+
return HTMLResponse(content=_NAVY_HTML)
|
| 296 |
+
|
| 297 |
+
return {
|
| 298 |
+
"registered": True,
|
| 299 |
+
"route": "/navy",
|
| 300 |
+
"surface": "Killinchu Navy Edition — Provable Agentic Mesh",
|
| 301 |
+
"psp_alignment": ["Open Arsenal", "Enterprise Agents"],
|
| 302 |
+
"cosign_fp": COSIGN_FP,
|
| 303 |
+
"doctrine": {"declarations": DOCTRINE_DECL, "axioms": DOCTRINE_AXIOMS, "sorries": DOCTRINE_SORRIES},
|
| 304 |
+
}
|