DOC GK-013 TYPE ENGINEERING LOG SUBJECT DODGE RECALL 80 / 80

Who makes
Starlink
dodge?

SpaceX reported that Starlink satellites moved out of the way of other objects 355,848 times between June 2025 and May 2026 (as reported by Space.com). Screening for close approaches is free now. Who causes them is not published. DODGE screens every Starlink satellite against everything else in its altitude band once a day, from public CelesTrak data, names the owner of the other object, and signs the result. Live: dodge.gautamkhosla.com. Code: dodge, MIT. Data: CC BY 4.0.

WHO SCREENS FOR CLOSE APPROACHES STARGAZESPACEX TRACSSUS GOVERNMENT SPACE-TRACKUS GOVERNMENT WHO IS ON THE OTHER SIDENOT PUBLISHED SCREENS: YESSCREENS: YESSCREENS: YES 148,696 + 207,152 = 355,848 AVOIDANCE MANEUVERS, JUN 2025 TO MAY 2026 SPACEX SEMIANNUAL REPORTS TO THE FCC, AS REPORTED BY SPACE.COM. ABOUT 40 PER SATELLITE.
FIG 13.1 · Screening is solved. The record of who causes the risk is the part nobody keeps.

SEC. 01

Screening is free. Attribution is not.

SpaceX's semiannual reports to the FCC put Starlink's avoidance maneuvers at 148,696 from June to November 2025 and 207,152 from December 2025 to May 2026: 355,848 in a year, about 40 per satellite. Those figures come from Space.com's report on the filings; I have not reopened the filings themselves. Finding close approaches is no longer the hard part. SpaceX's Stargaze, the US government's TraCSS and Space-Track all screen for them.

What nobody publishes is the other half: which objects and operators cause the risk, who shares where their satellites are, and who leaves spent hardware behind. DODGE is that record, rebuilt every day from public data by code anyone can read and rerun.

It measures exposure and transparency, not blame. Most passes involve small satellites without propulsion or old hardware, which sit where physics puts them.

ONE RELEASE PER DAY SINCE 6 OCTOBER 2026 · NO GAPS 06 07 08 09 10 11 12 13 14 15 16 17 11 SEALED: MANIFEST + ATTESTATION OPEN CELESTRAK KEEPS ONLY THE LATEST ORBIT PER OBJECT. THE HISTORY EXISTS ONLY BECAUSE DODGE KEEPS IT.
FIG 13.2 · A day is sealed the morning after it ends. As of 17 October, days 6 to 16 carry a manifest; the 17th is still being recorded.

SEC. 02

The orbit history nobody keeps

CelesTrak publishes the current orbit of every tracked object and keeps only the latest one. There is no public history to download, so DODGE records its own, starting on 6 October 2026. A GitHub Actions job pulls the public element sets for active satellites, analyst objects, recent launches, all debris and all rocket bodies, plus the satellite catalog. It also pulls the ephemerides that operators publish themselves through CelesTrak's SupGP: Starlink and ten other fleets, including OneWeb, Kuiper, Planet and Iridium.

Operator ephemerides beat radar-based sets for the same object, so they win whenever both exist. DODGE does not use Space-Track data at all. Everything it screens is something a reader can download from the same public source.

ONE DAY, END TO END RECORDCELESTRAK SCREENSGP4 · 24 H ATTRIBUTESATCAT OWNER SEAL, SIGNSHA-256 · SIGSTORE PUBLISHRELEASES · SITE 10 S GRID FOR 24 H = 8,640 STEPS 100 KM CUBES: OWN CELL + 26 NEIGHBOURS CLOSEST APPROACH: tau = -(r . v) / (v . v) UNDER 10 KM: SGP4 AGAIN AT 50 MS KEPT: EVERY PASS UNDER 5 KM, AT MOST ONE PER PAIR PER 10 MINUTES
FIG 13.3 · The screen runs once a day on every object whose orbit reaches Starlink's altitude band.

SEC. 03

The screen

Every remaining object is propagated with SGP4, through Brandon Rhodes' wrapper of David Vallado's reference code, for 24 hours on a 10 second grid: 8,640 steps. At each step the positions go into 100 km cubes. For each Starlink, DODGE checks its own cube and the 26 around it and keeps every pair closer than 100 km. A unit test proves this finds exactly the pairs a full distance matrix finds.

