Skip to content

Commit 538999a

Browse files
shrutipatel31facebook-github-bot
authored andcommitted
Update healthcheck statuses (#5020)
Summary: Update healthcheck status levels to better reflect their meaning and actionability: 1. Early Stopping Analysis: - ESS explicitly disabled: PASS → INFO (surface configuration choice) - ESS enabled, working correctly: PASS → INFO (informational, no action needed) - ESS not enabled but could save ≥10%: WARNING → INFO (nudge for feature upsell; not blocking the experiment) 2. Complexity Rating: - Advanced tier: WARNING → INFO (not blocking, informational) - Unsupported tier: FAIL → WARNING (concerning but not blocking) 3. Can Generate Candidates: - can_generate=False (recent trial): WARNING → INFO (expected behavior) 4. Baseline Improvement: - All objectives improved: PASS → INFO (valuable experiment takeaway) - Any objective not improved: WARNING → INFO (informational, not actionable) Differential Revision: D96412166
1 parent c889c57 commit 538999a

8 files changed

Lines changed: 38 additions & 44 deletions

ax/analysis/healthcheck/baseline_improvement.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,6 @@ def compute(
230230
num_improved = len(improved)
231231
num_total = len(comparison_list)
232232

233-
status = (
234-
HealthcheckStatus.PASS
235-
if num_improved == num_total
236-
else HealthcheckStatus.WARNING
237-
)
238-
239233
# Build subtitle
240234
subtitle = self._build_subtitle(
241235
num_improved=num_improved,
@@ -256,7 +250,7 @@ def compute(
256250
title="Baseline Improvement Healthcheck",
257251
subtitle=subtitle,
258252
df=pd.DataFrame(details),
259-
status=status,
253+
status=HealthcheckStatus.INFO,
260254
num_objectives_improved=num_improved,
261255
num_objectives_total=num_total,
262256
baseline_arm_name=baseline_arm_name,

ax/analysis/healthcheck/can_generate_candidates.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def compute(
7676
status = HealthcheckStatus.FAIL
7777
title_status = "Failure"
7878
else:
79-
status = HealthcheckStatus.WARNING
79+
status = HealthcheckStatus.INFO
8080
title_status = "Warning"
8181
subtitle += self.LAST_RUN_TEMPLATE.format(days=days_since_last_run)
8282
else:

ax/analysis/healthcheck/complexity_rating.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ def compute(
142142
if tier == "Standard":
143143
status = HealthcheckStatus.PASS
144144
elif tier == "Advanced":
145-
status = HealthcheckStatus.WARNING
145+
status = HealthcheckStatus.INFO
146146
else: # Unsupported
147-
status = HealthcheckStatus.FAIL
147+
status = HealthcheckStatus.WARNING
148148

149149
# Create dataframe with experiment summary
150150
df = pd.DataFrame(

ax/analysis/healthcheck/early_stopping_healthcheck.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def _report_early_stopping_disabled(
233233
"auto_early_stopping_config='standard' or configure an "
234234
"early_stopping_strategy_config."
235235
),
236-
status=HealthcheckStatus.PASS,
236+
status=HealthcheckStatus.INFO,
237237
df=df,
238238
)
239239

@@ -391,7 +391,7 @@ def _report_early_stopping_status(
391391
title=EARLY_STOPPING_SAVINGS_TITLE,
392392
subtitle=subtitle,
393393
df=df,
394-
status=HealthcheckStatus.PASS,
394+
status=HealthcheckStatus.INFO,
395395
)
396396

397397
def _report_early_stopping_nudge(
@@ -467,7 +467,7 @@ def _report_early_stopping_nudge(
467467
title=title,
468468
subtitle=subtitle,
469469
df=df,
470-
status=HealthcheckStatus.WARNING,
470+
status=HealthcheckStatus.INFO,
471471
potential_savings=savings_pct,
472472
best_metric=metric.name,
473473
)

ax/analysis/healthcheck/tests/test_baseline_improvement.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ def _attach_data(
6161
exp.attach_data(Data(df=pd.DataFrame(rows)))
6262

6363
def test_status_outcomes(self) -> None:
64-
"""Test PASS/WARNING status based on improvement."""
64+
"""Test INFO status for all improvement outcomes."""
6565
# minimize=True: lower is better
6666
test_cases = [
6767
# (baseline_mean, comparison_mean, expected_status, description)
68-
(100.0, 50.0, HealthcheckStatus.PASS, "improved (lower)"),
69-
(50.0, 100.0, HealthcheckStatus.WARNING, "not improved (higher)"),
68+
(100.0, 50.0, HealthcheckStatus.INFO, "improved (lower)"),
69+
(50.0, 100.0, HealthcheckStatus.INFO, "not improved (higher)"),
7070
]
7171

7272
for baseline_mean, comparison_mean, expected_status, desc in test_cases:
@@ -83,7 +83,7 @@ def test_status_outcomes(self) -> None:
8383
self.assertEqual(card.get_status(), expected_status)
8484

8585
def test_multi_objective_partial_improvement(self) -> None:
86-
"""Test WARNING status when only some objectives improve."""
86+
"""Test INFO status when only some objectives improve."""
8787
# minimize=True for both objectives (lower is better):
8888
# branin_a: 100 -> 50, improved (decreased)
8989
# branin_b: 50 -> 100, NOT improved (increased)
@@ -102,7 +102,7 @@ def test_multi_objective_partial_improvement(self) -> None:
102102
)
103103
card = analysis.compute(experiment=self.moo_experiment)
104104

105-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
105+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
106106
self.assertIn("1 out of 2", card.subtitle)
107107

108108
def test_documentation_link(self) -> None:
@@ -178,7 +178,7 @@ def test_dataframe_structure(self) -> None:
178178
self.assertEqual(len(card.df), 1)
179179

180180
def test_no_improvement_message_parameter(self) -> None:
181-
"""Test custom no_improvement_message is displayed on WARNING status."""
181+
"""Test custom no_improvement_message is displayed on INFO status."""
182182
self._attach_data(
183183
{"branin": [(50.0, 0.1), (100.0, 0.1)]}, arm_names=["0_0", "0_1"]
184184
)
@@ -192,5 +192,5 @@ def test_no_improvement_message_parameter(self) -> None:
192192
)
193193
card = analysis.compute(experiment=self.experiment)
194194

195-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
195+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
196196
self.assertIn(custom_message, card.subtitle)

ax/analysis/healthcheck/tests/test_can_generate_candidates.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ def test_warns_if_a_trial_was_recently_run(self) -> None:
5757
reason="The data is borked.",
5858
days_till_fail=2,
5959
).compute(experiment=experiment, generation_strategy=None)
60-
# THEN it is a WARNING
61-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
60+
# THEN it is INFO
61+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
6262
self.assertEqual(card.name, "CanGenerateCandidatesAnalysis")
6363
self.assertEqual(card.title, "Ax Candidate Generation Warning")
6464
self.assertEqual(
@@ -71,11 +71,11 @@ def test_warns_if_a_trial_was_recently_run(self) -> None:
7171
"LAST TRIAL RUN: 1 day(s) ago"
7272
),
7373
)
74-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
74+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
7575
self.assertDictEqual(
7676
card.get_aditional_attrs(),
7777
{
78-
"status": HealthcheckStatus.WARNING,
78+
"status": HealthcheckStatus.INFO,
7979
"reason": "The data is borked.",
8080
},
8181
)

ax/analysis/healthcheck/tests/test_complexity_rating.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def test_standard_configuration(self) -> None:
6565

6666
def test_parameter_counts(self) -> None:
6767
test_cases = [
68-
(60, HealthcheckStatus.WARNING, "Advanced", "60 tunable parameter(s)"),
69-
(250, HealthcheckStatus.FAIL, "Unsupported", "250 tunable parameter(s)"),
68+
(60, HealthcheckStatus.INFO, "Advanced", "60 tunable parameter(s)"),
69+
(250, HealthcheckStatus.WARNING, "Unsupported", "250 tunable parameter(s)"),
7070
]
7171

7272
for num_params, expected_status, expected_tier, expected_msg in test_cases:
@@ -92,8 +92,8 @@ def test_parameter_counts(self) -> None:
9292

9393
def test_objectives_count(self) -> None:
9494
test_cases = [
95-
(3, HealthcheckStatus.WARNING, "Advanced", "3 objectives"),
96-
(5, HealthcheckStatus.FAIL, "Unsupported", "5 objectives"),
95+
(3, HealthcheckStatus.INFO, "Advanced", "3 objectives"),
96+
(5, HealthcheckStatus.WARNING, "Unsupported", "5 objectives"),
9797
]
9898

9999
for num_objs, expected_status, expected_tier, expected_msg in test_cases:
@@ -128,7 +128,7 @@ def test_constraints(self) -> None:
128128
options=self.options, tier_metadata=self.tier_metadata
129129
).compute(experiment=self.experiment)
130130

131-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
131+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
132132
self.assertIn("Advanced", card.subtitle)
133133
self.assertIn("3 outcome constraints", card.subtitle)
134134

@@ -152,7 +152,7 @@ def test_constraints(self) -> None:
152152
options=self.options, tier_metadata=self.tier_metadata
153153
).compute(experiment=self.experiment)
154154

155-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
155+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
156156
self.assertIn("Advanced", card.subtitle)
157157
self.assertIn("3 parameter constraints", card.subtitle)
158158

@@ -174,14 +174,14 @@ def test_stopping_strategies(self) -> None:
174174
options=options, tier_metadata=self.tier_metadata
175175
).compute(experiment=self.experiment)
176176

177-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
177+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
178178
self.assertIn("Advanced", card.subtitle)
179179
self.assertIn(expected_msg, card.subtitle)
180180

181181
def test_trial_counts(self) -> None:
182182
test_cases = [
183-
(300, HealthcheckStatus.WARNING, "Advanced", "300 total trials"),
184-
(600, HealthcheckStatus.FAIL, "Unsupported", "600 total trials"),
183+
(300, HealthcheckStatus.INFO, "Advanced", "300 total trials"),
184+
(600, HealthcheckStatus.WARNING, "Unsupported", "600 total trials"),
185185
]
186186

187187
for max_trials, expected_status, expected_tier, expected_msg in test_cases:
@@ -229,7 +229,7 @@ def test_unsupported_configurations(self) -> None:
229229
options=options, tier_metadata=tier_metadata
230230
).compute(experiment=self.experiment)
231231

