FAILURE MAP
← Case archive

FA-68206 / Traffic signal timing plans / Open access

Transit signal priority decision: a bus arriving at green end is treated as in green · case 01

Transit signal priority decision returns a wrong result when a bus arriving at green end is treated as in green.

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

ROOT CAUSE

The exclusive green end is treated as green, so a bus arriving as the phase yields gets no extension.

VERIFIED REPAIR

Restore the green window membership rule so that the step reads `if gs <= a < ge:`.

Unsuccessful approach: Excluding green start treats a bus arriving at green onset as needing early green.

Case contract

Input {cycle, green_start, green_end (exclusive), max_ext, max_early, arrival (seconds, reduced modulo cycle), last_granted (cycle index or null), cycle_index, lockout}. A request within lockout cycles of the last grant (difference <= lockout) returns ['locked', 0]. Arrival in green needs nothing. If the arrival is less than max_ext seconds after green end (cyclically) green is extended through the arrival second: ['extend', d+1]. Otherwise green starts early by min(max_early, seconds until next green start).

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']
    a = x['arrival'] % C
    last = x['last_granted']
    if last is not None and x['cycle_index'] - last <= x['lockout']:
        return ['locked', 0]
    gs, ge = x['green_start'], x['green_end']
    if gs <= a <= ge:
        return ['none', 0]
    d = (a - ge) % C
    if d < x['max_ext']:
        return ['extend', d + 1]
    wait = (gs - a) % C
    return ['early', min(x['max_early'], wait)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 120, 'green_start': 19, 'green_end': 58, 'max_ext': 13, 'max_early': 8, 'arrival': 110, 'last_granted': 14, 'cycle_index': 21, 'lockout': 2}, ['early', 8]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 20, 'green_end': 35, 'max_ext': 5, 'max_early': 14, 'arrival': 141, 'last_granted': 16, 'cycle_index': 21, 'lockout': 1}, ['early', 14]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 50, 'green_end': 89, 'max_ext': 17, 'max_early': 13, 'arrival': 150, 'last_granted': None, 'cycle_index': 14, 'lockout': 3}, ['none', 0]), ({'cycle': 80, 'green_start': 3, 'green_end': 37, 'max_ext': 11, 'max_early': 15, 'arrival': 40, 'last_granted': None, 'cycle_index': 22, 'lockout': 1}, ['extend', 4]), ({'cycle': 90, 'green_start': 7, 'green_end': 32, 'max_ext': 8, 'max_early': 14, 'arrival': 32, 'last_granted': 1, 'cycle_index': 10, 'lockout': 1}, ['extend', 1])], [({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 110, 'green_start': 22, 'green_end': 56, 'max_ext': 11, 'max_early': 16, 'arrival': 132, 'last_granted': 17, 'cycle_index': 22, 'lockout': 3}, ['none', 0]), ({'cycle': 90, 'green_start': 37, 'green_end': 54, 'max_ext': 11, 'max_early': 6, 'arrival': 234, 'last_granted': None, 'cycle_index': 3, 'lockout': 2}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 130, 'green_start': 27, 'green_end': 52, 'max_ext': 11, 'max_early': 9, 'arrival': 318, 'last_granted': None, 'cycle_index': 1, 'lockout': 2}, ['extend', 7]), ({'cycle': 100, 'green_start': 30, 'green_end': 45, 'max_ext': 20, 'max_early': 10, 'arrival': 28, 'last_granted': 1, 'cycle_index': 6, 'lockout': 2}, ['early', 2]), ({'cycle': 80, 'green_start': 9, 'green_end': 46, 'max_ext': 15, 'max_early': 20, 'arrival': 106, 'last_granted': 20, 'cycle_index': 16, 'lockout': 2}, ['locked', 0])], [({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 100, 'green_start': 0, 'green_end': 17, 'max_ext': 7, 'max_early': 8, 'arrival': 265, 'last_granted': None, 'cycle_index': 15, 'lockout': 1}, ['early', 8]), ({'cycle': 90, 'green_start': 40, 'green_end': 65, 'max_ext': 11, 'max_early': 14, 'arrival': 21, 'last_granted': None, 'cycle_index': 15, 'lockout': 1}, ['early', 14]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 26, 'green_end': 47, 'max_ext': 15, 'max_early': 19, 'arrival': 137, 'last_granted': 10, 'cycle_index': 21, 'lockout': 2}, ['extend', 1]), ({'cycle': 140, 'green_start': 29, 'green_end': 55, 'max_ext': 14, 'max_early': 16, 'arrival': 195, 'last_granted': 8, 'cycle_index': 19, 'lockout': 3}, ['extend', 1]), ({'cycle': 110, 'green_start': 46, 'green_end': 66, 'max_ext': 10, 'max_early': 12, 'arrival': 204, 'last_granted': 12, 'cycle_index': 19, 'lockout': 3}, ['early', 12])], [({'cycle': 140, 'green_start': 65, 'green_end': 92, 'max_ext': 12, 'max_early': 13, 'arrival': 196, 'last_granted': None, 'cycle_index': 6, 'lockout': 2}, ['early', 9]), ({'cycle': 100, 'green_start': 3, 'green_end': 52, 'max_ext': 11, 'max_early': 9, 'arrival': 252, 'last_granted': None, 'cycle_index': 13, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 2, 'green_end': 21, 'max_ext': 13, 'max_early': 19, 'arrival': 182, 'last_granted': None, 'cycle_index': 8, 'lockout': 2}, ['none', 0]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 130, 'green_start': 65, 'green_end': 93, 'max_ext': 6, 'max_early': 10, 'arrival': 245, 'last_granted': 13, 'cycle_index': 22, 'lockout': 1}, ['early', 10]), ({'cycle': 100, 'green_start': 22, 'green_end': 55, 'max_ext': 19, 'max_early': 16, 'arrival': 255, 'last_granted': None, 'cycle_index': 17, 'lockout': 3}, ['extend', 1])], [({'cycle': 120, 'green_start': 2, 'green_end': 19, 'max_ext': 7, 'max_early': 19, 'arrival': 259, 'last_granted': None, 'cycle_index': 16, 'lockout': 2}, ['extend', 1]), ({'cycle': 100, 'green_start': 30, 'green_end': 45, 'max_ext': 20, 'max_early': 10, 'arrival': 28, 'last_granted': 1, 'cycle_index': 6, 'lockout': 2}, ['early', 2]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 100, 'green_start': 34, 'green_end': 62, 'max_ext': 16, 'max_early': 10, 'arrival': 134, 'last_granted': None, 'cycle_index': 4, 'lockout': 2}, ['none', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 140, 'green_start': 49, 'green_end': 114, 'max_ext': 18, 'max_early': 19, 'arrival': 53, 'last_granted': 5, 'cycle_index': 7, 'lockout': 1}, ['none', 0]), ({'cycle': 140, 'green_start': 63, 'green_end': 112, 'max_ext': 9, 'max_early': 6, 'arrival': 347, 'last_granted': None, 'cycle_index': 11, 'lockout': 2}, ['none', 0]), ({'cycle': 100, 'green_start': 40, 'green_end': 58, 'max_ext': 9, 'max_early': 14, 'arrival': 286, 'last_granted': None, 'cycle_index': 22, 'lockout': 1}, ['early', 14])]]
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['none', 0]['none', 0]Passed
timing oracle 1['early', 8]['early', 8]Passed
timing oracle 2['locked', 0]['locked', 0]Passed
timing oracle 3['early', 14]['early', 14]Passed
timing oracle 4['none', 0]['extend', 1]Failed
timing oracle 5['none', 0]['none', 0]Passed
timing oracle 6['extend', 4]['extend', 4]Passed
timing oracle 7['none', 0]['extend', 1]Failed

