/** * Browser ESM adapter — Slot Ledger public snapshot → /orbis/satellites/ directory UI. * Schema: nexus-orbis-satellites/1 (additionalProperties:false on root). * C1_DESCRIPTIVE_ONLY. No invented positions/activity/measurements. * Walls / empty-copy live here — NOT in satellites.json. */ export const SCHEMA_VERSION = "nexus-orbis-satellites/1"; export const MANIFEST_PATH = "/orbis/satellites/satellites.json"; export const EMPTY_COPY = "Noch keine Satelliten im Slot Ledger zugelassen. Leere Oberfläche ist ehrlich — keine illustrativen Marker als Live-Satelliten."; const ROOT_ALLOWED = new Set([ "schema_version", "generated_utc", "slot_ledger_revision", "claim_ceiling", "nexus_link_verified", "satellites", "source_manifest_sha256", ]); const UTC_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/; function isUtc(t) { return typeof t === "string" && UTC_RE.test(t) && !Number.isNaN(Date.parse(t)); } export function validatePublicManifest(doc) { const errors = []; if (!doc || typeof doc !== "object" || Array.isArray(doc)) { return { ok: false, errors: ["manifest_not_object"] }; } for (const k of Object.keys(doc)) { if (!ROOT_ALLOWED.has(k)) errors.push(`extra_root_field:${k}`); } if (doc.schema_version !== SCHEMA_VERSION) { errors.push(`schema_version_expected_${SCHEMA_VERSION}`); } if (doc.claim_ceiling !== "C1_DESCRIPTIVE_ONLY") { errors.push("claim_ceiling"); } // Schema const false — reject integer 0 / truthy if (doc.nexus_link_verified !== false) { errors.push("nexus_link_verified_must_be_boolean_false"); } if (!isUtc(doc.generated_utc)) errors.push("generated_utc"); if (typeof doc.slot_ledger_revision !== "string" || !doc.slot_ledger_revision) { errors.push("slot_ledger_revision"); } if (!Array.isArray(doc.satellites)) { errors.push("satellites_not_array"); } else { for (const s of doc.satellites) { if (!s || typeof s !== "object") { errors.push("satellite_not_object"); continue; } if (!s.id || !s.name) errors.push(`satellite_missing_identity:${s?.id || "?"}`); if (s.admission !== "ADMITTED_C1") errors.push(`admission:${s.id}`); if (s.position != null) { const p = s.position; if ( !p || p.data_class !== "ORBIT_PREDICTED" || typeof p.lat_deg !== "number" || typeof p.lng_deg !== "number" || typeof p.alt_km !== "number" || !isUtc(p.element_epoch_utc) || !isUtc(p.calculated_utc) ) { errors.push(`invalid_position:${s.id}`); } if ("height_km" in p || "epoch_utc" in p || "lat" in p || "lon" in p) { errors.push(`producer_shape_leak:${s.id}`); } } } } return { ok: errors.length === 0, errors }; } /** Only satellites with canonical lat_deg/lng_deg may become globe markers. Empty → zero dynamic markers. */ export function selectPlottableSatellites(doc) { if (!doc || !Array.isArray(doc.satellites)) return []; return doc.satellites.filter( (s) => s && s.position && s.position.data_class === "ORBIT_PREDICTED" && typeof s.position.lat_deg === "number" && typeof s.position.lng_deg === "number" && typeof s.position.alt_km === "number" ); } export function renderPublicDirectory(doc, mountEl) { const v = validatePublicManifest(doc); mountEl.replaceChildren(); const root = document.createElement("section"); root.className = "orbis-slot-ledger-directory"; root.setAttribute("data-claim-ceiling", "C1_DESCRIPTIVE_ONLY"); const h = document.createElement("h2"); h.textContent = "ORBIS Slot Ledger — öffentliche Satellitenliste"; root.appendChild(h); const meta = document.createElement("p"); meta.className = "orbis-slot-ledger-meta"; meta.textContent = [ `Revision: ${doc.slot_ledger_revision || "unknown"}`, `Generiert (UTC): ${doc.generated_utc || "unknown"}`, `NEXUS_LINK_VERIFIED: ${doc.nexus_link_verified === false ? "false" : String(doc.nexus_link_verified)}`, `Claim: C1_DESCRIPTIVE_ONLY`, ].join(" · "); root.appendChild(meta); const walls = document.createElement("ul"); walls.className = "orbis-slot-ledger-walls"; const wallItems = [ "GOES-16 ist nicht als aktueller Primary X-ray / GOES-East hardcodiert. NOAA: GOES-19 als GOES-East seit 2025-04-07; GOES-16 Reserve. Aktive XRS nur aus dynamischer NOAA-Instrumentenzuweisung — sonst UNKNOWN.", "OMM (CSV/JSON) bevorzugt für neue Bahnelemente. TLE nur legacy optional; TLE-only Manifeste schließen 6-stellige Katalognummern aus (CelesTrak).", "Kartografie ≠ Telemetrie. SGP4 = ORBIT_PREDICTED; NOAA-XRS = LIVE_MEASURED_EXTERNAL. Beides beweist keinen NEXUS-Satellitenlink.", "Keine erfundenen Positionen, Aktivitäten oder Messwerte. ORBIT_PREDICTED nur nach Stage-B Adapter + REAL_SATELLITE_ADMISSION.", ]; for (const t of wallItems) { const li = document.createElement("li"); li.textContent = t; walls.appendChild(li); } root.appendChild(walls); if (!v.ok) { const err = document.createElement("p"); err.className = "orbis-slot-ledger-error"; err.textContent = `Manifest-Validierung fehlgeschlagen: ${v.errors.join("; ")}`; root.appendChild(err); mountEl.appendChild(root); return { ok: false, plottable: [] }; } const list = document.createElement("ul"); list.className = "orbis-slot-ledger-list"; const sats = doc.satellites || []; if (sats.length === 0) { const empty = document.createElement("p"); empty.className = "orbis-slot-ledger-empty"; empty.textContent = EMPTY_COPY; root.appendChild(empty); } else { for (const s of sats) { const li = document.createElement("li"); const a = document.createElement("a"); a.href = `/orbis/satellites/#sat-${encodeURIComponent(s.id)}`; a.textContent = s.name; li.appendChild(a); const detail = document.createElement("span"); const oeFmt = s.orbital_elements?.format || "none"; detail.textContent = ` · NORAD ${s.norad_cat_id || "?"} · admission=${s.admission || "?"} · orbit_elements=${oeFmt} · position=${s.position ? "bound" : "null"}`; li.appendChild(detail); list.appendChild(li); } root.appendChild(list); } const plottable = selectPlottableSatellites(doc); const plotNote = document.createElement("p"); plotNote.className = "orbis-slot-ledger-plottable"; plotNote.textContent = `Dynamische Globus-Marker (Slot Ledger, position≠null): ${plottable.length}. Illustrative Doctrine-Marker am Globus bleiben getrennt und sind keine Live-Satelliten. DYNAMIC_GLOBE=${ plottable.length > 0 ? "SLOT_LEDGER_MARKERS_PLUS_ILLUSTRATIVE_DOCTRINE" : "ILLUSTRATIVE_DOCTRINE_ONLY_ZERO_SLOT_LEDGER_MARKERS" }`; root.appendChild(plotNote); mountEl.appendChild(root); return { ok: true, plottable }; } export async function bootDirectory(mountSelector = "#orbis-slot-ledger-mount") { const mount = document.querySelector(mountSelector); if (!mount) { console.warn("[orbis-slot-ledger] mount not found:", mountSelector); return null; } try { const res = await fetch(MANIFEST_PATH, { cache: "no-store" }); if (!res.ok) { mount.textContent = `satellites.json nicht erreichbar (HTTP ${res.status}).`; return null; } const doc = await res.json(); return renderPublicDirectory(doc, mount); } catch (e) { mount.textContent = `Manifest-Ladefehler: ${e?.message || e}`; return null; } } export async function bootGlobeMarkers(eventName = "orbis-slot-ledger-markers") { try { const res = await fetch(MANIFEST_PATH, { cache: "no-store" }); if (!res.ok) return []; const doc = await res.json(); const v = validatePublicManifest(doc); if (!v.ok) return []; const plottable = selectPlottableSatellites(doc); window.dispatchEvent( new CustomEvent(eventName, { detail: { plottable, nexus_link_verified: false, slot_ledger_revision: doc.slot_ledger_revision || null, dynamic_globe: plottable.length > 0 ? "SLOT_LEDGER_MARKERS_PLUS_ILLUSTRATIVE_DOCTRINE" : "ILLUSTRATIVE_DOCTRINE_ONLY_ZERO_SLOT_LEDGER_MARKERS", }, }) ); return plottable; } catch { return []; } } if (typeof document !== "undefined") { const run = () => { void bootDirectory(); void bootGlobeMarkers(); }; if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", run); } else { run(); } }