232-
self.assertEqual(card.get_status(), HealthcheckStatus.FAIL)
232+
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
233233
self.assertIn("Unsupported", card.subtitle)
234234
self.assertIn(expected_msg, card.subtitle)
235235

@@ -253,7 +253,7 @@ def test_unordered_choice_parameters(self) -> None:
253253
options=self.options, tier_metadata=self.tier_metadata
254254
).compute(experiment=self.experiment)
255255

256-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
256+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
257257
self.assertIn("Advanced", card.subtitle)
258258
self.assertIn("unordered choice parameter(s)", card.subtitle)
259259

@@ -275,7 +275,7 @@ def test_binary_parameters_count(self) -> None:
275275
options=self.options, tier_metadata=self.tier_metadata
276276
).compute(experiment=self.experiment)
277277

278-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
278+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
279279
self.assertIn("Advanced", card.subtitle)
280280
self.assertIn("60 binary tunable parameter(s)", card.subtitle)
281281

@@ -298,7 +298,7 @@ def test_multiple_violations(self) -> None:
298298
options=options, tier_metadata=tier_metadata
299299
).compute(experiment=experiment)
300300

301-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
301+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
302302
self.assertIn("Advanced", card.subtitle)
303303
self.assertIn("60 tunable parameter(s)", card.subtitle)
304304
self.assertIn("300 total trials", card.subtitle)

