Three decisions that mattered.
In the order they were discovered.
The physics is real, and it drives the story
Orbital period comes from Kepler's Third Law; altitude decay from a drag model derived from the energy-rate balance on a circular orbit — both pinned by unit tests against known values (a 400 km orbit's ~92.6 min period; GEO reproducing one sidereal day to 0.1%). Each satellite spends propellant on periodic station-keeping burns; when the tank runs dry, the drag model takes over and the orbit starts decaying on its own — the signal that triggers the deorbit recommendation, not a hardcoded rule.
A model that didn't work taught the most
Four subsystems degrade gradually — trend features (rolling mean/std/slope) handle them well. Comms doesn't: its fault is a step, and a 30-day trend window straddling a step gets swamped by the step itself. The first comms model scored 0.27 precision / 0.09 recall while every drift subsystem sailed through. The fix was a second feature family: change-point detectors comparing against a baseline lagged far enough back to exclude the step being detected.
The bigger problem was the threshold, not the features
The comms model's ROC-AUC was 0.97 — it was ranking almost perfectly. Positive cases averaged probability 0.31 against 0.03 for negatives, but scikit-learn's default 0.5 cutoff sat above nearly all of them. Each subsystem now gets its threshold chosen by GroupKFold cross-validation on the training satellites only, maximizing F1 on out-of-fold predictions. Comms went from F1 0.14 to F1 0.89.