SHA-256 / 20bf8f35445e2f4687224740bd2a703313f635aeecf731bcf2f68dc81b3019db

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']
    a = x['arrival'] % C
    last = x['last_granted']
    if last is not None and x['cycle_index'] - last <= x['lockout']:
        return ['locked', 0]
    gs, ge = x['green_start'], x['green_end']
    if gs < a < ge:
        return ['none', 0]
    d = (a - ge) % C
    if d < x['max_ext']:
        return ['extend', d + 1]
    wait = (gs - a) % C
    return ['early', min(x['max_early'], wait)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 120, 'green_start': 19, 'green_end': 58, 'max_ext': 13, 'max_early': 8, 'arrival': 110, 'last_granted': 14, 'cycle_index': 21, 'lockout': 2}, ['early', 8]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 20, 'green_end': 35, 'max_ext': 5, 'max_early': 14, 'arrival': 141, 'last_granted': 16, 'cycle_index': 21, 'lockout': 1}, ['early', 14]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 50, 'green_end': 89, 'max_ext': 17, 'max_early': 13, 'arrival': 150, 'last_granted': None, 'cycle_index': 14, 'lockout': 3}, ['none', 0]), ({'cycle': 80, 'green_start': 3, 'green_end': 37, 'max_ext': 11, 'max_early': 15, 'arrival': 40, 'last_granted': None, 'cycle_index': 22, 'lockout': 1}, ['extend', 4]), ({'cycle': 90, 'green_start': 7, 'green_end': 32, 'max_ext': 8, 'max_early': 14, 'arrival': 32, 'last_granted': 1, 'cycle_index': 10, 'lockout': 1}, ['extend', 1])], [({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 110, 'green_start': 22, 'green_end': 56, 'max_ext': 11, 'max_early': 16, 'arrival': 132, 'last_granted': 17, 'cycle_index': 22, 'lockout': 3}, ['none', 0]), ({'cycle': 90, 'green_start': 37, 'green_end': 54, 'max_ext': 11, 'max_early': 6, 'arrival': 234, 'last_granted': None, 'cycle_index': 3, 'lockout': 2}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 130, 'green_start': 27, 'green_end': 52, 'max_ext': 11, 'max_early': 9, 'arrival': 318, 'last_granted': None, 'cycle_index': 1, 'lockout': 2}, ['extend', 7]), ({'cycle': 100, 'green_start': 30, 'green_end': 45, 'max_ext': 20, 'max_early': 10, 'arrival': 28, 'last_granted': 1, 'cycle_index': 6, 'lockout': 2}, ['early', 2]), ({'cycle': 80, 'green_start': 9, 'green_end': 46, 'max_ext': 15, 'max_early': 20, 'arrival': 106, 'last_granted': 20, 'cycle_index': 16, 'lockout': 2}, ['locked', 0])], [({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 100, 'green_start': 0, 'green_end': 17, 'max_ext': 7, 'max_early': 8, 'arrival': 265, 'last_granted': None, 'cycle_index': 15, 'lockout': 1}, ['early', 8]), ({'cycle': 90, 'green_start': 40, 'green_end': 65, 'max_ext': 11, 'max_early': 14, 'arrival': 21, 'last_granted': None, 'cycle_index': 15, 'lockout': 1}, ['early', 14]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 26, 'green_end': 47, 'max_ext': 15, 'max_early': 19, 'arrival': 137, 'last_granted': 10, 'cycle_index': 21, 'lockout': 2}, ['extend', 1]), ({'cycle': 140, 'green_start': 29, 'green_end': 55, 'max_ext': 14, 'max_early': 16, 'arrival': 195, 'last_granted': 8, 'cycle_index': 19, 'lockout': 3}, ['extend', 1]), ({'cycle': 110, 'green_start': 46, 'green_end': 66, 'max_ext': 10, 'max_early': 12, 'arrival': 204, 'last_granted': 12, 'cycle_index': 19, 'lockout': 3}, ['early', 12])], [({'cycle': 140, 'green_start': 65, 'green_end': 92, 'max_ext': 12, 'max_early': 13, 'arrival': 196, 'last_granted': None, 'cycle_index': 6, 'lockout': 2}, ['early', 9]), ({'cycle': 100, 'green_start': 3, 'green_end': 52, 'max_ext': 11, 'max_early': 9, 'arrival': 252, 'last_granted': None, 'cycle_index': 13, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 2, 'green_end': 21, 'max_ext': 13, 'max_early': 19, 'arrival': 182, 'last_granted': None, 'cycle_index': 8, 'lockout': 2}, ['none', 0]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 130, 'green_start': 65, 'green_end': 93, 'max_ext': 6, 'max_early': 10, 'arrival': 245, 'last_granted': 13, 'cycle_index': 22, 'lockout': 1}, ['early', 10]), ({'cycle': 100, 'green_start': 22, 'green_end': 55, 'max_ext': 19, 'max_early': 16, 'arrival': 255, 'last_granted': None, 'cycle_index': 17, 'lockout': 3}, ['extend', 1])], [({'cycle': 120, 'green_start': 2, 'green_end': 19, 'max_ext': 7, 'max_early': 19, 'arrival': 259, 'last_granted': None, 'cycle_index': 16, 'lockout': 2}, ['extend', 1]), ({'cycle': 100, 'green_start': 30, 'green_end': 45, 'max_ext': 20, 'max_early': 10, 'arrival': 28, 'last_granted': 1, 'cycle_index': 6, 'lockout': 2}, ['early', 2]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 100, 'green_start': 34, 'green_end': 62, 'max_ext': 16, 'max_early': 10, 'arrival': 134, 'last_granted': None, 'cycle_index': 4, 'lockout': 2}, ['none', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 140, 'green_start': 49, 'green_end': 114, 'max_ext': 18, 'max_early': 19, 'arrival': 53, 'last_granted': 5, 'cycle_index': 7, 'lockout': 1}, ['none', 0]), ({'cycle': 140, 'green_start': 63, 'green_end': 112, 'max_ext': 9, 'max_early': 6, 'arrival': 347, 'last_granted': None, 'cycle_index': 11, 'lockout': 2}, ['none', 0]), ({'cycle': 100, 'green_start': 40, 'green_end': 58, 'max_ext': 9, 'max_early': 14, 'arrival': 286, 'last_granted': None, 'cycle_index': 22, 'lockout': 1}, ['early', 14])]]
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['early', 0]['none', 0]Failed
timing oracle 1['early', 8]['early', 8]Passed
timing oracle 2['locked', 0]['locked', 0]Passed
timing oracle 3['early', 14]['early', 14]Passed
timing oracle 4['extend', 1]['extend', 1]Passed
timing oracle 5['early', 0]['none', 0]Failed
timing oracle 6['extend', 4]['extend', 4]Passed
timing oracle 7['extend', 1]['extend', 1]Passed

