FA-31941 / Keyboard interactions / Open access
Multi-tap keyboard character commit timing: A press at the keypad commit deadline cycles the expired character or uses absolute time · case 01
The event trace violates the press expiry rule and produces incorrect keyboard state or command output.
ROOT CAUSE
A press at the keypad commit deadline cycles the expired character or uses absolute time.
VERIFIED REPAIR
Use the contract transition `now>=pending[2]: text` at the press expiry fault site; preserve the other state transitions.
Unsuccessful approach: The partial repair changes this transition to now>=window: text, which still violates the model contract on the explicit regression traces.
Case contract
Case [map,window,events]. Map maps keys to nonempty character strings. Events [kind,value,time]. Valid press cycles the pending same-key character before deadline, otherwise commits previous and starts new. Tick at or past deadline commits. Backspace cancels pending character before deleting committed text. Space commits pending then adds space; cancel drops pending only. Unknown press is ignored. Return committed text and pending [key,index,deadline] or None. 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):
mapping,window,events=c
text=''; pending=None
for kind,value,now in events:
if kind=='press' and value in mapping:
if pending is not None and now>pending[2]:
text+=mapping[pending[0]][pending[1]]; pending=None
if pending is not None and pending[0]==value:
pending[1]=(pending[1]+1)%len(mapping[value])
pending[2]=now+window
else:
if pending is not None: text+=mapping[pending[0]][pending[1]]
pending=[value,0,now+window]
elif kind=='tick' and pending is not None and now>=pending[2]:
text+=mapping[pending[0]][pending[1]]; pending=None
elif kind=='backspace':
if pending is not None: pending=None
else: text=text[:-1]
elif kind=='space':
if pending is not None: text+=mapping[pending[0]][pending[1]]
pending=None; text+=' '
elif kind=='cancel': pending=None
return [text,pending]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('multi-tap-keypad scenario 0', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 11]]]] * N), [['', ['2', 1, 16]]] * N)
check('multi-tap-keypad scenario 1', solve([[{'2': 'abc', '3': 'de'}, 5, []]] * N), [['', None]] * N)
check('multi-tap-keypad scenario 2', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 11], ['press', '2', 12], ['press', '2', 13], ['tick', '', 18]]]] * N), [['a', None]] * N)
check('multi-tap-keypad scenario 3', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 15]]]] * N), [['a', ['2', 0, 20]]] * N)
check('multi-tap-keypad scenario 4', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '3', 12], ['tick', '', 17]]]] * N), [['ad', None]] * N)
check('multi-tap-keypad scenario 5', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['tick', '', 12]]]] * N), [['', ['2', 0, 15]]] * N)
check('multi-tap-keypad scenario 6', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['tick', '', 15], ['press', '3', 16], ['backspace', '', 17]]]] * N), [['a', None]] * N)
check('multi-tap-keypad scenario 7', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '3', 11], ['space', '', 12], ['backspace', '', 13]]]] * N), [['ad', None]] * N)
check('multi-tap-keypad scenario 8', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['space', '', 12]]]] * N), [['a ', None]] * N)
check('multi-tap-keypad scenario 9', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '?', 10], ['backspace', '', 11]]]] * N), [['', None]] * 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 |
|---|---|---|---|
| multi-tap-keypad scenario 0 | [['', ['2', 1, 16]]] | [['', ['2', 1, 16]]] | Passed |
| multi-tap-keypad scenario 1 | [['', None]] | [['', None]] | Passed |
| multi-tap-keypad scenario 2 | [['a', None]] | [['a', None]] | Passed |
| multi-tap-keypad scenario 3 | [['', ['2', 1, 20]]] | [['a', ['2', 0, 20]]] | Failed |
| multi-tap-keypad scenario 4 | [['ad', None]] | [['ad', None]] | Passed |
| multi-tap-keypad scenario 5 | [['', ['2', 0, 15]]] | [['', ['2', 0, 15]]] | Passed |
| multi-tap-keypad scenario 6 | [['a', None]] | [['a', None]] | Passed |
| multi-tap-keypad scenario 7 | [['ad', None]] | [['ad', None]] | Passed |
| multi-tap-keypad scenario 8 | [['a ', None]] | [['a ', None]] | Passed |
| multi-tap-keypad scenario 9 | [['', None]] | [['', None]] | Passed |
SHA-256 / 373f5e846733c24b34ef26299e5d2be79965694f67ebe5edcc1018a4e18461b0
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):
mapping,window,events=c
text=''; pending=None
for kind,value,now in events:
if kind=='press' and value in mapping:
if pending is not None and now>=window:
text+=mapping[pending[0]][pending[1]]; pending=None
if pending is not None and pending[0]==value:
pending[1]=(pending[1]+1)%len(mapping[value])
pending[2]=now+window
else:
if pending is not None: text+=mapping[pending[0]][pending[1]]
pending=[value,0,now+window]
elif kind=='tick' and pending is not None and now>=pending[2]:
text+=mapping[pending[0]][pending[1]]; pending=None
elif kind=='backspace':
if pending is not None: pending=None
else: text=text[:-1]
elif kind=='space':
if pending is not None: text+=mapping[pending[0]][pending[1]]
pending=None; text+=' '
elif kind=='cancel': pending=None
return [text,pending]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('multi-tap-keypad scenario 0', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 11]]]] * N), [['', ['2', 1, 16]]] * N)
check('multi-tap-keypad scenario 1', solve([[{'2': 'abc', '3': 'de'}, 5, []]] * N), [['', None]] * N)
check('multi-tap-keypad scenario 2', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 11], ['press', '2', 12], ['press', '2', 13], ['tick', '', 18]]]] * N), [['a', None]] * N)
check('multi-tap-keypad scenario 3', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 15]]]] * N), [['a', ['2', 0, 20]]] * N)
check('multi-tap-keypad scenario 4', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '3', 12], ['tick', '', 17]]]] * N), [['ad', None]] * N)
check('multi-tap-keypad scenario 5', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['tick', '', 12]]]] * N), [['', ['2', 0, 15]]] * N)
check('multi-tap-keypad scenario 6', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['tick', '', 15], ['press', '3', 16], ['backspace', '', 17]]]] * N), [['a', None]] * N)
check('multi-tap-keypad scenario 7', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '3', 11], ['space', '', 12], ['backspace', '', 13]]]] * N), [['ad', None]] * N)
check('multi-tap-keypad scenario 8', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['space', '', 12]]]] * N), [['a ', None]] * N)
check('multi-tap-keypad scenario 9', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '?', 10], ['backspace', '', 11]]]] * N), [['', None]] * 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 |
|---|---|---|---|
| multi-tap-keypad scenario 0 | [['a', ['2', 0, 16]]] | [['', ['2', 1, 16]]] | Failed |
| multi-tap-keypad scenario 1 | [['', None]] | [['', None]] | Passed |
| multi-tap-keypad scenario 2 | [['aaaa', None]] | [['a', None]] | Failed |
| multi-tap-keypad scenario 3 | [['a', ['2', 0, 20]]] | [['a', ['2', 0, 20]]] | Passed |
| multi-tap-keypad scenario 4 | [['ad', None]] | [['ad', None]] | Passed |
| multi-tap-keypad scenario 5 | [['', ['2', 0, 15]]] | [['', ['2', 0, 15]]] | Passed |
| multi-tap-keypad scenario 6 | [['a', None]] | [['a', None]] | Passed |
| multi-tap-keypad scenario 7 | [['ad', None]] | [['ad', None]] | Passed |
| multi-tap-keypad scenario 8 | [['a ', None]] | [['a ', None]] | Passed |
| multi-tap-keypad scenario 9 | [['', None]] | [['', None]] | Passed |
SHA-256 / 8ecae75b6e7c2b10cf20a26f7ef618f2305d62c09a7a25c32ff17e7906ebb4f3
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):
mapping,window,events=c
text=''; pending=None
for kind,value,now in events:
if kind=='press' and value in mapping:
if pending is not None and now>=pending[2]:
text+=mapping[pending[0]][pending[1]]; pending=None
if pending is not None and pending[0]==value:
pending[1]=(pending[1]+1)%len(mapping[value])
pending[2]=now+window
else:
if pending is not None: text+=mapping[pending[0]][pending[1]]
pending=[value,0,now+window]
elif kind=='tick' and pending is not None and now>=pending[2]:
text+=mapping[pending[0]][pending[1]]; pending=None
elif kind=='backspace':
if pending is not None: pending=None
else: text=text[:-1]
elif kind=='space':
if pending is not None: text+=mapping[pending[0]][pending[1]]
pending=None; text+=' '
elif kind=='cancel': pending=None
return [text,pending]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('multi-tap-keypad scenario 0', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 11]]]] * N), [['', ['2', 1, 16]]] * N)
check('multi-tap-keypad scenario 1', solve([[{'2': 'abc', '3': 'de'}, 5, []]] * N), [['', None]] * N)
check('multi-tap-keypad scenario 2', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 11], ['press', '2', 12], ['press', '2', 13], ['tick', '', 18]]]] * N), [['a', None]] * N)
check('multi-tap-keypad scenario 3', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '2', 15]]]] * N), [['a', ['2', 0, 20]]] * N)
check('multi-tap-keypad scenario 4', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '3', 12], ['tick', '', 17]]]] * N), [['ad', None]] * N)
check('multi-tap-keypad scenario 5', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['tick', '', 12]]]] * N), [['', ['2', 0, 15]]] * N)
check('multi-tap-keypad scenario 6', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['tick', '', 15], ['press', '3', 16], ['backspace', '', 17]]]] * N), [['a', None]] * N)
check('multi-tap-keypad scenario 7', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['press', '3', 11], ['space', '', 12], ['backspace', '', 13]]]] * N), [['ad', None]] * N)
check('multi-tap-keypad scenario 8', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '2', 10], ['space', '', 12]]]] * N), [['a ', None]] * N)
check('multi-tap-keypad scenario 9', solve([[{'2': 'abc', '3': 'de'}, 5, [['press', '?', 10], ['backspace', '', 11]]]] * N), [['', None]] * 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 |
|---|---|---|---|
| multi-tap-keypad scenario 0 | [['', ['2', 1, 16]]] | [['', ['2', 1, 16]]] | Passed |
| multi-tap-keypad scenario 1 | [['', None]] | [['', None]] | Passed |
| multi-tap-keypad scenario 2 | [['a', None]] | [['a', None]] | Passed |
| multi-tap-keypad scenario 3 | [['a', ['2', 0, 20]]] | [['a', ['2', 0, 20]]] | Passed |
| multi-tap-keypad scenario 4 | [['ad', None]] | [['ad', None]] | Passed |
| multi-tap-keypad scenario 5 | [['', ['2', 0, 15]]] | [['', ['2', 0, 15]]] | Passed |
| multi-tap-keypad scenario 6 | [['a', None]] | [['a', None]] | Passed |
| multi-tap-keypad scenario 7 | [['ad', None]] | [['ad', None]] | Passed |
| multi-tap-keypad scenario 8 | [['a ', None]] | [['a ', None]] | Passed |
| multi-tap-keypad scenario 9 | [['', None]] | [['', None]] | Passed |
SHA-256 / c49828b5f5b1fdde51b61f28e886a77027aacc96eaa33b82489764363e23d433
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:07.122572+00:00.
Case digest / 868a4327f2cc260d2e9a095a7809289311d3e2403bae523b33ae2318e52664f0