FAILURE MAP
← Case archive

FA-31621 / Keyboard interactions / Open access

Keyboard macro deterministic playback scheduler: Playback cleanup loses held keys after repeated or simultaneous downs · case 01

The event trace violates the press track rule and produces incorrect keyboard state or command output.

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

ROOT CAUSE

Playback cleanup loses held keys after repeated or simultaneous downs.

VERIFIED REPAIR

Use the contract transition `if kind=='down': held.add(key)` at the press track fault site; preserve the other state transitions.

Unsuccessful approach: The partial repair changes this transition to if kind=='down': held={key}, which still violates the model contract on the explicit regression traces.

Case contract

Case [records,start,rate_num,rate_den,loops,gap]. Records [kind,key,offset] have ordered nonnegative integer offsets. Positive rational playback speed scales deadlines by floor(offset*den/num). Repeat cycles start after scaled final offset plus gap. End of each cycle synthesizes releases for remaining held keys in sorted order. Return emitted [kind,key,deadline] records. Loops nonnegative; gap positive. Inputs are finite ordered event traces; return the stated deterministic state. Batch entries are independent. N varies the number of independent input transactions.

Why this case matters

Controlled keyboard event processing model for debugging application event logic.

1 / The failure

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

N = 1
observations = []
def solve(cases):
    def run(c):
        records,start,num,den,loops,gap=c
        out=[]
        duration=(records[-1][2]*den//num) if records else 0
        for cycle in range(loops):
            base=start+cycle*(duration+gap)
            held=set()
            for kind,key,offset in records:
                due=base+offset*den//num
                if kind=='down': held.symmetric_difference_update({key})
                elif kind=='up': held.discard(key)
                out.append([kind,key,due])
            for key in sorted(held):
                out.append(['up',key,base+duration])
        return out
    return [run(c) for c in cases]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('macro-play scenario 0', solve([[[], 10, 1, 1, 0, 2]] * N), [[]] * N)
check('macro-play scenario 1', solve([[[], 10, 1, 1, 2, 2]] * N), [[]] * N)
check('macro-play scenario 2', solve([[[['down', 'A', 0], ['up', 'A', 3]], 10, 2, 1, 2, 4]] * N), [[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]] * N)
check('macro-play scenario 3', solve([[[['up', 'A', 0]], 10, 1, 1, 1, 2]] * N), [[['up', 'A', 10]]] * N)
check('macro-play scenario 4', solve([[[['down', 'A', 0], ['down', 'B', 1]], 10, 1, 1, 2, 2]] * N), [[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]] * N)
check('macro-play scenario 5', solve([[[['down', 'A', 0], ['down', 'A', 1]], 10, 1, 1, 1, 2]] * N), [[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]] * N)
check('macro-play scenario 6', solve([[[['down', 'A', 0], ['down', 'B', 1], ['up', 'A', 2]], 10, 1, 1, 1, 2]] * N), [[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]] * N)
check('macro-play scenario 7', solve([[[['down', 'A', 1], ['up', 'A', 5]], 10, 3, 2, 2, 2]] * N), [[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]] * N)
check('macro-play scenario 8', solve([[[['down', 'A', 0], ['up', 'A', 2]], 10, 1, 1, 0, 2]] * N), [[]] * N)
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
macro-play scenario 0[[]][[]]Passed
macro-play scenario 1[[]][[]]Passed
macro-play scenario 2[[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]][[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]]Passed
macro-play scenario 3[[['up', 'A', 10]]][[['up', 'A', 10]]]Passed
macro-play scenario 4[[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]][[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]]Passed
macro-play scenario 5[[['down', 'A', 10], ['down', 'A', 11]]][[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]]Failed
macro-play scenario 6[[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]][[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]]Passed
macro-play scenario 7[[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]][[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]]Passed
macro-play scenario 8[[]][[]]Passed

SHA-256 / 0ce756293e40896afc1a73c3a1974a572def2555b078b99051e00315002449f6

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(cases):
    def run(c):
        records,start,num,den,loops,gap=c
        out=[]
        duration=(records[-1][2]*den//num) if records else 0
        for cycle in range(loops):
            base=start+cycle*(duration+gap)
            held=set()
            for kind,key,offset in records:
                due=base+offset*den//num
                if kind=='down': held={key}
                elif kind=='up': held.discard(key)
                out.append([kind,key,due])
            for key in sorted(held):
                out.append(['up',key,base+duration])
        return out
    return [run(c) for c in cases]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('macro-play scenario 0', solve([[[], 10, 1, 1, 0, 2]] * N), [[]] * N)
check('macro-play scenario 1', solve([[[], 10, 1, 1, 2, 2]] * N), [[]] * N)
check('macro-play scenario 2', solve([[[['down', 'A', 0], ['up', 'A', 3]], 10, 2, 1, 2, 4]] * N), [[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]] * N)
check('macro-play scenario 3', solve([[[['up', 'A', 0]], 10, 1, 1, 1, 2]] * N), [[['up', 'A', 10]]] * N)
check('macro-play scenario 4', solve([[[['down', 'A', 0], ['down', 'B', 1]], 10, 1, 1, 2, 2]] * N), [[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]] * N)
check('macro-play scenario 5', solve([[[['down', 'A', 0], ['down', 'A', 1]], 10, 1, 1, 1, 2]] * N), [[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]] * N)
check('macro-play scenario 6', solve([[[['down', 'A', 0], ['down', 'B', 1], ['up', 'A', 2]], 10, 1, 1, 1, 2]] * N), [[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]] * N)
check('macro-play scenario 7', solve([[[['down', 'A', 1], ['up', 'A', 5]], 10, 3, 2, 2, 2]] * N), [[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]] * N)
check('macro-play scenario 8', solve([[[['down', 'A', 0], ['up', 'A', 2]], 10, 1, 1, 0, 2]] * N), [[]] * N)
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
macro-play scenario 0[[]][[]]Passed
macro-play scenario 1[[]][[]]Passed
macro-play scenario 2[[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]][[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]]Passed
macro-play scenario 3[[['up', 'A', 10]]][[['up', 'A', 10]]]Passed
macro-play scenario 4[[['down', 'A', 10], ['down', 'B', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'B', 14]]][[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]]Failed
macro-play scenario 5[[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]][[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]]Passed
macro-play scenario 6[[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]][[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]]Passed
macro-play scenario 7[[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]][[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]]Passed
macro-play scenario 8[[]][[]]Passed

SHA-256 / f74e44ee7918e2d32eac4ed8e846bd9535967ae313aa3e3f66f918a328aed550

3 / The verified repair

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

N = 1
observations = []
def solve(cases):
    def run(c):
        records,start,num,den,loops,gap=c
        out=[]
        duration=(records[-1][2]*den//num) if records else 0
        for cycle in range(loops):
            base=start+cycle*(duration+gap)
            held=set()
            for kind,key,offset in records:
                due=base+offset*den//num
                if kind=='down': held.add(key)
                elif kind=='up': held.discard(key)
                out.append([kind,key,due])
            for key in sorted(held):
                out.append(['up',key,base+duration])
        return out
    return [run(c) for c in cases]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('macro-play scenario 0', solve([[[], 10, 1, 1, 0, 2]] * N), [[]] * N)
check('macro-play scenario 1', solve([[[], 10, 1, 1, 2, 2]] * N), [[]] * N)
check('macro-play scenario 2', solve([[[['down', 'A', 0], ['up', 'A', 3]], 10, 2, 1, 2, 4]] * N), [[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]] * N)
check('macro-play scenario 3', solve([[[['up', 'A', 0]], 10, 1, 1, 1, 2]] * N), [[['up', 'A', 10]]] * N)
check('macro-play scenario 4', solve([[[['down', 'A', 0], ['down', 'B', 1]], 10, 1, 1, 2, 2]] * N), [[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]] * N)
check('macro-play scenario 5', solve([[[['down', 'A', 0], ['down', 'A', 1]], 10, 1, 1, 1, 2]] * N), [[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]] * N)
check('macro-play scenario 6', solve([[[['down', 'A', 0], ['down', 'B', 1], ['up', 'A', 2]], 10, 1, 1, 1, 2]] * N), [[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]] * N)
check('macro-play scenario 7', solve([[[['down', 'A', 1], ['up', 'A', 5]], 10, 3, 2, 2, 2]] * N), [[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]] * N)
check('macro-play scenario 8', solve([[[['down', 'A', 0], ['up', 'A', 2]], 10, 1, 1, 0, 2]] * N), [[]] * N)
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
macro-play scenario 0[[]][[]]Passed
macro-play scenario 1[[]][[]]Passed
macro-play scenario 2[[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]][[['down', 'A', 10], ['up', 'A', 11], ['down', 'A', 15], ['up', 'A', 16]]]Passed
macro-play scenario 3[[['up', 'A', 10]]][[['up', 'A', 10]]]Passed
macro-play scenario 4[[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]][[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 11], ['up', 'B', 11], ['down', 'A', 13], ['down', 'B', 14], ['up', 'A', 14], ['up', 'B', 14]]]Passed
macro-play scenario 5[[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]][[['down', 'A', 10], ['down', 'A', 11], ['up', 'A', 11]]]Passed
macro-play scenario 6[[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]][[['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12], ['up', 'B', 12]]]Passed
macro-play scenario 7[[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]][[['down', 'A', 10], ['up', 'A', 13], ['down', 'A', 15], ['up', 'A', 18]]]Passed
macro-play scenario 8[[]][[]]Passed

SHA-256 / e98c652512720bf6ad76c0d28a67659954e8bf958fa9ff26aa3ec79247e9df5c

Verification & scope

Offline stipulated event model, not a browser implementation or web standard conformance claim. 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:42:03.923345+00:00.

Case digest / 905c22b154b96e2a10f7e9cb46d2a12188a4cd291ab1dbcb99a7b452cdd18eb4