MileageAlgorithm
The seam that lets more than one mileage algorithm exist at the same time.
Today a tracking app has exactly one distance algorithm, welded into the service that acquires the fixes. That makes three ordinary questions unanswerable: is the other algorithm better on this route, what does this threshold actually buy, and did the change I just made help. You cannot answer any of them by reading code, because the algorithm cannot be run without a phone, a drive, and a day.
This interface exists to make those questions cheap. Everything here is deliberately pure:
no coroutines, no
Dispatchers, no I/O, no loggingno clock — time arrives as Fix.timeMs and never as
now()no platform types, no Android, no dependencies at all
That purity is not tidiness for its own sake. It is the single property that makes replay, shadow-mode comparison and parameter sweeps possible: an algorithm that cannot be re-run deterministically over a recorded trace cannot be compared against anything, and a comparison you cannot re-run is an opinion.
:location is the right home precisely because it has zero dependencies and builds for every target including wasmJs. Keep it that way — the moment this file needs a dependency to compile, the harness that replays traces in a browser preview stops working.
ponytail: three implementations, not four. Two of the four known algorithms differ only in threshold constants, so they are two TuningProfiles of one class, not two classes. Sibling classes that differ only in numbers are the mistake this abstraction exists to avoid.