Given baseline and candidate metrics by slice, return whether the
candidate can promote. Each threshold declares whether lower or
higher is better so latency/error metrics and recall/success metrics
are judged in the right direction.
Hidden answer: invariant, edge cases, and Python solution
Invariant: every required slice and metric must pass. Missing
candidate metrics are failures because a release gate cannot assume
safety. Test missing slices, missing metrics, exact threshold,
improvements, a lower-is-better regression, and a higher-is-better
regression.
def can_promote(baseline, candidate, thresholds):
failures = []
for slice_name, base_metrics in baseline.items():
cand_metrics = candidate.get(slice_name)
if cand_metrics is None:
failures.append((slice_name, "missing_slice", None))
continue
for metric, base_value in base_metrics.items():
if metric not in thresholds:
continue
cand_value = cand_metrics.get(metric)
if cand_value is None:
failures.append((slice_name, metric, "missing_metric"))
continue
direction = thresholds[metric]["direction"]
allowed = thresholds[metric]["allowed_regression"]
if direction == "lower_is_better":
regression = cand_value - base_value
elif direction == "higher_is_better":
regression = base_value - cand_value
else:
raise ValueError(f"unknown direction for {metric}: {direction}")
if regression - allowed > 1e-12:
failures.append((slice_name, metric, regression))
return {
"promote": not failures,
"failures": failures,
}