FAILURE MAP
← Case archive

FA-83931 / Sports scoring and tiebreakers / Open access

Badminton game runs past the 30-point cap · case 01

At 29-29 the next rally does not end the game.

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

ROOT CAUSE

The completion test omits the 30-point cap.

VERIFIED REPAIR

Also end the game when either player reaches 30.

Unsuccessful approach: Ending the game at 29 points closes a 29-28 game that must continue.

Case contract

One badminton singles game. rallies is a string of rally winners (A/B). A game is won at 21 points with a two-point lead, or by the first player to 30 points (29-29 next point wins). The rally winner serves next. The server serves from the right court when the server's own score is even and from the left court when odd. Return [a, b, winner, None, None] when finished (later rallies ignored) or [a, b, None, next server, "right"/"left"].

Why this case matters

Umpire scoring pads show the service court and server after each rally.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(rallies, first_server):
    a = b = 0
    server = first_server
    for r in rallies:
        if r == 'A':
            a += 1
        else:
            b += 1
        server = r
        if (max(a, b) >= 21 and abs(a - b) >= 2):
            return [a, b, r, None, None]
    own = a if server == 'A' else b
    return [a, b, None, server, 'right' if own % 2 == 0 else 'left']
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 opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [28, 29, None, 'B', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1', ('BABBBABBABBBABBABBABAABABBBBBBABBBB', 'B'), [9, 21, 'B', None, None]),
  ('variant scenario 2', ('BBABAABABABBBBBAAABBABBBABBA', 'A'), [11, 17, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'A'),
   [29, 28, None, 'A', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'A'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('BAAABBBABABBABBABAAAAABBBBABAABBBBABBBBABBABBABA', 'B'),
   [16, 21, 'B', None, None]),
  ('variant scenario 2', ('BBAABABAAABBBB', 'A'), [6, 8, None, 'B', 'right'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'A'),
   [29, 28, None, 'A', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'B'),
   [29, 30, 'B', None, None]),
  ('variant scenario 1', ('BBAABAAA', 'A'), [5, 3, None, 'A', 'left']),
  ('variant scenario 2', ('BAABABBAAAAABBAABABABBBBBABAA', 'A'), [15, 14, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABAAB', 'B'),
   [30, 28, 'A', None, None]),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('ABABABABBBABBABBBAAAAAABABABAABAABBABAAABAAAAABABBBBABAAAABBABABB', 'A'),
   [21, 18, 'A', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [21, 20, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('AAAAABBBAAABBBAAAABBBBABBBBABABBBBAABBBBABBBABBBBAAABBBBABABBAAABAABABAABBBABB', 'A'),
   [17, 21, 'B', None, None]),
  ('variant scenario 2',
   ('BAABABBAABABABBBABABBABBABBABBBBBAABABBBBBBABBABBBABABBBABABAABBBA', 'A'),
   [12, 21, 'B', None, None])]]
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 opening serve[0, 0, None, 'B', 'right'][0, 0, None, 'B', 'right']Passed
control server wins odd point[1, 0, None, 'A', 'left'][1, 0, None, 'A', 'left']Passed
boundary receiver wins rally[1, 1, None, 'B', 'left'][1, 1, None, 'B', 'left']Passed
boundary game at 21-19[21, 19, 'A', None, None][21, 19, 'A', None, None]Passed
boundary cap at 30[29, 30, None, 'B', 'right'][29, 30, 'B', None, None]Failed
control 20-all continues[20, 20, None, 'B', 'right'][20, 20, None, 'B', 'right']Passed
regression: thirty point cap[28, 29, None, 'B', 'left'][28, 29, None, 'B', 'left']Passed
regression: thirty point cap[31, 29, 'A', None, None][30, 29, 'A', None, None]Failed
variant scenario 1[9, 21, 'B', None, None][9, 21, 'B', None, None]Passed
variant scenario 2[11, 17, None, 'A', 'left'][11, 17, None, 'A', 'left']Passed

SHA-256 / cba5156898a0b333b3d579f24a453e676ada60aa86731bfe1de76320b6c9c36b

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(rallies, first_server):
    a = b = 0
    server = first_server
    for r in rallies:
        if r == 'A':
            a += 1
        else:
            b += 1
        server = r
        if (max(a, b) >= 21 and abs(a - b) >= 2) or max(a, b) == 29:
            return [a, b, r, None, None]
    own = a if server == 'A' else b
    return [a, b, None, server, 'right' if own % 2 == 0 else 'left']
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 opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [28, 29, None, 'B', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1', ('BABBBABBABBBABBABBABAABABBBBBBABBBB', 'B'), [9, 21, 'B', None, None]),
  ('variant scenario 2', ('BBABAABABABBBBBAAABBABBBABBA', 'A'), [11, 17, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'A'),
   [29, 28, None, 'A', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'A'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('BAAABBBABABBABBABAAAAABBBBABAABBBBABBBBABBABBABA', 'B'),
   [16, 21, 'B', None, None]),
  ('variant scenario 2', ('BBAABABAAABBBB', 'A'), [6, 8, None, 'B', 'right'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'A'),
   [29, 28, None, 'A', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'B'),
   [29, 30, 'B', None, None]),
  ('variant scenario 1', ('BBAABAAA', 'A'), [5, 3, None, 'A', 'left']),
  ('variant scenario 2', ('BAABABBAAAAABBAABABABBBBBABAA', 'A'), [15, 14, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABAAB', 'B'),
   [30, 28, 'A', None, None]),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('ABABABABBBABBABBBAAAAAABABABAABAABBABAAABAAAAABABBBBABAAAABBABABB', 'A'),
   [21, 18, 'A', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [21, 20, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('AAAAABBBAAABBBAAAABBBBABBBBABABBBBAABBBBABBBABBBBAAABBBBABABBAAABAABABAABBBABB', 'A'),
   [17, 21, 'B', None, None]),
  ('variant scenario 2',
   ('BAABABBAABABABBBABABBABBABBABBBBBAABABBBBBBABBABBBABABBBABABAABBBA', 'A'),
   [12, 21, 'B', None, None])]]
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 opening serve[0, 0, None, 'B', 'right'][0, 0, None, 'B', 'right']Passed
control server wins odd point[1, 0, None, 'A', 'left'][1, 0, None, 'A', 'left']Passed
boundary receiver wins rally[1, 1, None, 'B', 'left'][1, 1, None, 'B', 'left']Passed
boundary game at 21-19[21, 19, 'A', None, None][21, 19, 'A', None, None]Passed
boundary cap at 30[29, 28, 'A', None, None][29, 30, 'B', None, None]Failed
control 20-all continues[20, 20, None, 'B', 'right'][20, 20, None, 'B', 'right']Passed
regression: thirty point cap[28, 29, 'B', None, None][28, 29, None, 'B', 'left']Failed
regression: thirty point cap[29, 28, 'A', None, None][30, 29, 'A', None, None]Failed
variant scenario 1[9, 21, 'B', None, None][9, 21, 'B', None, None]Passed
variant scenario 2[11, 17, None, 'A', 'left'][11, 17, None, 'A', 'left']Passed

SHA-256 / 2b7ce861bf710089cad09a485f2341d778f768a44b7896d59e0b95f649180a66

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(rallies, first_server):
    a = b = 0
    server = first_server
    for r in rallies:
        if r == 'A':
            a += 1
        else:
            b += 1
        server = r
        if (max(a, b) >= 21 and abs(a - b) >= 2) or max(a, b) == 30:
            return [a, b, r, None, None]
    own = a if server == 'A' else b
    return [a, b, None, server, 'right' if own % 2 == 0 else 'left']
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 opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [28, 29, None, 'B', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1', ('BABBBABBABBBABBABBABAABABBBBBBABBBB', 'B'), [9, 21, 'B', None, None]),
  ('variant scenario 2', ('BBABAABABABBBBBAAABBABBBABBA', 'A'), [11, 17, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'A'),
   [29, 28, None, 'A', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'A'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('BAAABBBABABBABBABAAAAABBBBABAABBBBABBBBABBABBABA', 'B'),
   [16, 21, 'B', None, None]),
  ('variant scenario 2', ('BBAABABAAABBBB', 'A'), [6, 8, None, 'B', 'right'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'A'),
   [29, 28, None, 'A', 'left']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'B'),
   [29, 30, 'B', None, None]),
  ('variant scenario 1', ('BBAABAAA', 'A'), [5, 3, None, 'A', 'left']),
  ('variant scenario 2', ('BAABABBAAAAABBAABABABBBBBABAA', 'A'), [15, 14, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABAAB', 'B'),
   [30, 28, 'A', None, None]),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('ABABABABBBABBABBBAAAAAABABABAABAABBABAAABAAAAABABBBBABAAAABBABABB', 'A'),
   [21, 18, 'A', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [21, 20, None, 'A', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: thirty point cap',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA', 'B'),
   [30, 29, 'A', None, None]),
  ('variant scenario 1',
   ('AAAAABBBAAABBBAAAABBBBABBBBABABBBBAABBBBABBBABBBBAAABBBBABABBAAABAABABAABBBABB', 'A'),
   [17, 21, 'B', None, None]),
  ('variant scenario 2',
   ('BAABABBAABABABBBABABBABBABBABBBBBAABABBBBBBABBABBBABABBBABABAABBBA', 'A'),
   [12, 21, 'B', None, None])]]
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 opening serve[0, 0, None, 'B', 'right'][0, 0, None, 'B', 'right']Passed
control server wins odd point[1, 0, None, 'A', 'left'][1, 0, None, 'A', 'left']Passed
boundary receiver wins rally[1, 1, None, 'B', 'left'][1, 1, None, 'B', 'left']Passed
boundary game at 21-19[21, 19, 'A', None, None][21, 19, 'A', None, None]Passed
boundary cap at 30[29, 30, 'B', None, None][29, 30, 'B', None, None]Passed
control 20-all continues[20, 20, None, 'B', 'right'][20, 20, None, 'B', 'right']Passed
regression: thirty point cap[28, 29, None, 'B', 'left'][28, 29, None, 'B', 'left']Passed
regression: thirty point cap[30, 29, 'A', None, None][30, 29, 'A', None, None]Passed
variant scenario 1[9, 21, 'B', None, None][9, 21, 'B', None, None]Passed
variant scenario 2[11, 17, None, 'A', 'left'][11, 17, None, 'A', 'left']Passed

SHA-256 / ff248d5e8666456d9a2dc42bc1ac4f29cdafbd2ca9f4dbe707df1c804885a062

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

Case digest / 3e33c1cddfff499bf68658681e2a24c4512ab5aa785e8f5269328ee2343d9b52