FA-31061 / Keyboard interactions / Open access
Owned repeat deadline scheduler: Window blur leaves per-key repeat deadlines running · case 01
The event trace violates the blur cancel rule and produces incorrect keyboard state or command output.
ROOT CAUSE
Window blur leaves per-key repeat deadlines running.
VERIFIED REPAIR
Use the contract transition `next_due.clear()` at the blur cancel fault site; preserve the other state transitions.
Unsuccessful approach: The partial repair changes this transition to next_due.pop(key,None), which still violates the model contract on the explicit regression traces.
Case contract
Case [delay,period,events], events [kind,key,time]. First down per key emits immediately and schedules first repeat at time+delay. Tick drains every deadline at or before time, ordered by deadline then key. Up removes only that key, blur clears all. Return emissions [key,time] and sorted pending deadlines. Positive delay and period; times nondecreasing. 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):
delay,period,events=c
next_due={}; output=[]
for kind,key,now in events:
if kind=='down' and key not in next_due:
output.append([key,now])
next_due[key]=now+delay
elif kind=='up':
next_due.pop(key,None)
elif kind=='blur':
pass
elif kind=='tick':
ready=sorted((t,k) for k,t in next_due.items() if t<=now)
while ready:
due,k=ready[0]
output.append([k,due])
next_due[k]=due+period
ready=sorted((t,k) for k,t in next_due.items() if t<=now)
return [output,sorted([[k,v] for k,v in next_due.items()])]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('repeat-clock scenario 0', solve([[5, 2, []]] * N), [[[], []]] * N)
check('repeat-clock scenario 1', solve([[5, 2, [['down', 'A', 10], ['tick', '', 15]]]] * N), [[[['A', 10], ['A', 15]], [['A', 17]]]] * N)
check('repeat-clock scenario 2', solve([[5, 2, [['down', 'A', 10], ['down', 'A', 12], ['tick', '', 17]]]] * N), [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] * N)
check('repeat-clock scenario 3', solve([[5, 2, [['down', 'Z', 0], ['down', 'A', 1], ['tick', '', 10]]]] * N), [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] * N)
check('repeat-clock scenario 4', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 1], ['up', 'A', 2], ['tick', '', 9]]]] * N), [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] * N)
check('repeat-clock scenario 5', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 1], ['blur', '', 3], ['tick', '', 10]]]] * N), [[[['A', 0], ['B', 1]], []]] * N)
check('repeat-clock scenario 6', solve([[5, 2, [['down', 'A', 0], ['tick', '', 12]]]] * N), [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] * N)
check('repeat-clock scenario 7', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 0], ['tick', '', 5]]]] * N), [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] * 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| repeat-clock scenario 0 | [[[], []]] | [[[], []]] | Passed |
| repeat-clock scenario 1 | [[[['A', 10], ['A', 15]], [['A', 17]]]] | [[[['A', 10], ['A', 15]], [['A', 17]]]] | Passed |
| repeat-clock scenario 2 | [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] | [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] | Passed |
| repeat-clock scenario 3 | [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] | [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] | Passed |
| repeat-clock scenario 4 | [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] | [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] | Passed |
| repeat-clock scenario 5 | [[[['A', 0], ['B', 1], ['A', 5], ['B', 6], ['A', 7], ['B', 8], ['A', 9], ['B', 10]], [['A', 11], ['B', 12]]]] | [[[['A', 0], ['B', 1]], []]] | Failed |
| repeat-clock scenario 6 | [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] | [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] | Passed |
| repeat-clock scenario 7 | [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] | [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] | Passed |
SHA-256 / dc1a9d78dbd1ad99930ae39bf9fd9883a5f77c31a94922c7187e2d6de2a5a9b9
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):
delay,period,events=c
next_due={}; output=[]
for kind,key,now in events:
if kind=='down' and key not in next_due:
output.append([key,now])
next_due[key]=now+delay
elif kind=='up':
next_due.pop(key,None)
elif kind=='blur':
next_due.pop(key,None)
elif kind=='tick':
ready=sorted((t,k) for k,t in next_due.items() if t<=now)
while ready:
due,k=ready[0]
output.append([k,due])
next_due[k]=due+period
ready=sorted((t,k) for k,t in next_due.items() if t<=now)
return [output,sorted([[k,v] for k,v in next_due.items()])]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('repeat-clock scenario 0', solve([[5, 2, []]] * N), [[[], []]] * N)
check('repeat-clock scenario 1', solve([[5, 2, [['down', 'A', 10], ['tick', '', 15]]]] * N), [[[['A', 10], ['A', 15]], [['A', 17]]]] * N)
check('repeat-clock scenario 2', solve([[5, 2, [['down', 'A', 10], ['down', 'A', 12], ['tick', '', 17]]]] * N), [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] * N)
check('repeat-clock scenario 3', solve([[5, 2, [['down', 'Z', 0], ['down', 'A', 1], ['tick', '', 10]]]] * N), [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] * N)
check('repeat-clock scenario 4', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 1], ['up', 'A', 2], ['tick', '', 9]]]] * N), [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] * N)
check('repeat-clock scenario 5', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 1], ['blur', '', 3], ['tick', '', 10]]]] * N), [[[['A', 0], ['B', 1]], []]] * N)
check('repeat-clock scenario 6', solve([[5, 2, [['down', 'A', 0], ['tick', '', 12]]]] * N), [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] * N)
check('repeat-clock scenario 7', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 0], ['tick', '', 5]]]] * N), [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] * 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| repeat-clock scenario 0 | [[[], []]] | [[[], []]] | Passed |
| repeat-clock scenario 1 | [[[['A', 10], ['A', 15]], [['A', 17]]]] | [[[['A', 10], ['A', 15]], [['A', 17]]]] | Passed |
| repeat-clock scenario 2 | [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] | [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] | Passed |
| repeat-clock scenario 3 | [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] | [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] | Passed |
| repeat-clock scenario 4 | [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] | [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] | Passed |
| repeat-clock scenario 5 | [[[['A', 0], ['B', 1], ['A', 5], ['B', 6], ['A', 7], ['B', 8], ['A', 9], ['B', 10]], [['A', 11], ['B', 12]]]] | [[[['A', 0], ['B', 1]], []]] | Failed |
| repeat-clock scenario 6 | [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] | [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] | Passed |
| repeat-clock scenario 7 | [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] | [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] | Passed |
SHA-256 / db5dffaaa08c3e183e264b2541fb7d75da7adfe156707e0eb769f0cc026162e4
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):
delay,period,events=c
next_due={}; output=[]
for kind,key,now in events:
if kind=='down' and key not in next_due:
output.append([key,now])
next_due[key]=now+delay
elif kind=='up':
next_due.pop(key,None)
elif kind=='blur':
next_due.clear()
elif kind=='tick':
ready=sorted((t,k) for k,t in next_due.items() if t<=now)
while ready:
due,k=ready[0]
output.append([k,due])
next_due[k]=due+period
ready=sorted((t,k) for k,t in next_due.items() if t<=now)
return [output,sorted([[k,v] for k,v in next_due.items()])]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('repeat-clock scenario 0', solve([[5, 2, []]] * N), [[[], []]] * N)
check('repeat-clock scenario 1', solve([[5, 2, [['down', 'A', 10], ['tick', '', 15]]]] * N), [[[['A', 10], ['A', 15]], [['A', 17]]]] * N)
check('repeat-clock scenario 2', solve([[5, 2, [['down', 'A', 10], ['down', 'A', 12], ['tick', '', 17]]]] * N), [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] * N)
check('repeat-clock scenario 3', solve([[5, 2, [['down', 'Z', 0], ['down', 'A', 1], ['tick', '', 10]]]] * N), [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] * N)
check('repeat-clock scenario 4', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 1], ['up', 'A', 2], ['tick', '', 9]]]] * N), [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] * N)
check('repeat-clock scenario 5', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 1], ['blur', '', 3], ['tick', '', 10]]]] * N), [[[['A', 0], ['B', 1]], []]] * N)
check('repeat-clock scenario 6', solve([[5, 2, [['down', 'A', 0], ['tick', '', 12]]]] * N), [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] * N)
check('repeat-clock scenario 7', solve([[5, 2, [['down', 'A', 0], ['down', 'B', 0], ['tick', '', 5]]]] * N), [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] * 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| repeat-clock scenario 0 | [[[], []]] | [[[], []]] | Passed |
| repeat-clock scenario 1 | [[[['A', 10], ['A', 15]], [['A', 17]]]] | [[[['A', 10], ['A', 15]], [['A', 17]]]] | Passed |
| repeat-clock scenario 2 | [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] | [[[['A', 10], ['A', 15], ['A', 17]], [['A', 19]]]] | Passed |
| repeat-clock scenario 3 | [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] | [[[['Z', 0], ['A', 1], ['Z', 5], ['A', 6], ['Z', 7], ['A', 8], ['Z', 9], ['A', 10]], [['A', 12], ['Z', 11]]]] | Passed |
| repeat-clock scenario 4 | [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] | [[[['A', 0], ['B', 1], ['B', 6], ['B', 8]], [['B', 10]]]] | Passed |
| repeat-clock scenario 5 | [[[['A', 0], ['B', 1]], []]] | [[[['A', 0], ['B', 1]], []]] | Passed |
| repeat-clock scenario 6 | [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] | [[[['A', 0], ['A', 5], ['A', 7], ['A', 9], ['A', 11]], [['A', 13]]]] | Passed |
| repeat-clock scenario 7 | [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] | [[[['A', 0], ['B', 0], ['A', 5], ['B', 5]], [['A', 7], ['B', 7]]]] | Passed |
SHA-256 / 918e78dde2188835289176e5100f5ef0368da2c6990bf43874e92fc713ff776c
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:41:58.588349+00:00.
Case digest / 1aae535ffd6f152203d3ebcfd3394c92685e21677601fbca3cec6405a247a96f