FA-81731 / MIDI event timing / Open access
Active sensing timeout detection: timeout stamped at the next message arrival · case 01
A timeout is reported when the late message finally arrives instead of 300 ms after the last activity.
ROOT CAUSE
The timeout is timestamped with the arrival time of the message that revealed the gap.
VERIFIED REPAIR
Restore the timeout timestamp step so that it reads `: out.append(last + 300) armed = False`.
Unsuccessful approach: Subtracting 300 from the arrival time is only correct when the gap is exactly 600 ms.
Case contract
Input [messages, end_time] where messages are time-ordered [ms, kind]. Monitoring is armed by a "sense" message. While armed, if more than 300 ms pass between any two consecutive messages (of any kind), a timeout is reported at previous message time + 300 and monitoring disarms until the next sense message. At end_time the same check applies to the last message. Return the list of timeout times.
Why this case matters
MIDI sequencers, file readers and synth drivers depend on exact event ordering and tick/time arithmetic.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
if not isinstance(x, list) or len(x) != 2:
return None
msgs, end = x
armed = False
last = None
out = []
for t, m in msgs:
if armed and t - last > 300:
out.append(t)
armed = False
if m == 'sense':
armed = True
last = t
if armed and end - last > 300:
out.append(last + 300)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500])], [([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense']], 301], [300]), ([[[0, 'sense']], 300], []), ([[], 100], []), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense']], 300], []), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[], 100], []), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[100, 'sense'], [420, 'clock']], 430], [400])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | [] | [] | Passed |
| oracle 1 | [301] | [300] | Failed |
| oracle 2 | [] | [] | Passed |
| oracle 3 | [] | [] | Passed |
| oracle 4 | [] | [] | Passed |
| oracle 5 | [800] | [800] | Passed |
| oracle 6 | [320] | [300] | Failed |
| oracle 7 | [600] | [500] | Failed |
SHA-256 / c03be3723fce9221746780904da22c6ed3e6798344c7f3d391f233efd1514517
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
if not isinstance(x, list) or len(x) != 2:
return None
msgs, end = x
armed = False
last = None
out = []
for t, m in msgs:
if armed and t - last > 300:
out.append(t - 300)
armed = False
if m == 'sense':
armed = True
last = t
if armed and end - last > 300:
out.append(last + 300)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500])], [([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense']], 301], [300]), ([[[0, 'sense']], 300], []), ([[], 100], []), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense']], 300], []), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[], 100], []), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[100, 'sense'], [420, 'clock']], 430], [400])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | [] | [] | Passed |
| oracle 1 | [1] | [300] | Failed |
| oracle 2 | [] | [] | Passed |
| oracle 3 | [] | [] | Passed |
| oracle 4 | [] | [] | Passed |
| oracle 5 | [800] | [800] | Passed |
| oracle 6 | [20] | [300] | Failed |
| oracle 7 | [300] | [500] | Failed |
SHA-256 / b93fc9843a843849420176562be66bf8097f8756ec470b3e2c9900db8df9a8e8
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
if not isinstance(x, list) or len(x) != 2:
return None
msgs, end = x
armed = False
last = None
out = []
for t, m in msgs:
if armed and t - last > 300:
out.append(last + 300)
armed = False
if m == 'sense':
armed = True
last = t
if armed and end - last > 300:
out.append(last + 300)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500])], [([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense']], 301], [300]), ([[[0, 'sense']], 300], []), ([[], 100], []), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense']], 300], []), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[], 100], []), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [301, 'note']], 301], [300]), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[0, 'sense'], [200, 'clock'], [600, 'note']], 600], [500]), ([[[100, 'sense'], [420, 'clock']], 430], [400])], [([[[0, 'sense'], [200, 'sense'], [400, 'sense']], 500], []), ([[[0, 'sense'], [300, 'note']], 300], []), ([[[0, 'note'], [1000, 'note']], 2000], []), ([[[0, 'sense'], [250, 'clock'], [500, 'clock'], [750, 'sense']], 800], []), ([[[0, 'sense'], [250, 'note'], [500, 'note']], 1000], [800]), ([[[0, 'sense'], [800, 'note'], [900, 'note'], [1300, 'sense']], 1400], [300]), ([[[0, 'sense'], [320, 'note'], [650, 'note']], 660], [300]), ([[[100, 'sense'], [420, 'clock']], 430], [400])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | [] | [] | Passed |
| oracle 1 | [300] | [300] | Passed |
| oracle 2 | [] | [] | Passed |
| oracle 3 | [] | [] | Passed |
| oracle 4 | [] | [] | Passed |
| oracle 5 | [800] | [800] | Passed |
| oracle 6 | [300] | [300] | Passed |
| oracle 7 | [500] | [500] | Passed |
SHA-256 / ca6eb5bbcb94f5b56cf8344a10216162536c273a6f3355362a63f002e891dac8
Verification & scope
A deterministic bounded teaching model with a stipulated toy contract; it is not a complete Standard MIDI File or MIDI 1.0/2.0 implementation. 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:05.714291+00:00.
Case digest / 7bc840453e9ae5fb0bbb3a5b8435da16427830771f52878d32229eefbdffc95e