FAILURE MAP
← Case archive

FA-83966 / Sports scoring and tiebreakers / Open access

All-out innings counted at actual overs · case 01

A side bowled out early is credited with a very high run rate instead of the full quota.

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

ROOT CAUSE

The actual overs faced are used even when the side was all out.

VERIFIED REPAIR

Charge the full quota for any all-out innings on both the batting and bowling side.

Unsuccessful approach: Applying the quota only to overs faced leaves bowled-out opponents at their actual overs.

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 = balls(faced)
        g = 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: all out quota',
   ([[274, '11.3', False, 153, '36', False],
     [141, '9.4', True, 86, '41.3', True],
     [108, '15', False, 280, '44.5', False]],
    20),
   '+6.100'),
  ('variant scenario 1',
   ([[341, '0.5', False, 330, '45.0', False],
     [313, '19.5', False, 220, '25.3', False],
     [207, '42.1', False, 200, '3.1', False]],
    20),
   '+3.522'),
  ('variant scenario 2',
   ([[222, '5.1', False, 252, '48.1', True],
     [92, '24.4', False, 265, '23.3', True],
     [276, '32.3', False, 297, '6.2', False]],
    20),
   '-8.103')],
 [('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: all out quota',
   ([[323, '8.5', False, 245, '5', True],
     [198, '15.3', False, 151, '15.4', False],
     [239, '14.2', False, 121, '24.6', True],
     [107, '14', True, 94, '39.3', False]],
    50),
   '+5.840'),
  ('variant scenario 1',
   ([[271, '12.2', False, 108, '19.3', False], [129, '15.7', False, 146, '44.4', False]], 50),
   'invalid overs'),
  ('variant scenario 2',
   ([[260, '42.3', False, 116, '50.2', False],
     [339, '31.5', False, 320, '34.1', False],
     [360, '12.5', False, 211, '37.1', False]],
    50),
   '+5.684')],
 [('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: all out quota',
   ([[85, '18.2', True, 137, '19.4', False], [211, '33.3', True, 84, '44.5', True]], 50),
   '-0.212'),
  ('variant scenario 1',
   ([[122, '18.3', True, 178, '35.4', False],
     [155, '37.3', False, 116, '4.5', False],
     [134, '45.5', False, 248, '27.4', False]],
    20),
   '-3.974'),
  ('variant scenario 2',
   ([[353, '23.3', False, 353, '24.4', True],
     [233, '49.3', False, 281, '18.3', False],
     [245, '44.4', False, 260, '4.1', True],
     [278, '44', False, 291, '10.5', True],
     [222, '27.6', False, 153, '44', True]],
    50),
   'invalid overs')],
 [('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: all out quota',
   ([[294, '24.2', False, 86, '24.2', True],
     [111, '30', False, 139, '26.2', True],
     [139, '8.1', True, 316, '35.4', False],
     [115, '35.3', False, 329, '28.5', False],
     [171, '34.5', True, 227, '49.2', False]],
    50),
   '-0.758'),
  ('variant scenario 1', ([[0, '0', False, 0, '0', False]], 50), 'no overs'),
  ('variant scenario 2', ([[345, '2.1', True, 354, '26.5', False]], 20), '+4.057')],
 [('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: all out quota',
   ([[225, '40.5', False, 354, '9.1', True],
     [167, '22.1', False, 231, '34', False],
     [297, '26.0', False, 98, '19', False],
     [295, '49.2', False, 314, '45.4', False],
     [293, '46.3', False, 305, '29.1', True]],
    50),
   '+0.355'),
  ('variant scenario 1',
   ([[183, '19.5', False, 137, '36.6', False],
     [234, '46.4', False, 179, '46.4', False],
     [173, '24.1', False, 110, '31.6', False],
     [287, '24.0', True, 147, '37.1', True]],
    50),
   'invalid overs'),
  ('variant scenario 2',
   ([[172, '22.1', False, 287, '1.6', False],
     [352, '8', False, 332, '17.0', False],
     [126, '0.4', False, 127, '43.3', True]],
    20),
   'invalid overs')]]
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+1.166-0.661Failed
boundary invalid ball digitinvalid oversinvalid oversPassed
control no oversno oversno oversPassed
control negative rate-3.000-3.000Passed
regression: all out quota+10.218+6.100Failed
variant scenario 1+3.522+3.522Passed
variant scenario 2-0.971-8.103Failed

