FAILURE MAP
← Case archive

FA-83981 / Sports scoring and tiebreakers / Open access

Zero-overs guard checks the wrong totals · case 01

A table with no completed deliveries raises or reports a bogus rate.

Verified by executionVariant 1 · 10 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The guard requires both overs totals to be zero before bailing out.

VERIFIED REPAIR

Return "no overs" when either overs total is zero.

Unsuccessful approach: Guarding on zero runs instead of zero balls rejects legitimate low-scoring matches.

Case contract

Tournament net run rate. Each match row is [runs_for, overs_faced, all_out_for, runs_against, overs_bowled, all_out_against]. Overs strings use cricket notation "O.B" where B is balls 0-5 ("43.4" = 43 overs 4 balls); a ball digit above 5 returns "invalid overs". When a side was all out its innings counts as the full quota of overs. NRR = total runs for / total overs faced - total runs against / total overs bowled, aggregated over all matches before dividing, formatted as "%+.3f" of the exact value. If either overs total is zero return "no overs".

Why this case matters

Group-stage standings use net run rate as the first tiebreaker after points.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(matches, quota):
    def balls(text):
        whole, _, part = text.partition('.')
        part = int(part or 0)
        if part > 5:
            return None
        return int(whole) * 6 + part
    rf = bf = ra = ba = 0
    for runs_for, faced, out_for, runs_against, bowled, out_against in matches:
        f = quota * 6 if out_for else balls(faced)
        g = quota * 6 if out_against else balls(bowled)
        if f is None or g is None:
            return 'invalid overs'
        rf += runs_for
        bf += f
        ra += runs_against
        ba += g
    if bf == 0 and ba == 0:
        return 'no overs'
    value = Fraction(rf * 6, bf) - Fraction(ra * 6, ba)
    return '%+.3f' % float(value)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[112, '37.4', False, 359, '0.0', False]], 20), 'no overs'),
  ('variant scenario 1',
   ([[97, '37.1', True, 113, '12.3', True], [243, '29.4', False, 120, '28', False]], 20),
   '+1.991'),
  ('variant scenario 2',
   ([[141, '47.4', True, 121, '13.2', True],
     [241, '15.2', False, 312, '40.3', False],
     [303, '1.2', False, 251, '21.3', False]],
    20),
   '+10.340')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[0, '5', False, 30, '5', False]], 20), '-6.000'),
  ('variant scenario 1',
   ([[100, '17.2', False, 124, '24.2', False],
     [116, '23.2', False, 183, '47.4', False],
     [276, '50.4', True, 337, '28.2', False],
     [117, '29.3', False, 123, '27.2', False]],
    20),
   '+0.746'),
  ('variant scenario 2',
   ([[273, '50.3', False, 339, '0.0', False],
     [266, '31.2', False, 139, '40.2', False],
     [108, '1.2', False, 177, '39.2', True],
     [94, '37.2', True, 161, '7.3', False]],
    20),
   '-4.847')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[132, '6.3', False, 302, '0.0', False]], 20), 'no overs'),
  ('variant scenario 1', ([[118, '30.0', True, 121, '46.5', False]], 50), '-0.224'),
  ('variant scenario 2',
   ([[133, '6.4', False, 152, '24.4', True],
     [348, '27.2', False, 234, '38.4', True],
     [289, '22.1', False, 331, '45', False],
     [122, '44.3', False, 126, '23.1', False],
     [240, '11', False, 199, '17.3', False]],
    20),
   '+1.846')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[0, '5', False, 30, '5', False]], 20), '-6.000'),
  ('variant scenario 1',
   ([[133, '4.1', True, 163, '15.4', True],
     [347, '15.6', False, 137, '28.2', False],
     [106, '0.1', False, 162, '0.2', False],
     [128, '7.4', False, 81, '20.5', False],
     [83, '36.2', False, 189, '21.5', False]],
    20),
   'invalid overs'),
  ('variant scenario 2', ([[177, '43.5', True, 267, '47.4', False]], 20), '+3.249')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[360, '25.4', False, 360, '0.0', False]], 50), 'no overs'),
  ('variant scenario 1',
   ([[118, '12.2', True, 179, '28.0', False],
     [298, '13.1', False, 285, '42.1', False],
     [181, '50.3', False, 90, '32.3', False]],
    50),
   '-0.144'),
  ('variant scenario 2',
   ([[338, '28.5', False, 263, '35.1', True],
     [150, '13.0', False, 270, '26.2', True],
     [223, '14.2', False, 327, '30.2', True],
     [299, '0.2', False, 155, '50.4', False],
     [293, '8.4', False, 283, '0.5', False],
     [176, '41', False, 100, '11.3', False],
     [341, '40', False, 314, '34.0', False]],
    50),
   '+5.520')]]
for label, args, expected in cases[N - 1]:
    check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
