The platform, as it actually is.
No brochure. No mock diagrams. This page documents the live system that is rendering it.
Four planes, composed.
Every operator action, every public page, every SITREP is a path through these four planes. They are independent and independently deployable.
Siphon · Data plane
Rate-limited polite collectors. Every source has provenance, TTL, owner. Sharded across pu2 (leader), bravo, big-server.
Prism · Analytical plane
Pure functions over the data plane. 150+ lenses, typed inputs, cached outputs. Location-aware by parameter.
Dispatch · Action plane
A BYOK comms gateway. Stateless. Fire-and-forget pushes from Prism. Rules engine on top.
Surfaces · Experience plane
Next.js and static HTML. Every surface reads Prism. Nothing talks directly to a raw source from the browser.
From photon to pager.
One lifecycle, repeated 280+ times a minute.
- 01
Source polls
Siphon module runs on a configured interval. Fetches a URL, parses a feed, reads a socket. Tags output with source id, timestamp, owner node.
pythonhttpxsqlite - 02
Normalised + stored
Every source module returns a typed payload. Written to the shared siphon DB. Other nodes read it over the WG tunnel.
postgressqlitewireguard - 03
Lens runs
A Prism lens declares its inputs (one or more siphon keys) and a compute function. It runs on an interval or on-demand. Output cached with TTL.
fastapipydanticredis - 04
Correlator fuses
A meta-lens stitches lens outputs into hypotheses. 'Aviation anomaly + GNSS degradation + solar flare' becomes a single correlated event.
blackboard - 05
Surface renders
Next.js pages and the static EM Globe call /api/{lens}. Sub-second response from cache most of the time.
next.jsreactthree.js - 06
Dispatch notifies
If a rule fires, Prism POSTs to Dispatch. Dispatch picks the right channel per recipient and fires off. Log written. Done.
smtptwiliotelegramapns
150+ lenses.
Examples drawn live from /api/lenses on Prism right now. Every name here resolves to a real JSON endpoint.
em_environmentspace · emElectromagnetic environment index. Fuses geomag, radio, solar, flare, ground.
geomagnetic_stormspaceStorm score + phase + trend. Kp, Dst, solar wind, IMF, coupling proxy.
aurora_viewingspace · sitePer-location aurora viewing score. Weather × Kp × moon × AQI.
stormfront_outlookweather3-day convective outlook for Southern UK. CAPE, shear, LPI, hazards.
stormfront_lightning_jumpweatherDetects rapid lightning-flash-rate jumps. Early storm intensification signal.
sitrepmetaCross-domain SITREP generator. Persona-tuned text narrative.
correlatormetaCross-lens event correlator. Builds hypotheses on the blackboard.
source_healthplatformSelf-observability. 283 sources, per-owner breakdown, failure modes.
atc_activeaviationIs ATC open at EGPK? Evidence from ADS-B, METAR, NOTAM, schedule.
airport_ops_forecastaviationNext-hour ops forecast. Weather, TAF, movements, NOTAM effects.
flight_etaaviationETA for scheduled arrivals from live ADS-B + ground speed + winds.
vessel_risk_scoremarinePer-vessel risk from AIS, weather, tide, fleet SAR coverage.
beach_safetymarine · civicCSO overflow × bathing water × weather × marine hazard → go/no-go.
harbour_accessibilitymarineTide × wind × weather for specific harbours in the Clyde estuary.
storm_trackerweather · gridLive storm impact: weather, rivers, rainfall, warnings, grid outages.
infrastructure_cascadecivicGrid + telecoms + water + transport cascade score for Ayrshire.
commuter_easecivicPer-location door-to-door ease: trains, roads, weather, fuel, outages.
grid_pulsegridFrequency, demand, generation, imbalance. 300s cadence.
carbon_windowgridWhen to run the kettle: real-time grid carbon intensity with forecast.
fuel_arbitragefuel · financeCross-fuel comparator: petrol, heating oil, gas, LPG, red, hydrogen, EV.
raynet_network_healthradio · civicClyde RAYNET 16-node AllStar status. Silence detector, hub flap.
cve_infrastructure_exposuresecurityAre our upstream providers in today's CVEs? InfoCon layered on top.
+ ~120 more. Every lens is a pure function of its declared inputs.
Dispatch is BYOK on purpose.
We do not want to be in the business of holding anyone's SMTP password. Bring your own keys; we forward, log, and track.
Channels
Email (SMTP, per-tenant), SMS, Telegram Bot, APNs/FCM push, webhook out. Add a channel: implement one adapter.
Shape
Three stateless hosts (big-server PM2, small-server PM2, pu2 launchd) fronted by the same nginx cert bundle. Any one dies, traffic re-routes.
Upstream
Prism calls dispatch with fire-and-forget POST /api/events/inbound. If dispatch is down, Prism retries. Sender is never blocked.
Ops
Every send is logged per-tenant. Per-channel rate limits. Per-recipient opt-out tables. Designed for regulators, not hustlers.
Mesh-first networking.
When the internet degrades — and it will — the platform keeps working.
WireGuard backbone
small-server is the hub at 10.200.0.0/24. big-server, pu2, bravo, halio all peer. Subnet forwarding through the hub is live.
- 10.200.0.9 pu2
- 10.200.0.10 big-server
- 10.200.0.8 dispatch leader
- 10.200.0.16 bravo
Reticulum mesh
A four-node Reticulum mesh runs on top. TCP-over-WG today, transport abstraction tomorrow — LoRa and packet radio bearers already in the backlog.
Two VPS, two more in the room.
Not a platform-as-a-service. A platform built from principles up.
| Node | Role | Location | Specs |
|---|---|---|---|
| big-server | Public web surface, PM2, intel plane | Phoenix, AZ | 8c / 16 GB / 80 GB |
| small-server | Multi-tenant apps, WG hub, relay | Phoenix, AZ | 4c / 8 GB / 60 GB |
| pu2 | Siphon leader, FTP ingest | Ayr, UK | mac mini |
| bravo | Siphon worker, vision | Ayr, UK | M4 Pro MacBook |
Process mgmt
PM2 on Linux, launchd on macOS. One process manager per OS. No Kubernetes in the loop.
DB
PostgreSQL 16 on big-server + small-server. Per-service DBs. Nightly pg_dump -Fc, 14-day local retention.
Deploy
git pull on the host, restart. Some services autossh-tunnel into the relay. No CI pipeline; no CD either.
How we build.
No fabricated data.
If we don't have it, the UI says so. Never invent coordinates, timestamps, counts, or status. Hard rule, not a guideline.
Everything through Siphon.
No surface talks directly to a third-party API. One gatekeeper, one rate limit, one place to audit TOS compliance.
Pure lenses.
A Prism lens is a pure function of its declared inputs. Same inputs, same output. Replayable, cacheable, explainable.
Identity at the edge.
QR code = token. Token = identity. No login flows for field kit; just scan and act.
BYOK everywhere it matters.
Customers bring their own Stripe, their own SMTP, their own Twilio. We don't want the liability.
Small team, legible code.
Built by one. No JIRA, no sprints, no theatre. Code is the contract.