FA-31131 / Keyboard interactions / Open access
Tap versus hold command arbitration: Release clears other presses or retains a completed key · case 01
The event trace violates the release disarm rule and produces incorrect keyboard state or command output.
ROOT CAUSE
Release clears other presses or retains a completed key.
VERIFIED REPAIR
Use the contract transition `del pending[key]` at the release disarm fault site; preserve the other state transitions.
Unsuccessful approach: The partial repair changes this transition to pending[key][1]=True, which still violates the model contract on the explicit regression traces.
Case contract
Case [threshold,events]. Events [kind,key,time]. Down arms an unarmed key. Tick emits hold once when age >= threshold. Up before threshold emits tap, at or after threshold emits hold if not yet emitted. Cancel removes just one key silently. Return output and pending [key,start,held] entries. 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):
threshold,events=c
pending={}; output=[]
for kind,key,now in events:
if kind=='down' and key not in pending:
pending[key]=[now,False]
elif kind=='tick':
for k in sorted(pending):
start,sent=pending[k]
if not sent and now-start>=threshold:
output.append(['hold',k])
pending[k][1]=True
elif kind=='up' and key in pending:
start,sent=pending[key]
if not sent:
output.append(['hold' if now-start>=threshold else 'tap',key])
pending.clear()
elif kind=='cancel':
pending.pop(key,None)
return [output,sorted([[k]+v for k,v in pending.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('hold-threshold scenario 0', solve([[5, []]] * N), [[[], []]] * N)
check('hold-threshold scenario 1', solve([[5, [['down', 'A', 10], ['tick', '', 12]]]] * N), [[[], [['A', 10, False]]]] * N)
check('hold-threshold scenario 2', solve([[5, [['down', 'A', 10], ['up', 'A', 12]]]] * N), [[[['tap', 'A']], []]] * N)
check('hold-threshold scenario 3', solve([[5, [['down', 'A', 10], ['up', 'A', 15]]]] * N), [[[['hold', 'A']], []]] * N)
check('hold-threshold scenario 4', solve([[5, [['down', 'A', 10], ['tick', '', 15], ['tick', '', 16], ['up', 'A', 17]]]] * N), [[[['hold', 'A']], []]] * N)
check('hold-threshold scenario 5', solve([[5, [['down', 'A', 10], ['down', 'A', 13], ['tick', '', 15]]]] * N), [[[['hold', 'A']], [['A', 10, True]]]] * N)
check('hold-threshold scenario 6', solve([[5, [['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12]]]] * N), [[[['tap', 'A']], [['B', 11, False]]]] * N)
check('hold-threshold scenario 7', solve([[5, [['down', 'A', 10], ['down', 'B', 11], ['cancel', 'A', 12], ['tick', '', 16]]]] * N), [[[['hold', 'B']], [['B', 11, True]]]] * N)
check('hold-threshold scenario 8', solve([[5, [['up', 'A', 100]]]] * 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| hold-threshold scenario 0 | [[[], []]] | [[[], []]] | Passed |
| hold-threshold scenario 1 | [[[], [['A', 10, False]]]] | [[[], [['A', 10, False]]]] | Passed |
| hold-threshold scenario 2 | [[[['tap', 'A']], []]] | [[[['tap', 'A']], []]] | Passed |
| hold-threshold scenario 3 | [[[['hold', 'A']], []]] | [[[['hold', 'A']], []]] | Passed |
| hold-threshold scenario 4 | [[[['hold', 'A']], []]] | [[[['hold', 'A']], []]] | Passed |
| hold-threshold scenario 5 | [[[['hold', 'A']], [['A', 10, True]]]] | [[[['hold', 'A']], [['A', 10, True]]]] | Passed |
| hold-threshold scenario 6 | [[[['tap', 'A']], []]] | [[[['tap', 'A']], [['B', 11, False]]]] | Failed |
| hold-threshold scenario 7 | [[[['hold', 'B']], [['B', 11, True]]]] | [[[['hold', 'B']], [['B', 11, True]]]] | Passed |
| hold-threshold scenario 8 | [[[], []]] | [[[], []]] | Passed |
SHA-256 / 9c1f2e7e95e16f5ff8bfd0ca4a48cfa38890340074f0e0e7ad6cab722e123921
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):
threshold,events=c
pending={}; output=[]
for kind,key,now in events:
if kind=='down' and key not in pending:
pending[key]=[now,False]
elif kind=='tick':
for k in sorted(pending):
start,sent=pending[k]
if not sent and now-start>=threshold:
output.append(['hold',k])
pending[k][1]=True
elif kind=='up' and key in pending:
start,sent=pending[key]
if not sent:
output.append(['hold' if now-start>=threshold else 'tap',key])
pending[key][1]=True
elif kind=='cancel':
pending.pop(key,None)
return [output,sorted([[k]+v for k,v in pending.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('hold-threshold scenario 0', solve([[5, []]] * N), [[[], []]] * N)
check('hold-threshold scenario 1', solve([[5, [['down', 'A', 10], ['tick', '', 12]]]] * N), [[[], [['A', 10, False]]]] * N)
check('hold-threshold scenario 2', solve([[5, [['down', 'A', 10], ['up', 'A', 12]]]] * N), [[[['tap', 'A']], []]] * N)
check('hold-threshold scenario 3', solve([[5, [['down', 'A', 10], ['up', 'A', 15]]]] * N), [[[['hold', 'A']], []]] * N)
check('hold-threshold scenario 4', solve([[5, [['down', 'A', 10], ['tick', '', 15], ['tick', '', 16], ['up', 'A', 17]]]] * N), [[[['hold', 'A']], []]] * N)
check('hold-threshold scenario 5', solve([[5, [['down', 'A', 10], ['down', 'A', 13], ['tick', '', 15]]]] * N), [[[['hold', 'A']], [['A', 10, True]]]] * N)
check('hold-threshold scenario 6', solve([[5, [['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12]]]] * N), [[[['tap', 'A']], [['B', 11, False]]]] * N)
check('hold-threshold scenario 7', solve([[5, [['down', 'A', 10], ['down', 'B', 11], ['cancel', 'A', 12], ['tick', '', 16]]]] * N), [[[['hold', 'B']], [['B', 11, True]]]] * N)
check('hold-threshold scenario 8', solve([[5, [['up', 'A', 100]]]] * 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| hold-threshold scenario 0 | [[[], []]] | [[[], []]] | Passed |
| hold-threshold scenario 1 | [[[], [['A', 10, False]]]] | [[[], [['A', 10, False]]]] | Passed |
| hold-threshold scenario 2 | [[[['tap', 'A']], [['A', 10, True]]]] | [[[['tap', 'A']], []]] | Failed |
| hold-threshold scenario 3 | [[[['hold', 'A']], [['A', 10, True]]]] | [[[['hold', 'A']], []]] | Failed |
| hold-threshold scenario 4 | [[[['hold', 'A']], [['A', 10, True]]]] | [[[['hold', 'A']], []]] | Failed |
| hold-threshold scenario 5 | [[[['hold', 'A']], [['A', 10, True]]]] | [[[['hold', 'A']], [['A', 10, True]]]] | Passed |
| hold-threshold scenario 6 | [[[['tap', 'A']], [['A', 10, True], ['B', 11, False]]]] | [[[['tap', 'A']], [['B', 11, False]]]] | Failed |
| hold-threshold scenario 7 | [[[['hold', 'B']], [['B', 11, True]]]] | [[[['hold', 'B']], [['B', 11, True]]]] | Passed |
| hold-threshold scenario 8 | [[[], []]] | [[[], []]] | Passed |
SHA-256 / 04d6a33b554b53b4478c0d9d8116ec20c7a10d497f58cb8f5c61fe9870df863a
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):
threshold,events=c
pending={}; output=[]
for kind,key,now in events:
if kind=='down' and key not in pending:
pending[key]=[now,False]
elif kind=='tick':
for k in sorted(pending):
start,sent=pending[k]
if not sent and now-start>=threshold:
output.append(['hold',k])
pending[k][1]=True
elif kind=='up' and key in pending:
start,sent=pending[key]
if not sent:
output.append(['hold' if now-start>=threshold else 'tap',key])
del pending[key]
elif kind=='cancel':
pending.pop(key,None)
return [output,sorted([[k]+v for k,v in pending.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('hold-threshold scenario 0', solve([[5, []]] * N), [[[], []]] * N)
check('hold-threshold scenario 1', solve([[5, [['down', 'A', 10], ['tick', '', 12]]]] * N), [[[], [['A', 10, False]]]] * N)
check('hold-threshold scenario 2', solve([[5, [['down', 'A', 10], ['up', 'A', 12]]]] * N), [[[['tap', 'A']], []]] * N)
check('hold-threshold scenario 3', solve([[5, [['down', 'A', 10], ['up', 'A', 15]]]] * N), [[[['hold', 'A']], []]] * N)
check('hold-threshold scenario 4', solve([[5, [['down', 'A', 10], ['tick', '', 15], ['tick', '', 16], ['up', 'A', 17]]]] * N), [[[['hold', 'A']], []]] * N)
check('hold-threshold scenario 5', solve([[5, [['down', 'A', 10], ['down', 'A', 13], ['tick', '', 15]]]] * N), [[[['hold', 'A']], [['A', 10, True]]]] * N)
check('hold-threshold scenario 6', solve([[5, [['down', 'A', 10], ['down', 'B', 11], ['up', 'A', 12]]]] * N), [[[['tap', 'A']], [['B', 11, False]]]] * N)
check('hold-threshold scenario 7', solve([[5, [['down', 'A', 10], ['down', 'B', 11], ['cancel', 'A', 12], ['tick', '', 16]]]] * N), [[[['hold', 'B']], [['B', 11, True]]]] * N)
check('hold-threshold scenario 8', solve([[5, [['up', 'A', 100]]]] * 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| hold-threshold scenario 0 | [[[], []]] | [[[], []]] | Passed |
| hold-threshold scenario 1 | [[[], [['A', 10, False]]]] | [[[], [['A', 10, False]]]] | Passed |
| hold-threshold scenario 2 | [[[['tap', 'A']], []]] | [[[['tap', 'A']], []]] | Passed |
| hold-threshold scenario 3 | [[[['hold', 'A']], []]] | [[[['hold', 'A']], []]] | Passed |
| hold-threshold scenario 4 | [[[['hold', 'A']], []]] | [[[['hold', 'A']], []]] | Passed |
| hold-threshold scenario 5 | [[[['hold', 'A']], [['A', 10, True]]]] | [[[['hold', 'A']], [['A', 10, True]]]] | Passed |
| hold-threshold scenario 6 | [[[['tap', 'A']], [['B', 11, False]]]] | [[[['tap', 'A']], [['B', 11, False]]]] | Passed |
| hold-threshold scenario 7 | [[[['hold', 'B']], [['B', 11, True]]]] | [[[['hold', 'B']], [['B', 11, True]]]] | Passed |
| hold-threshold scenario 8 | [[[], []]] | [[[], []]] | Passed |
SHA-256 / 3559c584388395b9ad7f21e5c69727bd641bfedebef31b5afa7ed39ccfc09a19
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:59.226361+00:00.
Case digest / 3948f086e7fecee2e216b4fe57b1087edcbf6dc3978ec2ee90dad3964df4d149