Severity: LOW — defensive (hardening)
Found in a whole-repo code review. In the L2→L3 fused-aggregate path, a per-series counter-derivative intent that arrives without an enclosing Window would be emitted range-less (no TimeRange node), with no error.
Location
crates/l2/src/lower.rs:132-141 (the other arm of the temporal-range extraction)
Root cause
Only Rate/Increase recover their range from the AggFunc itself. Changes/Delta/IDelta/Deriv/Resets/PredictLinear/DoubleExpSmoothing rely entirely on an enclosing L2 Window; if one reaches the converter without it, time_range is None and the intent is produced without a TimeRange.
Reachability
Invariant holds today: the PromQL frontend routes all of these through at0→extract_matrix (crates/frontend-promql/src/promql.rs), which requires a matrix and always sets window: Some(..), so windowed_aggregate always wraps them in Window. This is a missing defensive guard, contrasting the explicit WindowedReductionKeys guard just below at lower.rs:172.
Proposed fix
Return a LoweringError (or debug-assert) if a per-series range intent lands in the fused path with time_range == None, so a future front-end path can't silently drop the range.
Severity: LOW — defensive (hardening)
Found in a whole-repo code review. In the L2→L3 fused-aggregate path, a per-series counter-derivative intent that arrives without an enclosing
Windowwould be emitted range-less (noTimeRangenode), with no error.Location
crates/l2/src/lower.rs:132-141(theotherarm of the temporal-range extraction)Root cause
Only
Rate/Increaserecover their range from theAggFuncitself.Changes/Delta/IDelta/Deriv/Resets/PredictLinear/DoubleExpSmoothingrely entirely on an enclosing L2Window; if one reaches the converter without it,time_rangeisNoneand the intent is produced without aTimeRange.Reachability
Invariant holds today: the PromQL frontend routes all of these through
at0→extract_matrix(crates/frontend-promql/src/promql.rs), which requires a matrix and always setswindow: Some(..), sowindowed_aggregatealways wraps them inWindow. This is a missing defensive guard, contrasting the explicitWindowedReductionKeysguard just below atlower.rs:172.Proposed fix
Return a
LoweringError(or debug-assert) if a per-series range intent lands in the fused path withtime_range == None, so a future front-end path can't silently drop the range.