These have been red since the initial commit. All four failed for the same
reason, and in every case the test was wrong rather than the detector.
EventDetector requires two conditions to hold on the SAME frame, and one of them
is a rolling-window statistic that takes time to respond. The tests ignored that
lag, so they described situations the detector cannot see - and could not have
seen at any point in its history.
Braking (3 tests). Each filled the accel window with a CONSTANT value, then
stepped the GPS speed down. The speed drop is therefore true on exactly one
frame, and on that frame the accel std dev is still ~0.75 against a 1.2
threshold, because the window is full of the constant. By the time the window
recovers (frame 4), prevSpeedMps has caught up and the drop is 0. The two
conditions never coincide and no BRAKING is possible. Constant accelerometer
output right up to the instant of a brake is not physical either: the IMU is
sampled continuously while GPS speed lags, so the shaking precedes the reported
drop. The tests now establish that variability during the cruise phase.
Stopping. The second episode ran for stoppingFrames + 5. But stopping requires
the accel std dev to be BELOW a threshold, and the window still held the five
moving samples from the acceleration burst between episodes. Those take 8 frames
to drain far enough for the std dev to fall under 0.15, leaving 17 of the 21
frames the event needs. The first episode is unaffected because the window starts
empty. The episode is now long enough to cover the settling time.
Verified by simulating the detector's exact arithmetic against both the old and
new inputs before touching the file: the old profiles produce no events, the new
ones produce BRAKING/HIGH, BRAKING/HIGH, BRAKING/MEDIUM and two STOPPING.
No production code changed - the detector behaves consistently and defensibly.
Assertions are unchanged; only the stimulus is now something a bicycle could
actually produce. Suite is 41 tests, 0 failures.