Inside a step, closest approach comes from straight-line relative motion. That is good enough because two objects 100 km apart in low orbit feel almost the same gravity: the relative acceleration is about 0.12 m/s², which bends the path by about 1.5 m over five seconds. Any pass estimated under 10 km is propagated again with SGP4 at 50 ms steps, and passes that refine to under 5 km are kept.

One early mistake was which orbit to use. SupGP files can hold several fits for the same object, some dated ahead, and the first version took the newest one. The newest fit is not the right fit for a screen that starts now. The screen now takes the element set whose epoch is closest to the screen start (ed723fe), and that decision is written into the changelog because it can move published numbers.

RECALL · 6 OCT 2026 · 1,500 STARLINK × 1,500 OTHERS · 3 H BRUTE FORCE 80 FAST SCREEN 80 MISSED 0 BRUTE FORCE: EVERY PAIR, EVERY SECOND, THEN THE SAME 50 MS REFINEMENT
FIG 13.4 · The brute force is the judge, not the screen. It is slow on purpose: every pair, every second, no spatial hash and no straight-line shortcut.

SEC. 04

Does it miss anything?

A fast screen that quietly skips passes would still produce a convincing table, so the first check had to be something that does not trust the shortcut. On 6 October I took a random sample of real recorded objects, 1,500 Starlink and 1,500 others, and found every pass under 5 km over three hours by brute force: every pair, every second. Then I ran the fast screen on the same sample.

CheckJudgeResult
Recall on real dataBrute force, every pair every second80 of 80 found, 0 missed
Spatial hashFull distance matrix, points on cell edgesIdentical pairs
Crafted 53° vs 97.5° crossing20 ms brute force around the reported timeFound; line estimate within 200 m of SGP4

The spatial hash test and the crafted crossing live in the engine's unit tests, which run in CI before every daily screen; the screen does not publish if they fail. The recall check is different, and SEC. 08 says how.

TWO OUTSIDE JUDGES PHYSICS, PREDICTED ~600/H SCREEN, FOUND 512/H SPACEX MANEUVERS 355,848 PASSES UNDER 1 KM ~157,000 / YEAR SPACEX MANEUVERS AT 3 IN 10 MILLION, NOT AT A FIXED 1 KM. SAME ORDER OF MAGNITUDE IS THE CLAIM.
FIG 13.5 · Neither judge is precise. Both are independent of the code, which is the point.

SEC. 05

Physics and SpaceX as outside judges

Recall says the screen finds what is in its input. It says nothing about whether the totals are plausible, so I checked them against two things the code cannot influence.

A kinetic gas estimate. On 6 October the screen kept about 4,500 non-Starlink objects in the 160 to 600 km band, which holds about 2.4 × 10¹¹ km³. A 5 km miss radius is a cross-section of 78.5 km², and closing speeds average about 10 km/s. That predicts about 600 passes under 5 km per hour. The screen found about 12,300 a day, which is 512 an hour.

SpaceX's own count. About 430 passes under 1 km a day is roughly 157,000 a year, against 355,848 maneuvers. SpaceX maneuvers at a 3 in 10 million collision probability, which is far more cautious than a fixed kilometre and covers wider passes with large uncertainty. Same order of magnitude is all this check claims, and all it can.

PASSES UNDER 5 KM PER OBJECT PER DAY · FIRST SCREEN NO REGISTERED OWNER 6.48 CHINA 2.77 UNITED STATES 2.67 RAW TOTALS FOLLOW HOW MUCH HARDWARE SITS AT STARLINK'S ALTITUDES. PER OBJECT DOES NOT.
FIG 13.6 · Per object, Chinese and US hardware come close at the same rate. Unregistered objects come close most often.

SEC. 06

What the first day said

The first screen started on 6 October 2026 at 22:56 UTC and covered the next 24 hours: 11,143 Starlink satellites against 4,502 other objects crossing their altitudes, 12,290 predicted passes under 5 km and 431 under 1 km. The closest was 50 m, between STARLINK-30376 and a Chinese CZ-2D rocket body, closing at 13.9 km/s.

Per object, Chinese and US hardware come close at the same rate: 2.77 and 2.67 passes a day.