ax/analysis/healthcheck/tests/test_early_stopping_healthcheck.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def test_early_stopping_not_enabled(self) -> None:
177177
return_value=mock_savings,
178178
):
179179
card = healthcheck.compute(experiment=self.experiment)
180-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
180+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
181181
self.assertIn("25%", card.subtitle)
182182

183183
def test_validate_applicable_state(self) -> None:
@@ -261,15 +261,15 @@ def test_auto_early_stopping_config(self) -> None:
261261
healthcheck = EarlyStoppingAnalysis(auto_early_stopping_config="disabled")
262262
card = healthcheck.compute(experiment=self.experiment)
263263

264-
self.assertEqual(card.get_status(), HealthcheckStatus.PASS)
264+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
265265
self.assertIn("auto_early_stopping_config='disabled'", card.subtitle)
266266

267267
with self.subTest("standard"):
268268
self._mark_trial_completed()
269269
healthcheck = EarlyStoppingAnalysis(auto_early_stopping_config="standard")
270270
card = healthcheck.compute(experiment=self.experiment)
271271

272-
self.assertEqual(card.get_status(), HealthcheckStatus.PASS)
272+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
273273
self.assertIn("0 trials were early stopped", card.subtitle)
274274

275275
with self.subTest("strategy_override"):
@@ -280,7 +280,7 @@ def test_auto_early_stopping_config(self) -> None:
280280
)
281281
card = healthcheck.compute(experiment=self.experiment)
282282

283-
self.assertEqual(card.get_status(), HealthcheckStatus.PASS)
283+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
284284
self.assertEqual(healthcheck.early_stopping_strategy, custom_strategy)
285285

286286
def test_multiple_metrics_note_in_subtitle(self) -> None:
@@ -294,7 +294,7 @@ def test_multiple_metrics_note_in_subtitle(self) -> None:
294294
):
295295
card = self.healthcheck.compute(experiment=self.experiment)
296296

297-
self.assertEqual(card.get_status(), HealthcheckStatus.PASS)
297+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
298298
self.assertIn("2 metrics are", card.subtitle)
299299

300300
def test_get_problem_type_via_disabled_config(self) -> None:
@@ -355,7 +355,7 @@ def test_hypothetical_savings_nudge(self) -> None:
355355
):
356356
card = healthcheck.compute(experiment=self.experiment)
357357

358-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
358+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
359359
self.assertIn("25%", card.subtitle)
360360

361361
with self.subTest("with_additional_info"):
@@ -375,5 +375,5 @@ def test_hypothetical_savings_nudge(self) -> None:
375375
):
376376
card = healthcheck_with_info.compute(experiment=self.experiment)
377377

378-
self.assertEqual(card.get_status(), HealthcheckStatus.WARNING)
378+
self.assertEqual(card.get_status(), HealthcheckStatus.INFO)
379379
self.assertIn(nudge_info, card.subtitle)

0 commit comments

Comments
 (0)