SHA-256 / e92e17f4b9c8cc7183bd62ffc07ab20676a959ab617f901bb65e86db096faecf

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']
    a = x['arrival'] % C
    last = x['last_granted']
    if last is not None and x['cycle_index'] - last <= x['lockout']:
        return ['locked', 0]
    gs, ge = x['green_start'], x['green_end']
    if gs <= a < ge:
        return ['none', 0]
    d = (a - ge) % C
    if d < x['max_ext']:
        return ['extend', d + 1]
    wait = (gs - a) % C
    return ['early', min(x['max_early'], wait)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 120, 'green_start': 19, 'green_end': 58, 'max_ext': 13, 'max_early': 8, 'arrival': 110, 'last_granted': 14, 'cycle_index': 21, 'lockout': 2}, ['early', 8]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 20, 'green_end': 35, 'max_ext': 5, 'max_early': 14, 'arrival': 141, 'last_granted': 16, 'cycle_index': 21, 'lockout': 1}, ['early', 14]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 50, 'green_end': 89, 'max_ext': 17, 'max_early': 13, 'arrival': 150, 'last_granted': None, 'cycle_index': 14, 'lockout': 3}, ['none', 0]), ({'cycle': 80, 'green_start': 3, 'green_end': 37, 'max_ext': 11, 'max_early': 15, 'arrival': 40, 'last_granted': None, 'cycle_index': 22, 'lockout': 1}, ['extend', 4]), ({'cycle': 90, 'green_start': 7, 'green_end': 32, 'max_ext': 8, 'max_early': 14, 'arrival': 32, 'last_granted': 1, 'cycle_index': 10, 'lockout': 1}, ['extend', 1])], [({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 110, 'green_start': 22, 'green_end': 56, 'max_ext': 11, 'max_early': 16, 'arrival': 132, 'last_granted': 17, 'cycle_index': 22, 'lockout': 3}, ['none', 0]), ({'cycle': 90, 'green_start': 37, 'green_end': 54, 'max_ext': 11, 'max_early': 6, 'arrival': 234, 'last_granted': None, 'cycle_index': 3, 'lockout': 2}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 130, 'green_start': 27, 'green_end': 52, 'max_ext': 11, 'max_early': 9, 'arrival': 318, 'last_granted': None, 'cycle_index': 1, 'lockout': 2}, ['extend', 7]), ({'cycle': 100, 'green_start': 30, 'green_end': 45, 'max_ext': 20, 'max_early': 10, 'arrival': 28, 'last_granted': 1, 'cycle_index': 6, 'lockout': 2}, ['early', 2]), ({'cycle': 80, 'green_start': 9, 'green_end': 46, 'max_ext': 15, 'max_early': 20, 'arrival': 106, 'last_granted': 20, 'cycle_index': 16, 'lockout': 2}, ['locked', 0])], [({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 100, 'green_start': 0, 'green_end': 17, 'max_ext': 7, 'max_early': 8, 'arrival': 265, 'last_granted': None, 'cycle_index': 15, 'lockout': 1}, ['early', 8]), ({'cycle': 90, 'green_start': 40, 'green_end': 65, 'max_ext': 11, 'max_early': 14, 'arrival': 21, 'last_granted': None, 'cycle_index': 15, 'lockout': 1}, ['early', 14]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 26, 'green_end': 47, 'max_ext': 15, 'max_early': 19, 'arrival': 137, 'last_granted': 10, 'cycle_index': 21, 'lockout': 2}, ['extend', 1]), ({'cycle': 140, 'green_start': 29, 'green_end': 55, 'max_ext': 14, 'max_early': 16, 'arrival': 195, 'last_granted': 8, 'cycle_index': 19, 'lockout': 3}, ['extend', 1]), ({'cycle': 110, 'green_start': 46, 'green_end': 66, 'max_ext': 10, 'max_early': 12, 'arrival': 204, 'last_granted': 12, 'cycle_index': 19, 'lockout': 3}, ['early', 12])], [({'cycle': 140, 'green_start': 65, 'green_end': 92, 'max_ext': 12, 'max_early': 13, 'arrival': 196, 'last_granted': None, 'cycle_index': 6, 'lockout': 2}, ['early', 9]), ({'cycle': 100, 'green_start': 3, 'green_end': 52, 'max_ext': 11, 'max_early': 9, 'arrival': 252, 'last_granted': None, 'cycle_index': 13, 'lockout': 1}, ['extend', 1]), ({'cycle': 100, 'green_start': 10, 'green_end': 50, 'max_ext': 10, 'max_early': 10, 'arrival': 250, 'last_granted': 3, 'cycle_index': 5, 'lockout': 2}, ['locked', 0]), ({'cycle': 90, 'green_start': 2, 'green_end': 21, 'max_ext': 13, 'max_early': 19, 'arrival': 182, 'last_granted': None, 'cycle_index': 8, 'lockout': 2}, ['none', 0]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 130, 'green_start': 65, 'green_end': 93, 'max_ext': 6, 'max_early': 10, 'arrival': 245, 'last_granted': 13, 'cycle_index': 22, 'lockout': 1}, ['early', 10]), ({'cycle': 100, 'green_start': 22, 'green_end': 55, 'max_ext': 19, 'max_early': 16, 'arrival': 255, 'last_granted': None, 'cycle_index': 17, 'lockout': 3}, ['extend', 1])], [({'cycle': 120, 'green_start': 2, 'green_end': 19, 'max_ext': 7, 'max_early': 19, 'arrival': 259, 'last_granted': None, 'cycle_index': 16, 'lockout': 2}, ['extend', 1]), ({'cycle': 100, 'green_start': 30, 'green_end': 45, 'max_ext': 20, 'max_early': 10, 'arrival': 28, 'last_granted': 1, 'cycle_index': 6, 'lockout': 2}, ['early', 2]), ({'cycle': 100, 'green_start': 10, 'green_end': 45, 'max_ext': 10, 'max_early': 10, 'arrival': 110, 'last_granted': None, 'cycle_index': 4, 'lockout': 1}, ['none', 0]), ({'cycle': 100, 'green_start': 34, 'green_end': 62, 'max_ext': 16, 'max_early': 10, 'arrival': 134, 'last_granted': None, 'cycle_index': 4, 'lockout': 2}, ['none', 0]), ({'cycle': 90, 'green_start': 0, 'green_end': 40, 'max_ext': 12, 'max_early': 8, 'arrival': 40, 'last_granted': None, 'cycle_index': 0, 'lockout': 1}, ['extend', 1]), ({'cycle': 140, 'green_start': 49, 'green_end': 114, 'max_ext': 18, 'max_early': 19, 'arrival': 53, 'last_granted': 5, 'cycle_index': 7, 'lockout': 1}, ['none', 0]), ({'cycle': 140, 'green_start': 63, 'green_end': 112, 'max_ext': 9, 'max_early': 6, 'arrival': 347, 'last_granted': None, 'cycle_index': 11, 'lockout': 2}, ['none', 0]), ({'cycle': 100, 'green_start': 40, 'green_end': 58, 'max_ext': 9, 'max_early': 14, 'arrival': 286, 'last_granted': None, 'cycle_index': 22, 'lockout': 1}, ['early', 14])]]
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['none', 0]['none', 0]Passed
timing oracle 1['early', 8]['early', 8]Passed
timing oracle 2['locked', 0]['locked', 0]Passed
timing oracle 3['early', 14]['early', 14]Passed
timing oracle 4['extend', 1]['extend', 1]Passed
timing oracle 5['none', 0]['none', 0]Passed
timing oracle 6['extend', 4]['extend', 4]Passed
timing oracle 7['extend', 1]['extend', 1]Passed

SHA-256 / fd8d45aac7e0d0870865a9f9cf5621a15c753757ee3b547fa20435c91d41333d

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

Case digest / c010a4a68d96ce0171ee9c35e888fa5aec234979499603e695046655279395f6