A research interface should show its own seams
Most model visualizations are built to look convincing. Smooth surfaces, confident shapes, a camera that glides. The approximations that made the picture possible are usually somewhere in a notebook nobody opens.
When I built the 3D viewer for BEACON, I tried to do the opposite: put the seams on screen, where a reviewer has to look at them.
What the viewer is for
BEACON ranks satellite conjunction events by predicted risk and by how much an ensemble of models disagrees about them. Those outputs are tables. Tables are fine for computing metrics and bad for the question an analyst actually asks: what is going on with this particular event, and why is it near the top?
The viewer turns each ranked event into something inspectable. You select an event, scrub across warning horizons from the earliest available observation through one day before closest approach, and watch how the model probability and its uncertainty move as the encounter gets closer. Target and secondary paths can be overlaid, the camera can track either object, and the whole state can be exported as JSON, HTML, or a screenshot.
The uncertainty volumes are lying, and the UI says so
Here is the honest problem. The model does not produce orbital covariance. It produces a standard deviation in probability space — the spread of predictions across bootstrap ensemble members. That is a real quantity, but it is not a position error, and it cannot be rendered as one without inventing something.
The viewer renders an uncertainty envelope anyway, because a comparative visual is genuinely useful. It just refuses to pretend the mapping is physical:
sigma_proxy_km = 100 + 1800 * predictive_std + 45 * time_to_tca_days
95_percent_visual_envelope_km = 1.96 * sigma_proxy_km
That formula is a display convention. It is monotonic in the two things that should make an analyst less certain — model disagreement and time remaining — and it is arbitrary in its constants. It supports the sentence “this event carries more uncertainty than that one.” It does not support any sentence containing the word kilometres.
So the viewer labels it a proxy in the interface, not in a footnote.
Geometry modes, stated out loud
The second honesty problem is positional. When absolute target and secondary positions are available in the data, the viewer uses them. When they are not, it falls back — to relative state, to miss distance, or to a deterministic reference orbit.
Those fallbacks produce visibly different pictures of the same encounter. A viewer that silently degraded between them would be showing four different things while looking like one. So the current geometry mode is displayed in the UI and written into every exported JSON snapshot. If someone puts a BEACON screenshot in a slide deck, the mode travels with it.
The same applies to scale. Real conjunction separations are often too small to see
against an orbital view, so close approaches are display-scaled for visibility. The
original relative_distance_km is preserved alongside the scaled value, and
the scale factor is shown. The picture is exaggerated on purpose, and it says so.
The guardrail panel
The viewer carries a panel that answers four questions at a glance: is this real exported data or sample fallback data, which geometry mode is active, what display scale is applied, and is this research-only output. A validity watermark rides along with screenshots.
That panel exists because of how research images actually travel. A figure gets exported for a reviewer, ends up in a slide, and three months later someone is describing it as a collision-warning display. Nothing about the pixels prevents that. A watermark and a provenance line make it harder.
Practical note: caveats attached to the artifact survive. Caveats attached to the paper do not. If a visualization can be screenshotted, its limitations belong inside the frame.
Making the demo repeatable
A viewer that only works when its author drives it is a liability. The repository carries a demo and export checklist — run the tests, export the data, serve the viewer, hard refresh, then run a smoke test in the browser console that confirms the globe loaded, the viewer constructed, and the expected controls exist.
It is a small thing. It also means a reviewer can reproduce the exact demo path without asking me anything, which is most of what reproducibility means in practice.
What I would keep
The general lesson is not about orbits. If you build an interface on top of a model:
- Name the quantity you are actually rendering. If it is a proxy, put the word proxy in the interface.
- If your rendering has fallback modes, display which one is active.
- If you exaggerate scale for visibility, keep the true value and show the factor.
- Assume every frame will be screenshotted out of context, and design the frame accordingly.
BEACON is a research prototype and the viewer is a research interface. It is not an operational display, it does not propagate orbits, and it does not recommend maneuvers. The viewer, the export checklist and the browser smoke test all live in the repository if you want to run it yourself.