FAILURE MAP
← Case archive

FA-68036 / Traffic signal timing plans / Open access

Coordinated local cycle timer: only the yellow is subtracted from the split to find green end · case 01

Coordinated local cycle timer returns a wrong result when only the yellow is subtracted from the split to find green end.

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

ROOT CAUSE

The all-red time is treated as green, so green ends late and the red interval disappears.

VERIFIED REPAIR

Restore the green end within split rule so that the step reads `ge = start + s - y - r`.

Unsuccessful approach: Subtracting only the larger clearance still omits the other clearance interval.

Case contract

Input {cycle, offset, master, splits: [[phase, split s]] in sequence starting with the coordinated phase, yellow, red, ref}. Splits must sum to the cycle, else 'bad-splits'. Local time = (master - offset) mod cycle, where the offset marks the start of coordinated green (ref 'begin') or the end of coordinated green (ref 'end'). Each split is green then yellow then all-red. Return [phase, interval, seconds remaining].

Why this case matters

Signal timing arithmetic is exact and integer or rational; a wrong rule silently produces unsafe or inefficient timing plans.

1 / The failure

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

N = 1
observations = []
def solve(x):
    C = x['cycle']
    sp = x['splits']
    y, r = x['yellow'], x['red']
    if sum(s for _, s in sp) != C:
        return 'bad-splits'
    lc = (x['master'] - x['offset']) % C
    if x['ref'] == 'end':
        lc = (lc + sp[0][1] - y - r) % C
    start = 0
    for ph, s in sp:
        ge = start + s - y
        if lc < ge:
            return [ph, 'green', ge - lc]
        if lc < ge + y:
            return [ph, 'yellow', ge + y - lc]
        if lc < start + s:
            return [ph, 'red', start + s - lc]
        start += s
    return ['free', 'dark', 0]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 102, 'offset': 93, 'master': 365, 'splits': [[2, 23], [4, 36], [6, 27], [8, 21]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 77, 'offset': 52, 'master': 478, 'splits': [[2, 16], [4, 35], [6, 31]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 69, 'offset': 26, 'master': 109, 'splits': [[2, 29], [4, 40]], 'yellow': 3, 'red': 1, 'ref': 'end'}, [4, 'green', 26]), ({'cycle': 56, 'offset': 40, 'master': 328, 'splits': [[2, 20], [4, 18], [6, 13]], 'yellow': 3, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 101, 'offset': 45, 'master': 754, 'splits': [[2, 37], [4, 34], [6, 18], [8, 12]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 30]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits')], [({'cycle': 80, 'offset': 58, 'master': 397, 'splits': [[2, 13], [4, 12], [6, 28], [8, 32]], 'yellow': 3, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 90, 'offset': 36, 'master': 162, 'splits': [[2, 34], [4, 28], [6, 16], [8, 17]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 116, 'offset': 2, 'master': 729, 'splits': [[2, 32], [4, 38], [6, 29], [8, 17]], 'yellow': 3, 'red': 2, 'ref': 'end'}, [4, 'green', 7]), ({'cycle': 45, 'offset': 12, 'master': 489, 'splits': [[2, 17], [4, 33]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 97, 'offset': 25, 'master': 957, 'splits': [[2, 37], [4, 38], [6, 22]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [6, 'green', 1]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10])], [({'cycle': 118, 'offset': 70, 'master': 343, 'splits': [[2, 39], [4, 20], [6, 26], [8, 28]], 'yellow': 4, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 81, 'offset': 45, 'master': 213, 'splits': [[2, 40], [4, 18], [6, 18]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 53, 'offset': 19, 'master': 297, 'splits': [[2, 23], [4, 30]], 'yellow': 4, 'red': 2, 'ref': 'end'}, [4, 'green', 17]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 82, 'offset': 1, 'master': 853, 'splits': [[2, 29], [4, 36], [6, 22]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 91, 'offset': 88, 'master': 494, 'splits': [[2, 35], [4, 34], [6, 22]], 'yellow': 3, 'red': 1, 'ref': 'end'}, [6, 'green', 14]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25])], [({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 58, 'offset': 8, 'master': 318, 'splits': [[2, 32], [4, 26]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, [2, 'green', 7]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 26, 'offset': 5, 'master': 373, 'splits': [[2, 19], [4, 12]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 58, 'offset': 47, 'master': 814, 'splits': [[2, 40], [4, 13]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 119, 'offset': 49, 'master': 964, 'splits': [[2, 40], [4, 38], [6, 28], [8, 13]], 'yellow': 3, 'red': 2, 'ref': 'end'}, [8, 'red', 2]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 113, 'offset': 43, 'master': 818, 'splits': [[2, 31], [4, 27], [6, 20], [8, 40]], 'yellow': 3, 'red': 2, 'ref': 'end'}, 'bad-splits')], [({'cycle': 63, 'offset': 45, 'master': 684, 'splits': [[2, 15], [4, 21], [6, 32]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 85, 'offset': 19, 'master': 704, 'splits': [[2, 30], [4, 29], [6, 26]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 24]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 103, 'offset': 26, 'master': 254, 'splits': [[2, 35], [4, 31], [6, 37]], 'yellow': 4, 'red': 2, 'ref': 'end'}, [4, 'green', 9]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 96, 'offset': 11, 'master': 271, 'splits': [[2, 23], [4, 18], [6, 24], [8, 36]], 'yellow': 4, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 49, 'offset': 34, 'master': 885, 'splits': [[2, 17], [4, 37]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, 'bad-splits')]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(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
timing oracle 0[4, 'green', 11][4, 'green', 10]Failed
timing oracle 1bad-splitsbad-splitsPassed
timing oracle 2bad-splitsbad-splitsPassed
timing oracle 3[4, 'green', 27][4, 'green', 26]Failed
timing oracle 4bad-splitsbad-splitsPassed
timing oracle 5[2, 'green', 27][2, 'green', 25]Failed
timing oracle 6[2, 'green', 32][2, 'green', 30]Failed
timing oracle 7bad-splitsbad-splitsPassed

SHA-256 / 6dfc87fcd65f66838b74f2f876c815c81094e2d0192d9f1a33cac81cbbc6eb62

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    C = x['cycle']
    sp = x['splits']
    y, r = x['yellow'], x['red']
    if sum(s for _, s in sp) != C:
        return 'bad-splits'
    lc = (x['master'] - x['offset']) % C
    if x['ref'] == 'end':
        lc = (lc + sp[0][1] - y - r) % C
    start = 0
    for ph, s in sp:
        ge = start + s - max(y, r)
        if lc < ge:
            return [ph, 'green', ge - lc]
        if lc < ge + y:
            return [ph, 'yellow', ge + y - lc]
        if lc < start + s:
            return [ph, 'red', start + s - lc]
        start += s
    return ['free', 'dark', 0]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 102, 'offset': 93, 'master': 365, 'splits': [[2, 23], [4, 36], [6, 27], [8, 21]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 77, 'offset': 52, 'master': 478, 'splits': [[2, 16], [4, 35], [6, 31]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 69, 'offset': 26, 'master': 109, 'splits': [[2, 29], [4, 40]], 'yellow': 3, 'red': 1, 'ref': 'end'}, [4, 'green', 26]), ({'cycle': 56, 'offset': 40, 'master': 328, 'splits': [[2, 20], [4, 18], [6, 13]], 'yellow': 3, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 101, 'offset': 45, 'master': 754, 'splits': [[2, 37], [4, 34], [6, 18], [8, 12]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 30]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits')], [({'cycle': 80, 'offset': 58, 'master': 397, 'splits': [[2, 13], [4, 12], [6, 28], [8, 32]], 'yellow': 3, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 90, 'offset': 36, 'master': 162, 'splits': [[2, 34], [4, 28], [6, 16], [8, 17]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 116, 'offset': 2, 'master': 729, 'splits': [[2, 32], [4, 38], [6, 29], [8, 17]], 'yellow': 3, 'red': 2, 'ref': 'end'}, [4, 'green', 7]), ({'cycle': 45, 'offset': 12, 'master': 489, 'splits': [[2, 17], [4, 33]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 97, 'offset': 25, 'master': 957, 'splits': [[2, 37], [4, 38], [6, 22]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [6, 'green', 1]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10])], [({'cycle': 118, 'offset': 70, 'master': 343, 'splits': [[2, 39], [4, 20], [6, 26], [8, 28]], 'yellow': 4, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 81, 'offset': 45, 'master': 213, 'splits': [[2, 40], [4, 18], [6, 18]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 53, 'offset': 19, 'master': 297, 'splits': [[2, 23], [4, 30]], 'yellow': 4, 'red': 2, 'ref': 'end'}, [4, 'green', 17]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 82, 'offset': 1, 'master': 853, 'splits': [[2, 29], [4, 36], [6, 22]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 91, 'offset': 88, 'master': 494, 'splits': [[2, 35], [4, 34], [6, 22]], 'yellow': 3, 'red': 1, 'ref': 'end'}, [6, 'green', 14]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25])], [({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 58, 'offset': 8, 'master': 318, 'splits': [[2, 32], [4, 26]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, [2, 'green', 7]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 26, 'offset': 5, 'master': 373, 'splits': [[2, 19], [4, 12]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 58, 'offset': 47, 'master': 814, 'splits': [[2, 40], [4, 13]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 119, 'offset': 49, 'master': 964, 'splits': [[2, 40], [4, 38], [6, 28], [8, 13]], 'yellow': 3, 'red': 2, 'ref': 'end'}, [8, 'red', 2]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 113, 'offset': 43, 'master': 818, 'splits': [[2, 31], [4, 27], [6, 20], [8, 40]], 'yellow': 3, 'red': 2, 'ref': 'end'}, 'bad-splits')], [({'cycle': 63, 'offset': 45, 'master': 684, 'splits': [[2, 15], [4, 21], [6, 32]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 85, 'offset': 19, 'master': 704, 'splits': [[2, 30], [4, 29], [6, 26]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 24]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 103, 'offset': 26, 'master': 254, 'splits': [[2, 35], [4, 31], [6, 37]], 'yellow': 4, 'red': 2, 'ref': 'end'}, [4, 'green', 9]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 96, 'offset': 11, 'master': 271, 'splits': [[2, 23], [4, 18], [6, 24], [8, 36]], 'yellow': 4, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 49, 'offset': 34, 'master': 885, 'splits': [[2, 17], [4, 37]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, 'bad-splits')]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(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
timing oracle 0[4, 'green', 11][4, 'green', 10]Failed
timing oracle 1bad-splitsbad-splitsPassed
timing oracle 2bad-splitsbad-splitsPassed
timing oracle 3[4, 'green', 27][4, 'green', 26]Failed
timing oracle 4bad-splitsbad-splitsPassed
timing oracle 5[2, 'green', 27][2, 'green', 25]Failed
timing oracle 6[2, 'green', 32][2, 'green', 30]Failed
timing oracle 7bad-splitsbad-splitsPassed

SHA-256 / 2f2f1684c8be825a23fe18b008f1d9afa0998c443be20367d0456dd815e4b12e

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    C = x['cycle']
    sp = x['splits']
    y, r = x['yellow'], x['red']
    if sum(s for _, s in sp) != C:
        return 'bad-splits'
    lc = (x['master'] - x['offset']) % C
    if x['ref'] == 'end':
        lc = (lc + sp[0][1] - y - r) % C
    start = 0
    for ph, s in sp:
        ge = start + s - y - r
        if lc < ge:
            return [ph, 'green', ge - lc]
        if lc < ge + y:
            return [ph, 'yellow', ge + y - lc]
        if lc < start + s:
            return [ph, 'red', start + s - lc]
        start += s
    return ['free', 'dark', 0]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 102, 'offset': 93, 'master': 365, 'splits': [[2, 23], [4, 36], [6, 27], [8, 21]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 77, 'offset': 52, 'master': 478, 'splits': [[2, 16], [4, 35], [6, 31]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 69, 'offset': 26, 'master': 109, 'splits': [[2, 29], [4, 40]], 'yellow': 3, 'red': 1, 'ref': 'end'}, [4, 'green', 26]), ({'cycle': 56, 'offset': 40, 'master': 328, 'splits': [[2, 20], [4, 18], [6, 13]], 'yellow': 3, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 101, 'offset': 45, 'master': 754, 'splits': [[2, 37], [4, 34], [6, 18], [8, 12]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 30]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits')], [({'cycle': 80, 'offset': 58, 'master': 397, 'splits': [[2, 13], [4, 12], [6, 28], [8, 32]], 'yellow': 3, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 90, 'offset': 36, 'master': 162, 'splits': [[2, 34], [4, 28], [6, 16], [8, 17]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 116, 'offset': 2, 'master': 729, 'splits': [[2, 32], [4, 38], [6, 29], [8, 17]], 'yellow': 3, 'red': 2, 'ref': 'end'}, [4, 'green', 7]), ({'cycle': 45, 'offset': 12, 'master': 489, 'splits': [[2, 17], [4, 33]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 97, 'offset': 25, 'master': 957, 'splits': [[2, 37], [4, 38], [6, 22]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [6, 'green', 1]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10])], [({'cycle': 118, 'offset': 70, 'master': 343, 'splits': [[2, 39], [4, 20], [6, 26], [8, 28]], 'yellow': 4, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 81, 'offset': 45, 'master': 213, 'splits': [[2, 40], [4, 18], [6, 18]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 53, 'offset': 19, 'master': 297, 'splits': [[2, 23], [4, 30]], 'yellow': 4, 'red': 2, 'ref': 'end'}, [4, 'green', 17]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 82, 'offset': 1, 'master': 853, 'splits': [[2, 29], [4, 36], [6, 22]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 91, 'offset': 88, 'master': 494, 'splits': [[2, 35], [4, 34], [6, 22]], 'yellow': 3, 'red': 1, 'ref': 'end'}, [6, 'green', 14]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25])], [({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 58, 'offset': 8, 'master': 318, 'splits': [[2, 32], [4, 26]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, [2, 'green', 7]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 26, 'offset': 5, 'master': 373, 'splits': [[2, 19], [4, 12]], 'yellow': 4, 'red': 2, 'ref': 'end'}, 'bad-splits'), ({'cycle': 58, 'offset': 47, 'master': 814, 'splits': [[2, 40], [4, 13]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 119, 'offset': 49, 'master': 964, 'splits': [[2, 40], [4, 38], [6, 28], [8, 13]], 'yellow': 3, 'red': 2, 'ref': 'end'}, [8, 'red', 2]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 113, 'offset': 43, 'master': 818, 'splits': [[2, 31], [4, 27], [6, 20], [8, 40]], 'yellow': 3, 'red': 2, 'ref': 'end'}, 'bad-splits')], [({'cycle': 63, 'offset': 45, 'master': 684, 'splits': [[2, 15], [4, 21], [6, 32]], 'yellow': 3, 'red': 1, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 90, 'offset': 30, 'master': 45, 'splits': [[2, 40], [4, 25], [6, 25]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 10]), ({'cycle': 85, 'offset': 19, 'master': 704, 'splits': [[2, 30], [4, 29], [6, 26]], 'yellow': 4, 'red': 1, 'ref': 'end'}, [4, 'green', 24]), ({'cycle': 80, 'offset': 70, 'master': 10, 'splits': [[2, 50], [4, 30]], 'yellow': 3, 'red': 2, 'ref': 'begin'}, [2, 'green', 25]), ({'cycle': 103, 'offset': 26, 'master': 254, 'splits': [[2, 35], [4, 31], [6, 37]], 'yellow': 4, 'red': 2, 'ref': 'end'}, [4, 'green', 9]), ({'cycle': 100, 'offset': 5, 'master': 3, 'splits': [[2, 50], [4, 30], [8, 25]], 'yellow': 4, 'red': 2, 'ref': 'begin'}, 'bad-splits'), ({'cycle': 96, 'offset': 11, 'master': 271, 'splits': [[2, 23], [4, 18], [6, 24], [8, 36]], 'yellow': 4, 'red': 1, 'ref': 'end'}, 'bad-splits'), ({'cycle': 49, 'offset': 34, 'master': 885, 'splits': [[2, 17], [4, 37]], 'yellow': 4, 'red': 1, 'ref': 'begin'}, 'bad-splits')]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(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
timing oracle 0[4, 'green', 10][4, 'green', 10]Passed
timing oracle 1bad-splitsbad-splitsPassed
timing oracle 2bad-splitsbad-splitsPassed
timing oracle 3[4, 'green', 26][4, 'green', 26]Passed
timing oracle 4bad-splitsbad-splitsPassed
timing oracle 5[2, 'green', 25][2, 'green', 25]Passed
timing oracle 6[2, 'green', 30][2, 'green', 30]Passed
timing oracle 7bad-splitsbad-splitsPassed

SHA-256 / 62d547931404c92a5a2f30c7f6c1e2208df6f389cea31f292cfc113d3f8dd184

Verification & scope

A deterministic, bounded toy model with a stipulated contract; it makes no claim of conformance to any agency manual or standard. 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:47:58.463143+00:00.

Case digest / f4dfd3e117021edc25a8bf32b897a8016980f164951ecd50c9931536cf3a3393