Systems / RESEARCH · ORBITWATCH · 2026
OrbitWatch: characterizing every cataloged orbit
Orbit characterization and pattern of life for every tracked object, from public element sets, held to a measured false-alarm bound and blind-tested against a sealed synthetic catalog. Two papers came out of it.
- 68,809
- cataloged objects characterized: orbit, changes over time, pattern of life2026-09-25
- 49 → 3 km
- median GPS propagation error at 30 days after restoring one resonance term; no fitted parameter2026-09-26
- 69.52 ± 0.07 m
- Earth's equatorial ellipticity recovered from 538 dead geostationary objects; textbook value 69.478 m2026-09-26
- 0.06 m
- how close the blind synthetic test came on that same measurement, readings sealed 17 seconds before unsealing2026-09-27
- 413
- phantom maneuvers per 1,000 object-years in a null catalog with no maneuvers at all; the number the detector is measured against2026-09-26
- 2
- preprints under review at Acta Astronautica2026-09-22
OrbitWatch characterizes every object in the public satellite catalog: its orbit, how that changes, and its operator's pattern of life, flagging a maneuver only when a measured false-alarm bound allows the word. A language model I serve then writes each report in plain language, with every number checked by code before it is published. Members get alerts by email and text. Two papers came out of it, and along the way it cut GPS propagation error from 49 km to 3 km with nothing fitted. A blind test against a sealed synthetic catalog lists what it recovered and what it missed.
The problem
Maritime Space Officers asked for a way to characterize what is in orbit: how each object moves, how that changes over time, and what its operator's pattern of life looks like, so that a real change stands out from noise. Public two-line element sets are noisy, the propagator is lossy, and anyone can make a detector that finds maneuvers everywhere. The hard part is knowing your false-alarm rate and saying it out loud.
What I built
A pipeline that propagates the public catalog, flags maneuvers only when a continuously measured false-alarm bound permits the word, and publishes what it finds on OrbitWatch with the explanation, the numbers, and the source on every figure. The purpose is characterization: each object's orbit, its changes over time, and its operator's habits. Treating the catalog as an instrument also recovers physical constants from the population, which is how the method is checked.
Three results I'd show:
- A propagation term switched back on. The standard propagator had a 12-hour resonance branch effectively disabled. Restoring it takes the median GPS satellite from 49.17 to 3.00 km of error at 30 days and from 4.66 to 0.227 km at 7, with one second of arithmetic per constellation and nothing fitted. The whole GPS gain comes from a single resonance argument.
- The equator is an ellipse, from dead satellites. 538 uncontrolled geostationary objects, 2022–2025, drift toward the gravitational wells. From their motion: ellipticity 69.52 m, minor axis at 14.95° W, libration periods of 2.06 and 2.54 years at the two wells. The 1960s geodesy answer is 69.478 m at 14.929° W.
- Does station-keeping relax before retirement? A registered, population-scale observational test in the geostationary belt, preprint one. Preprint two is the false-alarm control itself.
Moving the heavy steps to the GPU
OrbitWatch runs on a server in my house that also trains my weather models and refreshes the Space Operations Explorer every five minutes. On 12 September 2026 the archive behind it held about 183 million element sets for about 68,000 objects, more arithmetic than the server’s eight-core processor could spare time for. So I had the two heavy steps, the maneuver detector’s statistics and the drift fit, rewritten to run on the server’s two RTX 4080 graphics cards. Every object in the public catalog now goes through both, and the processor reads the archive and handles the smaller jobs.
The maneuver detector splits each object’s history into five-day blocks and takes the median and spread of each. It builds a baseline from the six blocks on either side and scores every step between element sets against it. On the card, each object’s whole history goes over at once and the block arithmetic runs as two compiled kernels. The drift fit looks for a slow rise in orbit size over the last 120 days in objects low enough to feel the atmosphere, where drag alone would shrink the orbit. For each object it takes the median slope between up to 4,000 pairs of daily points, and the card works through those pairs in double precision.
On 12 September 2026 I timed both versions of the detector on the same 1,000 objects and 1.22 million element sets, on one card. The GPU version made the same threshold and persistence decisions as the processor on all 1,074,766 steps, used 40% less processor time, and finished in 38.7 seconds against 51.2. A first GPU version had been slower than the processor, so it was rewritten before it went into service. Both steps ask a queue for about 320 MB of a card’s 16 GB and wait behind model training when the cards are busy.
The processor still reads the archive, builds the steps between element sets and the physical noise floor for each orbital element, and classifies each flagged change and estimates its size in meters per second. It also runs the studies behind the geostationary-belt pages, builds the site and publishes it. The written reports go to the Sparks, two machines that serve a language model.
On 30 September two more steps in the geostationary belt moved the same way. For the close-approach search, which measures how near each drifting dead satellite came to each working one it passed, the SGP4 propagator was ported line for line to the card. Scoring a year of those passes, 1,881,287 of them, took 5 hours 37 minutes on six processor cores in that night’s build and 4 minutes 18 seconds on one card. The passes and flags came out the same, and the closest-approach times agreed within 0.16 seconds. The check for one satellite moving in beside another went from 2 hours 31 minutes to about 12. Both are tested and not yet in the nightly build.
How it’s checked
A null catalog: 500 objects, two years, propagated with no maneuvers at all, run through the detector. It found 413 phantom maneuvers per 1,000 object-years, 43.8% of them blind. That number is the floor every claim is stated against, and a "demote list" names the numbers not safe to headline.
A blind test: an independently written synthetic 2024 catalog of 920 objects with its own physics and hidden constants, age-sealed, run through the shipped pipelines with readings committed before unsealing. Recovered: ellipticity and axis to 0.06 m and 0.09°, the air-density lag behind solar flux (0.88 vs a sealed 0.857 days), daily density level at r = 0.98. Not recovered: seasonal amplitudes (2.7–9.4× too large), the population calendar (recall 0.125), and the Moon check missed a 1% bar by 0.2%. Both lists are public.
A circularity audit, run when I asked whether the layered treatments were feeding data back into what we wanted to see: which studies consume a later study's product, which chains are independently anchored, whether headline numbers reproduce by re-derivation, and whether results are invariant to processing order. And one rule from a near-miss: never tune the detector on one fleet; Starlink's shell noise and burn style would set thresholds wrong for everyone else.
What happened
OrbitWatch is public with 17 figure primitives and 274 plain-language digests written by the Spark model and cached nightly. Uptake in the Information Warfare community is new and growing. The raw catalog data stays private under the provider's redistribution terms; methods, code, and findings are public.
Links and credits
Built withDerek Conklin (co-author). SGP4, Python, S3 and CloudFront, Qwen3-235B for digests. Analysis pipelines written with Claude Code and Codex under the audit rules above.