Calibrated against a full-day legacy report for vehicle KDE 638J:
without this rule we collapsed 15 dispatcher-visible trips into 3
(the algorithm waited for explicit ACC_OFF + stationary fixes that never
came in the polled data — the device just stops reporting between trips).
New rule: if mid-trip and the next fix arrives >=5 min after the previous
one (but <=30 min, which is still long_gap), close the trip at the prior
fix with end_reason='nofix_stop'.
Validation:
638J full day: legacy 15 trips, mine 15 trips, perfect alignment
728K half day: legacy 33 noisy trips, mine 9 clean trips
(stop-and-go traffic still consolidates because fixes
keep coming, just slow/stationary — not silence)
Also commits scripts/simulate_trips_from_legacy.py which runs the same
state machine in Python against REPORTS/*.json dumps for offline tuning.