control single match+1.000+1.000Passed
boundary partial over+1.317+1.317Passed
boundary all out uses quota-0.661-0.661Passed
boundary invalid ball digitinvalid oversinvalid oversPassed
control no oversno oversno oversPassed
control negative rate-3.000-3.000Passed
regression: zero overs guardraised ZeroDivisionErrorno oversFailed
regression: zero overs guardraised ZeroDivisionErrorno oversFailed
variant scenario 1+1.991+1.991Passed
variant scenario 2+10.340+10.340Passed

SHA-256 / 5868632e0f97b7cc23d792528fc2197ff8b473d5b45bc7811461c64845c2b69c

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(matches, quota):
    def balls(text):
        whole, _, part = text.partition('.')
        part = int(part or 0)
        if part > 5:
            return None
        return int(whole) * 6 + part
    rf = bf = ra = ba = 0
    for runs_for, faced, out_for, runs_against, bowled, out_against in matches:
        f = quota * 6 if out_for else balls(faced)
        g = quota * 6 if out_against else balls(bowled)
        if f is None or g is None:
            return 'invalid overs'
        rf += runs_for
        bf += f
        ra += runs_against
        ba += g
    if rf == 0 or ra == 0:
        return 'no overs'
    value = Fraction(rf * 6, bf) - Fraction(ra * 6, ba)
    return '%+.3f' % float(value)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[112, '37.4', False, 359, '0.0', False]], 20), 'no overs'),
  ('variant scenario 1',
   ([[97, '37.1', True, 113, '12.3', True], [243, '29.4', False, 120, '28', False]], 20),
   '+1.991'),
  ('variant scenario 2',
   ([[141, '47.4', True, 121, '13.2', True],
     [241, '15.2', False, 312, '40.3', False],
     [303, '1.2', False, 251, '21.3', False]],
    20),
   '+10.340')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[0, '5', False, 30, '5', False]], 20), '-6.000'),
  ('variant scenario 1',
   ([[100, '17.2', False, 124, '24.2', False],
     [116, '23.2', False, 183, '47.4', False],
     [276, '50.4', True, 337, '28.2', False],
     [117, '29.3', False, 123, '27.2', False]],
    20),
   '+0.746'),
  ('variant scenario 2',
   ([[273, '50.3', False, 339, '0.0', False],
     [266, '31.2', False, 139, '40.2', False],
     [108, '1.2', False, 177, '39.2', True],
     [94, '37.2', True, 161, '7.3', False]],
    20),
   '-4.847')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[132, '6.3', False, 302, '0.0', False]], 20), 'no overs'),
  ('variant scenario 1', ([[118, '30.0', True, 121, '46.5', False]], 50), '-0.224'),
  ('variant scenario 2',
   ([[133, '6.4', False, 152, '24.4', True],
     [348, '27.2', False, 234, '38.4', True],
     [289, '22.1', False, 331, '45', False],
     [122, '44.3', False, 126, '23.1', False],
     [240, '11', False, 199, '17.3', False]],
    20),
   '+1.846')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[0, '5', False, 30, '5', False]], 20), '-6.000'),
  ('variant scenario 1',
   ([[133, '4.1', True, 163, '15.4', True],
     [347, '15.6', False, 137, '28.2', False],
     [106, '0.1', False, 162, '0.2', False],
     [128, '7.4', False, 81, '20.5', False],
     [83, '36.2', False, 189, '21.5', False]],
    20),
   'invalid overs'),
  ('variant scenario 2', ([[177, '43.5', True, 267, '47.4', False]], 20), '+3.249')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[360, '25.4', False, 360, '0.0', False]], 50), 'no overs'),
  ('variant scenario 1',
   ([[118, '12.2', True, 179, '28.0', False],
     [298, '13.1', False, 285, '42.1', False],
     [181, '50.3', False, 90, '32.3', False]],
    50),
   '-0.144'),
  ('variant scenario 2',
   ([[338, '28.5', False, 263, '35.1', True],
     [150, '13.0', False, 270, '26.2', True],
     [223, '14.2', False, 327, '30.2', True],
     [299, '0.2', False, 155, '50.4', False],
     [293, '8.4', False, 283, '0.5', False],
     [176, '41', False, 100, '11.3', False],
     [341, '40', False, 314, '34.0', False]],
    50),
   '+5.520')]]
for label, args, expected in cases[N - 1]:
    check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
control single match+1.000+1.000Passed
boundary partial over+1.317+1.317Passed
boundary all out uses quota-0.661-0.661Passed
boundary invalid ball digitinvalid oversinvalid oversPassed
control no oversno oversno oversPassed
control negative rate-3.000-3.000Passed
regression: zero overs guardno oversno oversPassed
regression: zero overs guardraised ZeroDivisionErrorno oversFailed
variant scenario 1+1.991+1.991Passed
variant scenario 2+10.340+10.340Passed