Objects with no registered owner come close most often, at 6.48 passes per object. Many are recent rideshare deployments still waiting to be identified, including some from SpaceX's own Transporter missions. About one pass in six involves a spent rocket stage or debris, hardware nobody can steer.

Eleven days later the totals are similar. As of the screen of 17 October: 11,156 Starlink, 4,572 others, 12,591 passes under 5 km, 464 under 1 km.

Read the closest pass with care. Public element sets are typically good to about a kilometre near epoch. A single predicted pass under a few hundred metres means close, not a measured 50 m. Totals and per-object rates are robust; single passes are indicative.

EACH MANIFEST NAMES THE ONE BEFORE IT MANIFEST 06FIRST LINK MANIFEST 07PREV: SHA-256(06) MANIFEST 08PREV: SHA-256(07) ... MANIFEST 16PREV: SHA-256(15) CHANGE ONE BYTE OF AN OLD FILE AND THE CHAIN BREAKS FROM THAT DAY ON. RULE: NEVER SEAL TODAY OR A FUTURE DAY. NEVER WRITE INTO A SEALED RELEASE.
FIG 13.7 · You do not have to trust DODGE. The verifier needs no network and no dependencies.

SEC. 07

Sealed, signed, and refusing to seal today

A public record is only worth something if it cannot be quietly rewritten. Every day's files get a SHA-256 manifest that names the exact hash of the previous day's manifest, and a Sigstore attestation from the repository's own screen workflow, recorded in the public Rekor log. Every daily release also carries SLSA provenance. A reader checks the hashes and the chain with a Python script that uses no network and no dependencies, and the signatures with gh attestation verify.

The guard I care most about is a refusal. The screen will not seal today or a future day, and it will never write into a release that is already sealed (3a9d097). A day that is still being recorded cannot be sealed without freezing a partial set of files, and a sealed day that can still change is not sealed. The parsers for incoming orbit data and the verifier itself are fuzzed with ClusterFuzzLite and Atheris, because they are the first code to touch input from outside.

WHAT BROKE, AND WHERE IT STANDS recorder died on a CelesTrak outageFIXED · PR #1 newest orbit fit picked, not the closestFIXED · ed723fe recall against brute force checked once, not dailyOPEN SCREENING GRADE. NOT A COLLISION PROBABILITY. NEVER FOR COLLISION AVOIDANCE.
FIG 13.8 · The headline number has one row behind it. That row should be a column.

SEC. 08

What broke, and what I would change

The recorder died on a CelesTrak outage. The scheduled run at 06:07 UTC on 7 October hit a CelesTrak timeout, the recorder raised, and the publish step then tried to upload a release with no files in it. Downloads now retry timeouts, connection errors and server errors at 20, 60 and 120 seconds; a run that still gets nothing is logged as a miss instead of crashing, and an empty upload is skipped with a warning. A real crash still fails the job (PR #1, with tests for each case).

CodeQL found files left open, unused imports and a redundant assignment (e37071e). Small, but it was in code that runs unattended every day.

The limits are in the data, not the code. Public element sets are good to about a kilometre. The screen does not model maneuvers after an element set's epoch, and Starlink maneuvers often, so some predicted passes will never happen. Objects without public element sets cannot be screened at all. DODGE has no covariance, so it cannot compute a collision probability and must not be used for collision avoidance.

What I would change: the 80 of 80 is one sample, on one day, over three hours. It is the strongest number on this page and it has a single row behind it. The recall check should run against brute force on a fresh sample every day, with the result sealed into that day's release next to the passes it vouches for.

SEC. 09

Follow-up: can public data see the burns?

DODGE's sealed history made a second question testable. Maneuver Ledger reads DODGE's sealed releases and looks for the step an avoidance burn leaves in the size of a satellite's orbit. SpaceX filed 207,152 avoidance maneuvers with the FCC for December 2025 to May 2026. Public element sets cannot rebuild them: the 207,152 was not reproduced.

In the cleanest test, burns of 16 cm/s or more are at most 2.8 per satellite-year, 8% of the lower filed rate.

The check I registered in advance failed. The public GP element sets and CelesTrak's SupGP sets agreed on 29% of steps beyond chance, against a line of 70%. So the result is a detection limit, not a count.

DOC GK-013 · DODGE · MIT, data CC BY 4.0 · recall 80 of 80 against brute force Previous log: GK-012 · Takehome →