value_col over observations STRICTLY BEFORE the current row. Same frame as trailing_median — deliberately so: 08b’s forward-window auditor has ONE shape to whitelist, not one per aggregate. This is the aggregate a point-in-time RATE needs. A rate is not a median of per-period rates: it is sum(numerator) / sum(denominator) over the window, so that a 78-lap race carries more weight than a 44-lap one. Build it from two trailing_sum calls sharing a frame, never from a trailing_median of a ratio column. Returns NULL where fewer than min_observations valid observations precede the row — which is what distinguishes “no prior history” (NULL, unknowable) from “prior history with no events” (0.0, a real measurement). Ship trailing_observation_count() alongside so the NULLs are explainable from the data rather than silent.