SHA-256 / 101ede9fe5ee5ca10720ed93e7b4d23e86da542236908f21d1e77cfd9686e6a6

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(matches, quota):
    def balls(text):
        whole, _, part = text.partition('.')
        part = int(part or 0)
        if part > 5:
            return None
        return int(whole) * 6 + part
    rf = bf = ra = ba = 0
    for runs_for, faced, out_for, runs_against, bowled, out_against in matches:
        f = quota * 6 if out_for else balls(faced)
        g = quota * 6 if out_against else balls(bowled)
        if f is None or g is None:
            return 'invalid overs'
        rf += runs_for
        bf += f
        ra += runs_against
        ba += g
    if bf == 0 or ba == 0:
        return 'no overs'
    value = Fraction(rf * 6, bf) - Fraction(ra * 6, ba)
    return '%+.3f' % float(value)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[112, '37.4', False, 359, '0.0', False]], 20), 'no overs'),
  ('variant scenario 1',
   ([[97, '37.1', True, 113, '12.3', True], [243, '29.4', False, 120, '28', False]], 20),
   '+1.991'),
  ('variant scenario 2',
   ([[141, '47.4', True, 121, '13.2', True],
     [241, '15.2', False, 312, '40.3', False],
     [303, '1.2', False, 251, '21.3', False]],
    20),
   '+10.340')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[0, '5', False, 30, '5', False]], 20), '-6.000'),
  ('variant scenario 1',
   ([[100, '17.2', False, 124, '24.2', False],
     [116, '23.2', False, 183, '47.4', False],
     [276, '50.4', True, 337, '28.2', False],
     [117, '29.3', False, 123, '27.2', False]],
    20),
   '+0.746'),
  ('variant scenario 2',
   ([[273, '50.3', False, 339, '0.0', False],
     [266, '31.2', False, 139, '40.2', False],
     [108, '1.2', False, 177, '39.2', True],
     [94, '37.2', True, 161, '7.3', False]],
    20),
   '-4.847')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[132, '6.3', False, 302, '0.0', False]], 20), 'no overs'),
  ('variant scenario 1', ([[118, '30.0', True, 121, '46.5', False]], 50), '-0.224'),
  ('variant scenario 2',
   ([[133, '6.4', False, 152, '24.4', True],
     [348, '27.2', False, 234, '38.4', True],
     [289, '22.1', False, 331, '45', False],
     [122, '44.3', False, 126, '23.1', False],
     [240, '11', False, 199, '17.3', False]],
    20),
   '+1.846')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[0, '0', False, 50, '10', False]], 20), 'no overs'),
  ('regression: zero overs guard', ([[0, '5', False, 30, '5', False]], 20), '-6.000'),
  ('variant scenario 1',
   ([[133, '4.1', True, 163, '15.4', True],
     [347, '15.6', False, 137, '28.2', False],
     [106, '0.1', False, 162, '0.2', False],
     [128, '7.4', False, 81, '20.5', False],
     [83, '36.2', False, 189, '21.5', False]],
    20),
   'invalid overs'),
  ('variant scenario 2', ([[177, '43.5', True, 267, '47.4', False]], 20), '+3.249')],
 [('control single match', ([[300, '50', False, 250, '50', False]], 50), '+1.000'),
  ('boundary partial over', ([[150, '20.3', False, 150, '25', False]], 50), '+1.317'),
  ('boundary all out uses quota', ([[120, '15.2', True, 121, '18.1', False]], 20), '-0.661'),
  ('boundary invalid ball digit', ([[100, '10.6', False, 90, '10', False]], 20), 'invalid overs'),
  ('control no overs', ([[0, '0', False, 0, '0', False]], 20), 'no overs'),
  ('control negative rate', ([[100, '20', False, 160, '20', False]], 20), '-3.000'),
  ('regression: zero overs guard', ([[360, '25.4', False, 360, '0.0', False]], 50), 'no overs'),
  ('variant scenario 1',
   ([[118, '12.2', True, 179, '28.0', False],
     [298, '13.1', False, 285, '42.1', False],
     [181, '50.3', False, 90, '32.3', False]],
    50),
   '-0.144'),
  ('variant scenario 2',
   ([[338, '28.5', False, 263, '35.1', True],
     [150, '13.0', False, 270, '26.2', True],
     [223, '14.2', False, 327, '30.2', True],
     [299, '0.2', False, 155, '50.4', False],
     [293, '8.4', False, 283, '0.5', False],
     [176, '41', False, 100, '11.3', False],
     [341, '40', False, 314, '34.0', False]],
    50),
   '+5.520')]]
for label, args, expected in cases[N - 1]:
    check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
control single match+1.000+1.000Passed
boundary partial over+1.317+1.317Passed
boundary all out uses quota-0.661-0.661Passed
boundary invalid ball digitinvalid oversinvalid oversPassed
control no oversno oversno oversPassed
control negative rate-3.000-3.000Passed
regression: zero overs guardno oversno oversPassed
regression: zero overs guardno oversno oversPassed
variant scenario 1+1.991+1.991Passed
variant scenario 2+10.340+10.340Passed

SHA-256 / 4510de7befa144f895e43bb2196b1310f2e6163ee19beb4f26556d217d78d51c

Verification & scope

Stipulated, bounded toy contract stated in the contract field; not a claim of conformance with any governing body rulebook or operator house rules. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:26.557206+00:00.

Case digest / a07e42f5665b2c457792d211e8599231c675e9b47662a6064e56ba32a4ad3b90