Skip to content

Commit bef5693

Browse files
aarthy-dkclaude
andcommitted
fix(monitors): keep gated forecast band continuous (no zero-width pinch)
The freshness-gated forecast band collapsed to a zero-width point at the flat anchor (lower=upper=baseline), rendering as an hourglass for a future next-update window and as a band detached from history for an imminent one. Carry the next-refresh tolerance across the whole forecast so the band stays a continuous width that connects to the historical band; the mean line still holds flat at baseline then steps. Display-only — no effect on anomaly evaluation. TG-1131 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d6920ae commit bef5693

2 files changed

Lines changed: 12 additions & 5 deletions

File tree

testgen/common/monitor_forecast.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,16 @@ def gated_forecast_prediction(
120120
# typed throughout (baseline is already a float).
121121
lower_tol = float(definition.lower_tolerance) if definition.lower_tolerance is not None else None
122122
upper_tol = float(definition.upper_tolerance) if definition.upper_tolerance is not None else None
123+
# The band carries the next-refresh tolerance across the whole forecast, flat anchor included.
124+
# Anchoring the band to the tolerance — rather than collapsing it to the baseline at the flat
125+
# anchor — keeps it a continuous width that connects to the historical band and avoids a
126+
# zero-width pinch (which renders as an hourglass for a future window, or a band detached from
127+
# history for an imminent one). The mean line still holds flat at baseline, then steps.
123128
return {
124129
"method": "predict",
125130
"mean": {flat_anchor: baseline, window_end: next_refresh_mean},
126-
"lower_tolerance": {flat_anchor: baseline, window_end: lower_tol},
127-
"upper_tolerance": {flat_anchor: baseline, window_end: upper_tol},
131+
"lower_tolerance": {flat_anchor: lower_tol, window_end: lower_tol},
132+
"upper_tolerance": {flat_anchor: upper_tol, window_end: upper_tol},
128133
}
129134

130135

tests/unit/ui/test_monitors_dashboard.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,12 @@ def test_gated_prediction_anchors_at_now_when_window_started():
135135
mean = {str(NOW_MS + 3 * HOUR): 1200.0, str(NOW_MS + 27 * HOUR): 1300.0}
136136
result = gated_forecast_prediction(_gated_def(mean=mean), window, LAST_RUN)
137137
assert result["method"] == "predict"
138+
# mean holds flat at baseline then steps to the next-refresh forecast
138139
assert result["mean"] == {NOW_MS: 1000.0, NOW_MS + 3 * HOUR: 1200.0}
139-
# tolerances coerced from VARCHAR to float
140-
assert result["lower_tolerance"] == {NOW_MS: 1000.0, NOW_MS + 3 * HOUR: 950.0}
141-
assert result["upper_tolerance"] == {NOW_MS: 1000.0, NOW_MS + 3 * HOUR: 1400.0}
140+
# band carries the next-refresh tolerance across the whole forecast (continuous width, no
141+
# zero-width pinch at the flat anchor); coerced from VARCHAR to float
142+
assert result["lower_tolerance"] == {NOW_MS: 950.0, NOW_MS + 3 * HOUR: 950.0}
143+
assert result["upper_tolerance"] == {NOW_MS: 1400.0, NOW_MS + 3 * HOUR: 1400.0}
142144

143145

144146
def test_gated_prediction_anchors_at_window_start_when_future():

0 commit comments

Comments
 (0)