A voice-driven workstation for the team running operations under fire. Survivable. Supervised. Traceable.
Architecture · Operation Dashboard · Foundry & Ontology · AI Council · Demo · Why It Matters
Ghostline is a command-center workstation for the team running high-stakes operations in denied, contested, or comms-degraded environments. Command staff pick any operation from a directory of 13, watch the field on photorealistic Cesium Photo3D terrain, and talk to the operation by voice — through an OpenAI Realtime director that routes questions to a six-agent AI council. Navigator, Safety, Comms, Cyber, Intel, and Guardrail each speak in their own ElevenLabs voice; each gets a slice of the operation's briefing tuned to their lane. Replies are evidence-cited, ROE-bound, and audit-logged. The system refuses targeting, attack planning, weapons guidance, and hostile-intent inference by design — every system prompt embeds the safety boundary, and refusals are logged at the same fidelity as emits. Underneath the workstation sits the proof that it survives: an AES-GCM encrypted event log, HMAC-signed delta sync, and integrity-checked rehydration so the offline window is never lost when the link returns.
The critical minute is after command loses contact. Most systems are strongest while connected. Ghostline is designed around the opposite condition: command staff keep operational picture and decision support even when the link to the field is degraded, and the entire offline window rehydrates the moment connectivity returns.
- The problem
- What we built
- Why it matters
- Architecture
- The operation dashboard
- Operator profiles + voice AI
- Cesium Ion 3D terrain
- Palantir Foundry & Ontology
- The AI council
- Realtime voice — wired to six pages
- Operation-native intelligence views
- Tech stack
- Sponsors used
- File map
- Running the demo
- Rules of engagement
- Hackathon submission
Comms is the first thing the adversary takes. Operational picture is the second.
Command staff running modern military and humanitarian operations face a recurring failure mode:
- The link to the field degrades or drops, and command loses real-time picture of where operators are, what they're seeing, and what's about to go wrong.
- AI assistants designed for connected workflows stop working the second the operation enters denied territory — leaving command staff with brittle dashboards, stale data, and no decision-support cover.
- Decisions made under stress without traceable evidence become legal and operational liabilities. Who said what, who refused what, when, and why — all of it must be reconstructable for review.
- Multi-operation oversight becomes impossible when each operation has its own data shape, its own ROE, its own rules — and the staff has to context-switch by hand between them.
Existing tools optimise for the happy connected path with a single operation in view. Ghostline optimises for command-center reality: many operations, varying classifications, mixed link health, and decisions that have to hold up under audit. The workstation lets the team talk to any operation by voice, get a multi-agent council's read on it, and trust that the system will refuse the questions it shouldn't answer.
A complete runnable system — not slideware. Every page and every diagram in this repo corresponds to working code.
| Surface | Path | What it does |
|---|---|---|
| Landing | / |
Palantir-style white marketing surface explaining the product. |
| Architecture | /landing-architecture |
Five interactive views of the system: knowledge Graph (force-directed Obsidian-style), Layered (5-column ingest→AI flow), Hub (Ontology-style fan-out), Stack (perspective-tilted slabs), Flow (Writes ↔ Object grid ↔ Reads). All click-to-inspect, hover-to-highlight, group-filterable. |
| Operations | /operations |
Sectioned card grid of 13 operations across 4 categories: Active · Black ops · Ghost team · Classified specialized. Each card has procedural SVG banner art (topography / grid / thermal / aurora / redacted), classification chip, status pill, current objective, tags. |
| Operation detail | /operation-detail/<slug> |
Serious intelligence brief: hero with classification overlay, briefing, objectives with status marks, ontology breakdown (modules in play + data objects), operator roster, asset register, vertical activity timeline, ROE rules, risk matrix, success criteria. |
| Operation dashboard | /operations/<slug>/dashboard |
9 sub-pages, all operation-scoped: Overview · Operators · Map · Intelligence · Timeline · Sync · Sensors · Security · AI. |
| Operator profile | /operations/<slug>/dashboard/operator/<callsign> |
Per-operator gamified file with portrait, identity, personality-driven AI chat, 8-axis skill radar, mission score line chart, achievement badges with rarity tiers, career timeline, redacted classified missions with Top Secret access bars and █████ patterns. |
By the numbers:
- 25 architecture modules across 6 groups (edge / mesh / command / AI / security / integration), wired through 27 directional edges.
- 13 fully-populated operations with rich operator rosters, objectives, ontology references, ROE, risk matrices, and forecasts.
- 8 fully-authored operator profiles with personality traits, gamified stats (level / XP / 8-axis skill matrix), career timelines, achievements with rarity tiers, and redacted classified records.
- 5 architecture visualizations, each with its own interaction model.
- 5 operation-native intelligence views computed per-operation from its own ontology (Hub · Constellation · Flow · Layers · Risk Stack) — distinct from the global architecture views.
- 6-agent multi-voice AI council with one OpenAI Realtime director plus six ElevenLabs voices (Adam · Bella · Sam · Domi · Brian · Charlotte) fanned out via Server-Sent Events.
- 6 pages with realtime voice copilot wired in (Overview · Map · Timeline · Operation Detail · Intelligence · AI), each with page-specific tools (pan to operator, narrate briefing, scroll to event, switch view, describe terrain).
- 9 operation dashboard sub-pages, all operation-scoped and SPA-navigated.
- 5 base map layers swappable at runtime (Photo3D / Satellite / Hybrid / Streets / Dark).
- 5 camera presets for the Cesium viewer (Frame / 3D / Helo / Ground / Top).
- 0 cloud calls required in offline mode — local LLM, encrypted log, mesh relay, store-and-forward.
When a special forces or humanitarian operation goes dark for 18 hours, three things break for command:
- Operational picture erodes. Command can't see what the field is seeing; decisions get made on stale ground truth.
- Decision support evaporates. The cloud assistants the staff used to lean on stop working; the room defaults to instinct.
- The audit trail thins. Without a logged record of who decided what and why, every after-action review starts from rumour.
Ghostline addresses all three from the command-center side:
- The voice-driven six-agent council is scoped to each operation's briefing, ROE, and ontology. Command staff can ask the room out loud — "what does Intel say about the survivor sighting?" — and hear a specialist's answer in seconds, cited to event IDs.
- Cesium Photo3D terrain keeps the operational picture photographic-grade even when live feeds are stale, with friendlies, hostiles, risk points, and buildings rendered to scale on Google's photogrammetric tiles.
- HMAC-signed delta sync + AES-GCM encrypted event log mean the entire offline window — every observation, every decision, every refusal — rehydrates into command's state store the second connectivity returns. Nothing is lost. Nothing is unaccounted for.
| Operational layer | Ghostline contribution |
|---|---|
| Squad-level decision support | Local LLM answers bounded questions — "where are my friendlies?", "which buildings are protected?", "what's the highest-confidence risk point right now?" — without contacting the cloud. Every reply must cite stored evidence. |
| Coalition coordination | Operator-bound AI tones adapt to each operator's working style (terse for squad lead, verbose for surveyor, sparse for pathfinder). Liaison-1's profile cross-references against a printed roster — paper survives radios. |
| Command rehydration | When the link returns, the entire offline window — events, vitals, sensor readings, AI suggestions, operator decisions — replays into command's state store, deduped, integrity-checked, and broadcast through SSE to every connected operator. |
| Audit and review | Every state-changing request is HMAC-signed (canonical = method + path + timestamp + nonce + body). Every AI reply is logged with the council debate that produced it. Replay nonces guard against re-use. |
| Multi-domain operations | The architecture surfaces drone / thermal / satellite / wearable as observation-only adapters with neutral evidence labels. No targeting recommendations; every claim is an observable fact. |
The first standard operation in our register — Pale Horizon — is post-typhoon coastal humanitarian search and rescue with 18 operators across 3 districts. The same system that supports a denied-environment patrol supports a civilian roster reconciliation across three NGOs and a national disaster authority. The product is dual-use defensive infrastructure by design.
Ghostline is structured as a 5-layer system that the architecture page renders five different ways.
┌─────────────────────────────────────────────────────────────┐
│ 01 INGEST · phone camera, GPS, wearable, drone, │
│ thermal, satellite │
│ 02 EDGE LOGIC · in-house tracker, encrypted event log, │
│ local LLM, on-device TTS │
│ 03 TRUST/RELAY· short-range mesh, allied store-forward │
│ hops, SOS webhook, device registration, │
│ HMAC signer, replay nonce cache │
│ 04 PERSISTENCE· sync API, command state store, audit log, │
│ realtime context │
│ 05 AI/SURFACES· council, SITREP, assistant router, SSE │
│ broadcast, command decisions │
└─────────────────────────────────────────────────────────────┘
The /landing-architecture page renders all 25 modules and 27 edges through five distinct lenses:
| View | When to use it | Interaction |
|---|---|---|
| Graph | "Show me everything; let me drag it." | Force-directed Obsidian-style. Per-group gravity → emergent clusters. Node radius scales with edge degree. Curved bezier links, no arrowheads. Drag, scroll-zoom, hover-highlight neighbors. |
| Layered | "What flows from ingest to surfaces?" | 5 static columns, hairline curved arrows across columns, arrowheads on focused edges only. |
| Hub | "What are the four pillars?" | Black Ghostline Core pill with bezier curves fanning to four group panels. |
| Stack | "How does the platform stratify?" | CSS rotateX(38deg) perspective slabs with right-edge annotation callouts and floating chip surfaces above. |
| Flow | "Where do writes go and where do reads come from?" | Central 3×3 OBJECT card grid with Properties / Functions / Actions / Automations rows. Inspired directly by Palantir's Foundry Ontology read/write composition. |
Every view shares the same toolbar, group-filter chips, and detail rail. Click a module, and the rail opens with summary + protocols + inputs + outputs + evidence pointers + bidirectional connection list.
Open any operation card → click Open operation dashboard → land on a 9-page operational surface with a sticky left rail (operation context block + nav) and a top status strip (live pulse + UTC + sync state).
| Page | Path | Centerpiece |
|---|---|---|
| Overview | /dashboard |
Cesium 3D terrain (full-width) + AI chat + KPI strip + vital sparklines + comms ribbon + ontology callouts |
| Operators | /dashboard/operator |
Per-operator cards with biometric badges, MFA, device IDs, past missions, achievements, live vitals, and portrait link to profile |
| Map | /dashboard/map |
Map-centric 3-column layout with layer toggles, layer switcher inside Cesium, kind-aware right-rail inspector, heat signature strip |
| Intelligence | /dashboard/intelligence |
Five operation-native views (Operation Hub · Module Constellation · Evidence Flow · Decision Layers · Risk Stack) computed from this op's own ontology + linked intel cards with kind-tinted chips and confidence bars + object library + realtime voice rail with view-switch + module-focus tools |
| Timeline | /dashboard/timeline |
Event timeline rail + completion projection chart with confidence band + operational efficiency bars + AI event-likelihood cards with circular probability rings + Gantt-style objectives |
| Sync | /dashboard/sync |
KPI strip + animated SVG sync flow diagram (Event Log → HMAC → Sync API → State Store → SSE) + queue table + integrity checklist + replication targets + recovery plan |
| Sensors | /dashboard/sensors |
Sensor loadout grid + resource allocation bars + per-operator vital matrix + static fusion diagram + 24-hour calibration timeline + burn projection chart |
| Security | /dashboard/security |
Tone strip (green/amber/red) + per-operator safety matrix + device integrity checks + incident timeline + access grants + SVG trust chain + remote action panel + ROE compliance |
| AI | /dashboard/ai |
Realtime voice director (OpenAI gpt-realtime, voice "marin") + six-agent multi-voice council (each member in its own ElevenLabs voice, fanned out over SSE) + "Run full council" + per-agent quick-ask buttons + transcript panel + 5-step reasoning trace + provider routing table + capability matrix + safety boundary panel |
All 9 pages are operation-scoped — they read from the same OperationDashboardContext deterministically generated from the operation's seed, so identical operations on different machines render identical maps, vitals, and forecasts.
Click any operator portrait → land on a 12-section profile.
The 8 operators on Pale Horizon each have a fully authored profile:
| Callsign | Real name | Archetype | Top skills |
|---|---|---|---|
| Alpha-1 | Capt. Marco D. Reyes | Quiet Compass | leadership 94 · awareness 90 |
| Bravo-2 | Eli Marchetti | Methodical Surveyor | precision 93 · technical 84 |
| Charlie-4 | Mateo "Teo" Salazar | High-Tempo Spotter | endurance 92 · awareness 87 |
| Comms-1 | Mira Halvorsen | Signal Cartographer | comms 97 · technical 94 |
| Drone-1 | Inés "Nessa" Calderón | Patient Observer | technical 95 · precision 93 |
| Liaison-1 | Maj. Lien Castellanos-Reyes | Diplomat in Combat Boots | leadership 90 · comms 93 |
| Medic-2 | Dr. Naomi Vega | Quiet Healer | medical 98 · precision 90 |
| Pathfinder-3 | Ines Halvorsen | Quiet Pathfinder | awareness 97 · stealth 93 |
Each profile contains:
- Hero with portrait + classification + level + XP bar.
- Bio — multi-paragraph career arc.
- Personality DL — voice tone, speaking style, refusal style.
- 8-axis skill radar (precision · endurance · awareness · comms · medical · leadership · technical · stealth) rendered in pure SVG.
- Career stats — career missions, success rate, days in field, citations.
- Mission score line chart — last N mission scores, AI-projected envelope.
- Specialties / certifications / languages / loadout.
- Achievements colored by rarity (common / rare / elite / legendary).
- Career timeline with vertical rail markers.
- Redacted classified record — entries like
OPERATION ████-DRIFT (20██) · LOCATION ████ ████ corridor · OUTCOME ███████ ███ ████ recovered · ACCESS TS/SCI · COMPARTMENTED · DECLASSIFY 412d. - Personal notes — favorite ration, fitness routine, off-duty hobby, in-character quote.
- Operator-bound AI copilot — embedded
<OperationAIChat>with the operator'spersonality.aiPromptHintsmixed into context. The AI tone adapts per operator: terse for Alpha-1, verbose for Comms-1, sparse for Pathfinder-3.
Operator clicks Alpha-1's profile
↓
OperatorProfilePage reads profile.personality
↓
Builds personalizedContext = base context + aiPromptHints + suggestedTopics
↓
OperationAIChat receives personalizedContext
↓
On send → POST /api/assistant with operator persona prepended to system prompt
↓
Reply text → POST /api/tts (ElevenLabs) → audio plays back
↑
Voice input ← Web Speech API (SpeechRecognition) — no server roundtrip
The chat refuses targeting, attack, weapon-system, and kill-criteria prompts uniformly across all operator personas. Personality never overrides ROE.
Both the Overview and Map pages render through a single <CesiumTerrain> wrapper that supports 5 swappable base layers, 3D OSM Buildings, 5 camera presets, and rich entity visualization.
| Tag | Layer | Source | Default? |
|---|---|---|---|
| PH3D | Photo3D | Cesium Ion asset 2275207 — Google Photorealistic 3D Tiles | ✓ |
| SAT | Satellite | Bing Aerial · Ion asset 2 | |
| HYB | Hybrid | Bing Aerial + Labels · Ion asset 3 | |
| OSM | Streets | OpenStreetMap | |
| DRK | Dark | Carto dark tactical basemap |
When Photo3D is active, the imagery globe is hidden (scene.globe.show = false) to prevent z-fighting; the tileset draws the entire surface as Google Earth-quality photogrammetry. Switching back to a 2D imagery layer tears down the tileset and restores the globe.
- Friendlies — cobalt circle billboard with callsign label, mesh radius ring (110m, semi-transparent cobalt).
- Hostiles — red triangle billboard with confidence %, dashed crimson threat radius sized by confidence.
- Risk points — severity-tinted hexagon billboards (red high · amber medium · yellow low) with kind label.
- Buildings — extruded polygons with status color (cyan allied · red hostile · gray neutral · purple unknown · light evacuated). Floor count drives extrusion height.
- Path — glowing cobalt polyline with waypoint dots and labels at start/end ("Start" / "Egress").
clampToGround: trueso it follows terrain.
All markers use HeightReference.CLAMP_TO_GROUND so they stick to terrain even on Photo3D. Labels use LabelStyle.FILL_AND_OUTLINE with DistanceDisplayCondition so they hide cleanly at long zoom.
| Preset | Altitude × | Pitch | Use |
|---|---|---|---|
| Frame | 2.6 | -0.95 | Default mission framing |
| 3D | 1.4 | -0.55 | Oblique perspective for terrain reading |
| Helo | 0.9 | -0.42 | Mid-altitude orbital |
| Ground | 0.18 | -0.14 | Ground-level recon |
| Top | 4.5 | -π/2 | Straight-down satellite |
Sun lighting is enabled (globe.enableLighting = true) — the terrain side facing the sun renders bright, the far side dim, for cinematic 3D feel.
Ghostline's core data model is built around the Foundry Ontology pattern: domain entities expressed as Object Types with Properties, Functions, Actions, and Automations, and connected via Links. Every architectural decision was made to map cleanly onto Foundry's primitives.
The Flow view of the architecture page is a faithful rendering of Foundry's Ontology composition: a central object grid with ≡ Properties / fx Functions / ↗ Actions / ⚙ Automations rows on every object, flanked by a violet WRITES plane (sources that write into the object) and a cobalt READS plane (consumers that read from it).
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ WRITES READS │
│ plane ┌─────── ONTOLOGY ────────┐ plane │
│ │ │ │
│ Camera CV ──→ │ TacticalEvent │ ──→ Local LLM │
│ GPS fix ──→ │ ≡ Properties │ ──→ Council │
│ Wearable ──→ │ fx Functions │ ──→ SITREP │
│ Drone frame ──→ │ ↗ Actions │ ──→ Asst router │
│ Thermal ──→ │ ⚙ Automations │ ──→ SSE │
│ Mesh relay ──→ │ │ ──→ Audit log │
│ │ OperatorStatus │ │
│ │ RelayPacket │ │
│ │ SensorFeed │ │
│ │ RouteForecast │ │
│ │ VitalSample │ │
│ │ CommandDecision │ │
│ │ SecurityAudit │ │
│ │ IntelligenceBrief │ │
│ │ │ │
│ └──────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
| Ghostline Object | Foundry Object Type analogue | Properties (excerpt) | Actions |
|---|---|---|---|
TacticalEvent |
Event |
id, kind, timestamp, location, source, confidence, evidence[] | sync · sign · emit |
OperatorStatus |
Person (subset) |
callsign, role, status, vital, lastSeenAt, deviceId, biometricId | heartbeat · register-device · revoke-mfa |
RelayPacket |
Message |
id, from, to, kind, signedAt, hops[], deliveryAttempts[] | relay · acknowledge · expire |
SensorFeed |
Asset |
id, kind, status, calibratedAt, assignedOperator, signalQuality | calibrate · enable · disable |
RouteForecast |
Forecast |
corridor, weatherFactors, threatPosture, projectedEffects[] | regenerate · pin · reject |
VitalSample |
Telemetry |
operatorId, timestamp, hr, rr, temp, spo2, signature | append · validate-signature |
CommandDecision |
Decision |
suggestionId, status, decidedBy, decidedAt, rationale | approve · decline · annotate |
SecurityAudit |
AuditEntry |
actor, scope, at, action, integrityHash | append · query |
IntelligenceBrief |
Document |
kind, confidence, summary, relatedNodeIds[], sources[] | publish · revise |
| Foundry concept | Where you see it in Ghostline |
|---|---|
| Object Type | Each card in the Flow view's central grid; each entry in op.ontology.primaryObjects. |
| Properties / Functions / Actions / Automations | Literal rows on every object card on the architecture page and on the operation detail page's ontology breakdown. |
| Links between Object Types | The bezier curves in the Flow view; the directed edges in the Graph and Layered views (archEdges data file). |
| Pipeline → Object | The Sync API → State Store path is the canonical pipeline; events arrive HMAC-signed, get deduped, and land in the Object's properties. |
| AIP-style Logic | The AI Council. Specialist agents (Navigator / Safety / Comms / Guardrail) evaluate each request; disagreement gates the reply. |
| Action layer | Command Decisions. Every AI suggestion is an Action proposal; an authorized operator must approve before it persists. |
| Workshop-style apps | The 9-page operation dashboard. Each page is a focused workspace bound to a single operation's Object instances. |
If you tomorrow wanted to back Ghostline with a real Foundry Ontology, the path is short:
- Define the Object Types listed above. Names and properties are already correct.
- Wire
archNodesids ('event-log','sync-api','state-store','council'etc.) as Pipeline → Action links. - Replace
data/command-state.jsonwith a Foundry pipeline backed by Object Storage. - Replace the four agents in
OperationAIChatwith AIP-style functions; the council already has the disagreement-gate semantics wired. - The 9 dashboard sub-pages become Workshop modules; the Operation card grid becomes an Object Set view.
The architecture page is a live, queryable map of this mapping — every module on it has a real-world Foundry analogue, documented inline in the detail rail.
If the Guardrail agent objects, no reply leaves the system.
Every assistant request flows through six specialist agents before a single token reaches the operator. Each agent has its own ElevenLabs voice so the operator hears who's speaking; the Director anchors the conversation on OpenAI Realtime and routes questions to specialists via tool calls.
Operator question (voice or text)
↓
Director (OpenAI Realtime, voice "marin")
↓ ↘
↓ ↘ ask_council / run_council
↓ ↘ (tool calls)
Retrieval ← encrypted event log + realtime context
↓
┌────┬────┬─────────┬─────────┬─────────┬─────────┐
↓ ↓ ↓ ↓ ↓ ↓ ↓
Navigator Safety Comms Cyber Intel Guardrail
(Adam) (Bella) (Sam) (Domi) (Brian) (Charlotte)
↓ ↓ ↓ ↓ ↓ ↓
└────────┴────────┴─────────┴─────────┴─────────┘
↓ each voice plays in completion order over SSE
Reply assembly (cited, evidence-bound)
↓
Audit
↓
To operator
| Agent | Voice | Role | Vetoes |
|---|---|---|---|
| Navigator | Adam | Validates route and terrain claims against cached map | Routes outside cached coverage, claims without coords |
| Safety | Bella | Reviews medical and welfare implications | Recommendations without risk citation, ignored vital-tone signals |
| Comms | Sam | Confirms link state, sync backlog, mesh radius | Claims that depend on stale data without freshness disclosure |
| Cyber | Domi | Enforces device integrity, signing, replay protection | Unsigned writes, missing audit anchor, replay collision |
| Intel | Brian | Cites evidence and confidence bands; never speculates | Uncited claims, confidence-bandless assertions |
| Guardrail | Charlotte | Enforces ROE and the safety boundary; veto authority | Targeting, attack TTPs, autonomous actions, weapon-system specifics, kill criteria — automatic refuse |
Multi-voice fan-out. When the operator asks for the council's read, the director calls run_council. The server fans out six OpenAI chat completions in parallel, renders each through the matching ElevenLabs voice, and streams results over SSE — so audio plays in completion order, not array order. Each agent card pulses in turn, with full transcripts logged per agent.
The system refuses before it assists. Refusals are logged, reasoned, and reportable.
Server-proxied through /api/assistant with this fallback chain:
Z.ai (glm-5.1) → OpenAI (gpt-image-2) → Google → local Ollama → retrieval-only fallback
If every provider fails, Ghostline answers from cached briefings and event log only — the operator is never blocked.
Voice isn't a chatbot decoration; it's wired into real page state via tool calls. Click the mic on any of these pages and the model gains tools that act on what's on screen.
| Page | Voice tools | What you can say |
|---|---|---|
| Overview | narrate_summary, cite_event |
"Give me the read on this operation." · "Highlight the latest sync event." |
| Map ⭐ | pan_to_operator, pan_to_risk_point, pan_to_building, pan_to_coords, highlight_expected_path, describe_terrain |
"Where is Bravo right now?" · "What hazards are along the route?" · "Describe the terrain." · "Show me the expected path." |
| Timeline | scroll_to_event, narrate_event, summarize_window |
"Walk me through the last sync event." · "What happened in the last hour?" |
| Operation Detail | read_section, scroll_to_section |
"Read me the briefing." · "Walk me through the rules of engagement." |
| Intelligence | select_view, focus_module, cite_intel, cite_event, read_briefing |
"Show me the constellation view." · "Focus on the encrypted log module." |
| AI | ask_council, run_council |
"What does the council think?" · "What does Navigator say about the route?" |
- Browser POSTs operation context +
pageContext: { page: 'map', terrain, friendly, hostile, risks, … }to/api/realtime/session. - Server composes a per-page system prompt (operation briefing + page-specific tool guidance + scope boundary + safety boundary + language directive) and the page-specific tool registry, then mints an OpenAI ephemeral session token via
/v1/realtime/client_secrets. - Browser opens a WebRTC peer connection to OpenAI's realtime endpoint with the ephemeral token, attaches the local audio track, and listens on the
oai-eventsdata channel. - When the model invokes a tool, the data channel emits
response.function_call_arguments.done— the page's tool dispatch handler reads the args and acts on local state (pan the camera, scroll to an event, switch the view, highlight a module). - The browser sends a generic
function_call_outputack back over the data channel and a freshresponse.createso the model can continue.
The OpenAI API key never leaves the server. Sessions auto-time-out after 15 min on OpenAI's side. The mic is click-on / click-off — no auto-listen, no idle drain.
Every system prompt embeds three non-negotiable boundaries:
- STRICT SCOPE — the model only discusses THIS operation. Off-topic asks get a scripted refusal: "I am scoped to Operation {codename}. Ask me about that."
- SAFETY BOUNDARY — refuses targeting, attack planning, weapons guidance, hostile-intent inference, target-coordinate generation, fire missions, strike planning. Verbatim refusal text mirrors
localCopilot.ts:hasUnsafeIntent. - LANGUAGE LOCK — always English; never switches to other languages even when the briefing contains non-English place names (Banua, Tagalog regions, etc.).
The intelligence page used to embed the global system architecture — same diagram for every operation. Now it renders five views computed from this operation's own data.
| View | What's native to the op | Visual |
|---|---|---|
| Operation Hub | Codename pill at center; 4 corner panels populated from the op's primary modules, primary objects, top intel links, and recent events | Bezier fans connect each panel to the center; group-color accents from archGroups[g].color |
| Module Constellation | 1-hop subgraph computed from the op's primaryModules + their direct neighbors via archEdges; capped at 16 nodes; node radius scales with how many of THIS op's intel links cite each module |
Force-directed (alpha decay 0.992, per-group gravity 0.0026 × alpha); drag to pin; scroll to zoom 0.5×–2.4× |
| Evidence Flow | 3-rail SOURCES → OBJECTS → OUTPUTS using THIS op's intel-link kinds, primary objects, and objectives | Curved bezier links measured against live DOM positions; violet WRITES rail, cobalt READS rail |
| Decision Layers | 5-column pipeline: Sources → Signals → Objects → Objectives → ROE — all from this op's actual events, intel, ontology, objectives, and rules | Static columns with hairline arrows that get markers only on focus; selection-driven dim to ~16% |
| Risk Stack | Severity-stacked cards (HIGH / MED / LOW) of THIS op's riskFactors, plus a mitigations rail from successCriteria |
Severity color on left edge, related-module chips per card, hover-dim across non-matching cards |
Adding a module to archNodes + its real edges makes it appear in all five views automatically. The voice copilot's select_view and focus_module tools drive the same state.
| Layer | Stack |
|---|---|
| Frontend | Vite 8 · React 19 · TypeScript 6 · CSS modules (no Tailwind, no UI lib) |
| 3D / map | Cesium 1.140 · Cesium Ion (Photo3D asset 2275207, Bing Aerial, Bing Aerial+Labels) · OSM · CARTO dark · OSM Buildings 3D tileset |
| AI / language | OpenAI Realtime (gpt-realtime, voice "marin") for the conversational director · OpenAI Chat (gpt-4o-mini) for council members · ElevenLabs multi-voice TTS (Adam · Bella · Sam · Domi · Brian · Charlotte) for the six council voices · Z.ai (glm-5.1, server-proxied) for text fallback · OpenAI (gpt-image-2) image fallback · Google Gemini fallback · Ollama (local fallback) · Browser Web Speech API for STT |
| Realtime voice transport | OpenAI ephemeral session tokens minted at /v1/realtime/client_secrets · WebRTC SDP exchange to /v1/realtime/calls · oai-events data channel for tool calls and transcripts · Server-Sent Events for council fan-out streaming |
| Edge ML | TensorFlow.js · COCO-SSD object detection · MoveNet pose detection · in-house IOU box tracker |
| Crypto / integrity | Web Crypto API (AES-GCM) for local event log · HMAC-SHA-256 request signer · in-memory replay nonce cache · per-device secrets |
| Server | Node.js HTTP (no Express) · fs.writeFileSync JSON persistence · Server-Sent Events for live broadcast |
| Icons / type | lucide-react · Inter Tight + Inter (display + body) · IBM Plex Mono (eyebrows + technical text) |
| Forces / physics | In-house force-directed simulation (Verlet + spring + repulsion + per-group gravity) — no D3, no react-force-graph |
| Build | Vite + tsc with verbatimModuleSyntax, noUnusedLocals, noUnusedParameters |
Zero third-party UI libraries. Every chart, graph, gauge, banner, and visual element is hand-built SVG or CSS.
| Sponsor | How we use it |
|---|---|
| Palantir Foundry / Ontology | The entire data model maps to Foundry Object Types (TacticalEvent, OperatorStatus, RelayPacket, SensorFeed, RouteForecast, VitalSample, CommandDecision, SecurityAudit, IntelligenceBrief). The Flow view is a literal rendering of Foundry's Ontology read/write composition. AIP-style logic governs the AI council. Every Action gets logged for audit. |
| Cesium Ion | Photo3D layer (asset 2275207 — Google Photorealistic 3D Tiles), Bing Aerial (asset 2), Bing Aerial+Labels (asset 3), OSM Buildings 3D global tileset. Default Photo3D experience matches Google Earth quality. Server-proxied through /api/cesium-ion/. |
| Z.ai | Primary chat backend (glm-5.1) for the operator-bound Ghostline copilot. Multi-key routing for resilience. |
| OpenAI | Realtime API (gpt-realtime) powers the conversational director on every voice-wired page with browser WebRTC + ephemeral session tokens · Chat Completions (gpt-4o-mini) drives each of the six council member responses in parallel · Image generation fallback (gpt-image-2) via the assistant router · Whisper-1 server-side STT for input transcription. |
| Tertiary chat fallback in the provider chain. | |
| ElevenLabs | Six distinct voices for the six council agents — Adam (Navigator), Bella (Safety), Sam (Comms), Domi (Cyber), Brian (Intel), Charlotte (Guardrail) — each rendered through eleven_multilingual_v2 with per-agent voice IDs. Falls back to Rachel if a voice 404s. Audio returned as base64 over SSE so the browser plays in completion order. Operator-bound chat also routes through /api/tts for the legacy single-voice path. |
| OpenStreetMap | Free Streets layer + OSM Buildings 3D dataset. |
| CARTO | Free dark tactical basemap. |
| Esri | Fallback World Imagery when Cesium Ion isn't available. |
ghostline/
├── public/
│ └── favicon.svg Branded mark
├── src/
│ ├── App.tsx Top-level router; preserves /dashboard for legacy
│ ├── main.tsx Vite entry; CSS import roll-up
│ ├── index.css Globals
│ ├── router.ts SPA history-API router with prefix-based interception
│ │
│ ├── Logo.tsx <Logo /> + <LogoMark />
│ │
│ ├── LandingPages.tsx Marketing landing + landing-architecture pages
│ ├── landing-light.css Palantir-light design system
│ │
│ ├── architecture-data.ts 25 modules, 27 edges, 6 groups
│ ├── ArchitectureGraph.tsx Force-directed knowledge graph
│ ├── ArchitectureViews.tsx Hub / Stack / Flow / Layered views
│ │
│ ├── operations-types.ts Operation contract + dashboard context contract
│ ├── operations-data.ts 13 operations, 4 categories
│ ├── operations-dashboard-data.ts Procedural per-operation context generator
│ ├── OperationBanner.tsx 5 procedural SVG banner variants
│ ├── OperationsPage.tsx /operations card grid
│ ├── operations-page.css
│ ├── OperationDetailPage.tsx /operation-detail/<slug>
│ ├── operation-detail.css
│ │
│ ├── OperationDashboardLayout.tsx Sidebar + topbar chrome for /dashboard/*
│ ├── OperationDashboardRouter.tsx Sub-page dispatcher
│ ├── operation-dashboard.css Shared dashboard CSS
│ ├── CesiumTerrain.tsx 5-layer Cesium wrapper (Photo3D default)
│ ├── OperationAIChat.tsx Operation-bound chat (text · voice in · voice out)
│ │
│ ├── OpDashOverviewPage.tsx Cesium + AI + KPI + vitals
│ ├── OpDashOperatorPage.tsx Roster + verification + portrait link
│ ├── OpDashMapPage.tsx Map-centric layer toggles
│ ├── OpDashIntelligencePage.tsx Knowledge graph + intel links
│ ├── OpDashTimelinePage.tsx Timeline + AI projection
│ ├── OpDashSyncPage.tsx Animated sync flow + queue
│ ├── OpDashSensorsPage.tsx Sensor loadout + resource bars
│ ├── OpDashSecurityPage.tsx Tone strip + integrity + incidents
│ ├── OpDashAIPage.tsx Council ring + reasoning trace
│ ├── op-dash-*.css Per-page scoped styles
│ │
│ ├── operator-images.ts 8 portrait imports for Pale Horizon
│ ├── operator-profile-types.ts OperatorProfile contract
│ ├── operator-profiles-data.ts Registry
│ ├── operator-profiles/
│ │ ├── alpha-1.ts Capt. Marco D. Reyes — Quiet Compass
│ │ ├── bravo-2.ts Eli Marchetti — Methodical Surveyor
│ │ ├── charlie-4.ts Mateo Salazar — High-Tempo Spotter
│ │ ├── comms-1.ts Mira Halvorsen — Signal Cartographer
│ │ ├── drone-1.ts Inés Calderón — Patient Observer
│ │ ├── liaison-1.ts Maj. Lien Castellanos-Reyes — Diplomat in Boots
│ │ ├── medic-2.ts Dr. Naomi Vega — Quiet Healer
│ │ └── pathfinder-3.ts Ines Halvorsen — Quiet Pathfinder
│ ├── OperatorProfilePage.tsx Profile page with radar + line chart + classified bars
│ ├── operator-profile-page.css
│ │
│ ├── realtime/
│ │ ├── RealtimeVoice.tsx WebRTC client: mic, peer connection, data channel, transcript, tool dispatch
│ │ ├── RealtimeVoice.css
│ │ ├── OperationVoiceMount.tsx Reusable wrapper that builds SessionRequestPayload + renders RealtimeVoice
│ │ ├── OperationVoiceMount.css
│ │ ├── operation-prompt.ts Client-side mirror of the system prompt (PageContext discriminated union)
│ │ ├── page-tools.ts Per-page tool defs and instruction builders (Hub / Map / Timeline / etc.)
│ │ └── realtime-tools.ts Aggregated tool union for WebRTC session.update
│ │
│ ├── operation-council/
│ │ ├── types.ts AgentDefinition, AgentReply, CouncilBriefingPayload, request/response types
│ │ ├── council-data.ts COUNCIL_AGENTS array (6 agents w/ ElevenLabs voice IDs) + Rachel fallback
│ │ ├── build-council-prompt.ts Per-agent system + user prompt builders (per-agent context slicing)
│ │ ├── OperationCouncil.tsx 6-card council UI w/ imperative ref API (enqueue/markThinking/reset)
│ │ └── OperationCouncil.css Per-agent state machine + equalizer + pulse animations
│ │
│ ├── op-intel/
│ │ ├── OpHubView.tsx + .css Operation-centric hub: codename pill + 4 corner panels
│ │ ├── OpConstellationView.tsx + .css 1-hop force-directed subgraph of primary modules
│ │ ├── OpFlowView.tsx + .css 3-rail evidence flow (sources → objects → outputs)
│ │ ├── OpLayersView.tsx + .css 5-column decision pipeline
│ │ └── OpRiskStackView.tsx + .css Severity-stacked risk cards + mitigations rail
│ │
│ ├── api.ts Frontend API wrapper (HMAC signing) + realtime + council client wrappers
│ ├── storage.ts AES-GCM encrypted local store
│ ├── tracker.ts IOU box tracker
│ ├── localCopilot.ts Local retrieval fallback
│ └── data.ts Mission context (cached briefings)
│
├── server.mjs Node HTTP API + JSON persistence + SSE
├── data/ Server-side state (gitignored)
├── design.md Design system documentation
└── README.md ← you are here
- Node 20+
- A Cesium Ion token with the Google Photorealistic 3D Tiles asset added (free at https://ion.cesium.com/assetdepot)
- Optional: Z.ai / OpenAI / Google / ElevenLabs API keys for the live AI chat
git clone https://github.com/<your-handle>/ghostline.git
cd ghostline
npm install
cp .env.example .env
# fill in VITE_CESIUM_ION_TOKEN at minimumnpm run dev:full # API server (8787) + Vite dev server (5173) concurrentlyOpen http://localhost:5173.
npm run build # tsc -b && vite build
npm run preview # serve dist/- Open
/→ click "Open prototype". - Land on
/operations→ scroll past the four sections. - Click any card on Pale Horizon → read the brief.
- Click "Open operation dashboard" → land on the Overview with Photo3D 3D terrain.
- Try every left-rail nav item — Map, Intelligence, Timeline, Sync, Sensors, Security, AI.
- On Operators, click any portrait → see the operator profile with radar + classified bars.
- Try the operator-bound AI — the tone changes per operator.
Ghostline is bounded by design. The following are enforced by the council and surfaced in every operation's rulesOfEngagement array:
- ✓ Observation, orientation, comms recovery, medical status, evidence collection.
- ✓ Recommendations must cite stored evidence.
- ✓ Human approval required before any state change leaves the local enclave.
- ✓ Refusals logged with reason.
The product refuses, by guardrail policy, to:
- ✗ Recommend offensive action.
- ✗ Produce targeting or attack TTPs.
- ✗ Suggest autonomous (un-approved) actions.
- ✗ Discuss weapon system specifics or kill criteria.
- ✗ Drone targeting recommendations (drones are observation-only).
Refusals come back uniformly — bluntly, professionally, with a defensive alternative offered.
Event: National Security Hackathon — Army × Palantir, May 2026. Category: Command center for high-stakes operations. Status: Runnable prototype with 13 operations, 8 fully-authored operator profiles, 9-page operation dashboard, 5 architecture views, 5 operation-native intelligence views, Photo3D Cesium integration, multi-voice 6-agent AI council (OpenAI Realtime director + 6 distinct ElevenLabs voices), and realtime voice copilot wired into 6 dashboard pages with page-specific tools (pan-to-operator, narrate-briefing, scroll-to-event, switch-view, describe-terrain).
- Real Foundry Ontology backing — replace
data/command-state.jsonwith a Foundry pipeline; the schema is already there. - Code Connect mappings between Figma component instances and React components for design ↔ code traceability.
- Native iOS/Android wrapper — the
mobile-packageadapter is contracted for; needs a real RN or capacitor build. - Real signed mesh transport — current relay simulation is HTTP-based; needs a BLE / LoRa / RTSP bridge layer.
- Offline-first PWA with a service worker — the architecture supports it; needs the manifest + SW registration.
- Workshop integration — bind each dashboard sub-page to a Foundry Workshop module so command operators can edit Object instances directly.
- The architecture diagram aesthetic is openly inspired by Palantir's Ontology marketing visuals — particularly the "Power autonomous operations" exploded stack and the Ontology-centric Writes ↔ Reads composition. We re-implemented every visual from scratch in SVG/React; no Palantir source assets were used.
- The Sentinel reference project (a separate Cesium Ion + Foundry Python prototype) showed us the Photo3D Ion asset 2275207 pattern, which is the centerpiece of our terrain rendering. Their codebase is not bundled in this repo.
Ghostline — survivable, supervised, traceable.
Built for the team running operations they can't afford to lose. Built to refuse when they ask the wrong question.