fix(simple_metrics): ignore unparseable frequency_alert and malformed adaptive_state (SIENTIAPDE-2190)
This commit is contained in:
@@ -100,8 +100,16 @@ def simple_metrics(config: dict[str, Any]):
|
||||
# SIENTIAPDE-1995: laborious flips `adaptive_state.escalated` on a threshold breach (and back
|
||||
# after the window is renewed without one) and bumps `updated_at`, which makes this tick
|
||||
# rewrite the schedule.
|
||||
if frequency_alert and (config.get('adaptive_state') or {}).get('escalated'):
|
||||
base['frequency'] = frequency_alert
|
||||
state = config.get('adaptive_state')
|
||||
# Hand-written docs: a malformed state must not raise and kill the tick for every model.
|
||||
if frequency_alert and isinstance(state, dict) and state.get('escalated') is True:
|
||||
try:
|
||||
# Temporal parses the schedule frequency on create/update; an unparseable value
|
||||
# would fail it, so keep `frequency` (create_schedule_config still warns).
|
||||
parse_frequency(str(frequency_alert))
|
||||
base['frequency'] = frequency_alert
|
||||
except ValueError:
|
||||
pass
|
||||
return {
|
||||
**base,
|
||||
'schema': 'sientia_data',
|
||||
@@ -121,7 +129,8 @@ MIN_FREQUENCY_ALERT_SECONDS = 60
|
||||
def frequency_alert_warning(frequency_alert: str | None) -> str | None:
|
||||
"""
|
||||
Warning message when `frequency_alert` is below the 1-minute floor or does not parse,
|
||||
otherwise None. Warn only: the configured value is kept (SIENTIAPDE-1995 decision 7).
|
||||
otherwise None. Warn only (SIENTIAPDE-1995 decision 7): a value below the floor is kept;
|
||||
an unparseable one is ignored by `simple_metrics()`, which keeps `frequency`.
|
||||
"""
|
||||
if not frequency_alert:
|
||||
return None
|
||||
|
||||
@@ -1057,6 +1057,18 @@ def test_create_schedule_config_warns_on_frequency_alert_below_floor(formatters)
|
||||
assert kwargs['metadata']['schedule_name'] == 'm1-simple_metrics-60m'
|
||||
|
||||
|
||||
def test_create_schedule_config_warns_on_frequency_alert_below_floor_on_update(formatters):
|
||||
input_data = _schedule_config_with_frequency_alert('30s')
|
||||
input_data['current_schedule_config'] = {'laborious': {'m1-simple_metrics-60m': '2026-10-06'}}
|
||||
|
||||
result = formatters.create_schedule_config(input_data)
|
||||
|
||||
assert 'm1-simple_metrics-60m' in result['to_update']['laborious']
|
||||
formatters.send_notification.assert_called_once()
|
||||
kwargs = formatters.send_notification.call_args.kwargs
|
||||
assert kwargs['notification_id'] == 'SIMPLE_METRICS_FREQUENCY_ALERT_BELOW_FLOOR'
|
||||
|
||||
|
||||
def test_create_schedule_config_no_warning_at_or_above_floor(formatters):
|
||||
formatters.create_schedule_config(_schedule_config_with_frequency_alert('5m'))
|
||||
|
||||
|
||||
@@ -158,6 +158,24 @@ def test_simple_metrics_frequency_alert_without_state_keeps_frequency():
|
||||
assert simple_metrics(_simple_metrics_config(frequency_alert='5m'))['frequency'] == '1h'
|
||||
|
||||
|
||||
def test_simple_metrics_escalated_unparseable_frequency_alert_keeps_frequency():
|
||||
# An unparseable frequency would make the Temporal schedule create/update fail.
|
||||
config = _simple_metrics_config(frequency_alert='5min', adaptive_state={'escalated': True})
|
||||
assert simple_metrics(config)['frequency'] == '1h'
|
||||
|
||||
|
||||
def test_simple_metrics_escalated_below_floor_frequency_alert_is_applied():
|
||||
# Decision 7: below the floor only warns, the value is kept.
|
||||
config = _simple_metrics_config(frequency_alert='30s', adaptive_state={'escalated': True})
|
||||
assert simple_metrics(config)['frequency'] == '30s'
|
||||
|
||||
|
||||
@mark.parametrize('adaptive_state', ['yes', {'escalated': 'false'}])
|
||||
def test_simple_metrics_malformed_adaptive_state_keeps_frequency(adaptive_state):
|
||||
config = _simple_metrics_config(frequency_alert='5m', adaptive_state=adaptive_state)
|
||||
assert simple_metrics(config)['frequency'] == '1h'
|
||||
|
||||
|
||||
def test_minimal_retrain():
|
||||
config = {
|
||||
'workflow_type': 'minimal_retrain',
|
||||
|
||||
Reference in New Issue
Block a user