SHA-256 / de4cdb3d6c00e3ca9347d129f3cef21503ffdb488547617f7cee922cd274d6c6

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 = 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: all out quota',
   ([[274, '11.3', False, 153, '36', False],
     [141, '9.4', True, 86, '41.3', True],
     [108, '15', False, 280, '44.5', False]],
    20),
   '+6.100'),
  ('variant scenario 1',
   ([[341, '0.5', False, 330, '45.0', False],
     [313, '19.5', False, 220, '25.3', False],
     [207, '42.1', False, 200, '3.1', False]],
    20),
   '+3.522'),
  ('variant scenario 2',
   ([[222, '5.1', False, 252, '48.1', True],
     [92, '24.4', False, 265, '23.3', True],
     [276, '32.3', False, 297, '6.2', False]],
    20),
   '-8.103')],
 [('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: all out quota',
   ([[323, '8.5', False, 245, '5', True],
     [198, '15.3', False, 151, '15.4', False],
     [239, '14.2', False, 121, '24.6', True],
     [107, '14', True, 94, '39.3', False]],
    50),
   '+5.840'),
  ('variant scenario 1',
   ([[271, '12.2', False, 108, '19.3', False], [129, '15.7', False, 146, '44.4', False]], 50),
   'invalid overs'),
  ('variant scenario 2',
   ([[260, '42.3', False, 116, '50.2', False],
     [339, '31.5', False, 320, '34.1', False],
     [360, '12.5', False, 211, '37.1', False]],
    50),
   '+5.684')],
 [('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: all out quota',
   ([[85, '18.2', True, 137, '19.4', False], [211, '33.3', True, 84, '44.5', True]], 50),
   '-0.212'),
  ('variant scenario 1',
   ([[122, '18.3', True, 178, '35.4', False],
     [155, '37.3', False, 116, '4.5', False],
     [134, '45.5', False, 248, '27.4', False]],
    20),
   '-3.974'),
  ('variant scenario 2',
   ([[353, '23.3', False, 353, '24.4', True],
     [233, '49.3', False, 281, '18.3', False],
     [245, '44.4', False, 260, '4.1', True],
     [278, '44', False, 291, '10.5', True],
     [222, '27.6', False, 153, '44', True]],
    50),
   'invalid overs')],
 [('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: all out quota',
   ([[294, '24.2', False, 86, '24.2', True],
     [111, '30', False, 139, '26.2', True],
     [139, '8.1', True, 316, '35.4', False],
     [115, '35.3', False, 329, '28.5', False],
     [171, '34.5', True, 227, '49.2', False]],
    50),
   '-0.758'),
  ('variant scenario 1', ([[0, '0', False, 0, '0', False]], 50), 'no overs'),
  ('variant scenario 2', ([[345, '2.1', True, 354, '26.5', False]], 20), '+4.057')],
 [('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: all out quota',
   ([[225, '40.5', False, 354, '9.1', True],
     [167, '22.1', False, 231, '34', False],
     [297, '26.0', False, 98, '19', False],
     [295, '49.2', False, 314, '45.4', False],
     [293, '46.3', False, 305, '29.1', True]],
    50),
   '+0.355'),
  ('variant scenario 1',
   ([[183, '19.5', False, 137, '36.6', False],
     [234, '46.4', False, 179, '46.4', False],
     [173, '24.1', False, 110, '31.6', False],
     [287, '24.0', True, 147, '37.1', True]],
    50),
   'invalid overs'),
  ('variant scenario 2',
   ([[172, '22.1', False, 287, '1.6', False],
     [352, '8', False, 332, '17.0', False],
     [126, '0.4', False, 127, '43.3', True]],
    20),
   'invalid overs')]]
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: all out quota+7.005+6.100Failed
variant scenario 1+3.522+3.522Passed
variant scenario 2-0.971-8.103Failed

SHA-256 / e455aa67fb1f405c177b00576ecd4c5fe69ae4004d75b3a4d78d1f1f106c8c83

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: all out quota',
   ([[274, '11.3', False, 153, '36', False],
     [141, '9.4', True, 86, '41.3', True],
     [108, '15', False, 280, '44.5', False]],
    20),
   '+6.100'),
  ('variant scenario 1',
   ([[341, '0.5', False, 330, '45.0', False],
     [313, '19.5', False, 220, '25.3', False],
     [207, '42.1', False, 200, '3.1', False]],
    20),
   '+3.522'),
  ('variant scenario 2',
   ([[222, '5.1', False, 252, '48.1', True],
     [92, '24.4', False, 265, '23.3', True],
     [276, '32.3', False, 297, '6.2', False]],
    20),
   '-8.103')],
 [('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: all out quota',
   ([[323, '8.5', False, 245, '5', True],
     [198, '15.3', False, 151, '15.4', False],
     [239, '14.2', False, 121, '24.6', True],
     [107, '14', True, 94, '39.3', False]],
    50),
   '+5.840'),
  ('variant scenario 1',
   ([[271, '12.2', False, 108, '19.3', False], [129, '15.7', False, 146, '44.4', False]], 50),
   'invalid overs'),
  ('variant scenario 2',
   ([[260, '42.3', False, 116, '50.2', False],
     [339, '31.5', False, 320, '34.1', False],
     [360, '12.5', False, 211, '37.1', False]],
    50),
   '+5.684')],
 [('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: all out quota',
   ([[85, '18.2', True, 137, '19.4', False], [211, '33.3', True, 84, '44.5', True]], 50),
   '-0.212'),
  ('variant scenario 1',
   ([[122, '18.3', True, 178, '35.4', False],
     [155, '37.3', False, 116, '4.5', False],
     [134, '45.5', False, 248, '27.4', False]],
    20),
   '-3.974'),
  ('variant scenario 2',
   ([[353, '23.3', False, 353, '24.4', True],
     [233, '49.3', False, 281, '18.3', False],
     [245, '44.4', False, 260, '4.1', True],
     [278, '44', False, 291, '10.5', True],
     [222, '27.6', False, 153, '44', True]],
    50),
   'invalid overs')],
 [('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: all out quota',
   ([[294, '24.2', False, 86, '24.2', True],
     [111, '30', False, 139, '26.2', True],
     [139, '8.1', True, 316, '35.4', False],
     [115, '35.3', False, 329, '28.5', False],
     [171, '34.5', True, 227, '49.2', False]],
    50),
   '-0.758'),
  ('variant scenario 1', ([[0, '0', False, 0, '0', False]], 50), 'no overs'),
  ('variant scenario 2', ([[345, '2.1', True, 354, '26.5', False]], 20), '+4.057')],
 [('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: all out quota',
   ([[225, '40.5', False, 354, '9.1', True],
     [167, '22.1', False, 231, '34', False],
     [297, '26.0', False, 98, '19', False],
     [295, '49.2', False, 314, '45.4', False],
     [293, '46.3', False, 305, '29.1', True]],
    50),
   '+0.355'),
  ('variant scenario 1',
   ([[183, '19.5', False, 137, '36.6', False],
     [234, '46.4', False, 179, '46.4', False],
     [173, '24.1', False, 110, '31.6', False],
     [287, '24.0', True, 147, '37.1', True]],
    50),
   'invalid overs'),
  ('variant scenario 2',
   ([[172, '22.1', False, 287, '1.6', False],
     [352, '8', False, 332, '17.0', False],
     [126, '0.4', False, 127, '43.3', True]],
    20),
   'invalid overs')]]
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: all out quota+6.100+6.100Passed
variant scenario 1+3.522+3.522Passed
variant scenario 2-8.103-8.103Passed

SHA-256 / 7bfcda7c93a407964f30ac50422b70cbd4b5eac41242d9712787cfc52efa888b

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.516041+00:00.

Case digest / 901a50c75afe98cf519b878134935082d351ab76889467d28df9b93bfe3ab4f3