FAILURE MAP
← Case archive

FA-31736 / Keyboard interactions / Open access

Adjacent keyboard repeat batch coalescing: The final repeat batch is not emitted with its required entry type · case 01

The event trace violates the final flush rule and produces incorrect keyboard state or command output.

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

ROOT CAUSE

The final repeat batch is not emitted with its required entry type.

VERIFIED REPAIR

Use the contract transition `if batch is not None: out.append(['repeat']+batch) return` at the final flush fault site; preserve the other state transitions.

Unsuccessful approach: The partial repair changes this transition to if batch is not None: out.append(['raw']+batch) return, which still violates the model contract on the explicit regression traces.

Case contract

Events [kind,device,code,time,repeat]. Consecutive repeated down events for the same device/code coalesce into [device,code,first,last,count]; any nonrepeat or non-down event flushes the batch and is emitted as a raw event. A repeated down for a different token flushes and starts another. Return ordered entries tagged repeat or raw. 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):
        out=[]; batch=None
        for kind,device,code,now,repeat in c:
            eligible=kind=='down' and repeat
            if eligible:
                if batch is not None and batch[0]==device and batch[1]==code:
                    batch[3]=now
                    batch[4]+=1
                else:
                    if batch is not None: out.append(['repeat']+batch)
                    batch=[device,code,now,now,1]
            else:
                if batch is not None:
                    out.append(['repeat']+batch)
                    batch=None
                out.append(['raw',kind,device,code,now])
        if batch is not None: pass
        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('repeat-coalescing scenario 0', solve([[]] * N), [[]] * N)
check('repeat-coalescing scenario 1', solve([[['down', 'a', 'A', 10, False]]] * N), [[['raw', 'down', 'a', 'A', 10]]] * N)
check('repeat-coalescing scenario 2', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'A', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 12, 2]]] * N)
check('repeat-coalescing scenario 3', solve([[['down', 'a', 'A', 10, True], ['down', 'b', 'A', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'b', 'A', 12, 12, 1]]] * N)
check('repeat-coalescing scenario 4', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'B', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'a', 'B', 12, 12, 1]]] * N)
check('repeat-coalescing scenario 5', solve([[['down', 'a', 'A', 10, True], ['up', 'a', 'A', 12, False], ['down', 'a', 'A', 14, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]] * N)
check('repeat-coalescing scenario 6', solve([[['up', 'a', 'A', 10, True]]] * N), [[['raw', 'up', 'a', 'A', 10]]] * N)
check('repeat-coalescing scenario 7', solve([[['down', 'a', 'A', 10, True], ['text', 'a', 'A', 12, False]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]] * N)
check('repeat-coalescing scenario 8', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'A', 12, False], ['down', 'a', 'A', 14, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]] * 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
repeat-coalescing scenario 0[[]][[]]Passed
repeat-coalescing scenario 1[[['raw', 'down', 'a', 'A', 10]]][[['raw', 'down', 'a', 'A', 10]]]Passed
repeat-coalescing scenario 2[[]][[['repeat', 'a', 'A', 10, 12, 2]]]Failed
repeat-coalescing scenario 3[[['repeat', 'a', 'A', 10, 10, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'b', 'A', 12, 12, 1]]]Failed
repeat-coalescing scenario 4[[['repeat', 'a', 'A', 10, 10, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'a', 'B', 12, 12, 1]]]Failed
repeat-coalescing scenario 5[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]]Failed
repeat-coalescing scenario 6[[['raw', 'up', 'a', 'A', 10]]][[['raw', 'up', 'a', 'A', 10]]]Passed
repeat-coalescing scenario 7[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]]Passed
repeat-coalescing scenario 8[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]]Failed

SHA-256 / e70ffc5985fd869c93dd6a2f83ff2047285c6401cbea5a5880417be73323814b

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):
        out=[]; batch=None
        for kind,device,code,now,repeat in c:
            eligible=kind=='down' and repeat
            if eligible:
                if batch is not None and batch[0]==device and batch[1]==code:
                    batch[3]=now
                    batch[4]+=1
                else:
                    if batch is not None: out.append(['repeat']+batch)
                    batch=[device,code,now,now,1]
            else:
                if batch is not None:
                    out.append(['repeat']+batch)
                    batch=None
                out.append(['raw',kind,device,code,now])
        if batch is not None: out.append(['raw']+batch)
        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('repeat-coalescing scenario 0', solve([[]] * N), [[]] * N)
check('repeat-coalescing scenario 1', solve([[['down', 'a', 'A', 10, False]]] * N), [[['raw', 'down', 'a', 'A', 10]]] * N)
check('repeat-coalescing scenario 2', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'A', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 12, 2]]] * N)
check('repeat-coalescing scenario 3', solve([[['down', 'a', 'A', 10, True], ['down', 'b', 'A', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'b', 'A', 12, 12, 1]]] * N)
check('repeat-coalescing scenario 4', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'B', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'a', 'B', 12, 12, 1]]] * N)
check('repeat-coalescing scenario 5', solve([[['down', 'a', 'A', 10, True], ['up', 'a', 'A', 12, False], ['down', 'a', 'A', 14, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]] * N)
check('repeat-coalescing scenario 6', solve([[['up', 'a', 'A', 10, True]]] * N), [[['raw', 'up', 'a', 'A', 10]]] * N)
check('repeat-coalescing scenario 7', solve([[['down', 'a', 'A', 10, True], ['text', 'a', 'A', 12, False]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]] * N)
check('repeat-coalescing scenario 8', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'A', 12, False], ['down', 'a', 'A', 14, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]] * 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
repeat-coalescing scenario 0[[]][[]]Passed
repeat-coalescing scenario 1[[['raw', 'down', 'a', 'A', 10]]][[['raw', 'down', 'a', 'A', 10]]]Passed
repeat-coalescing scenario 2[[['raw', 'a', 'A', 10, 12, 2]]][[['repeat', 'a', 'A', 10, 12, 2]]]Failed
repeat-coalescing scenario 3[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'b', 'A', 12, 12, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'b', 'A', 12, 12, 1]]]Failed
repeat-coalescing scenario 4[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'a', 'B', 12, 12, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'a', 'B', 12, 12, 1]]]Failed
repeat-coalescing scenario 5[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['raw', 'a', 'A', 14, 14, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]]Failed
repeat-coalescing scenario 6[[['raw', 'up', 'a', 'A', 10]]][[['raw', 'up', 'a', 'A', 10]]]Passed
repeat-coalescing scenario 7[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]]Passed
repeat-coalescing scenario 8[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['raw', 'a', 'A', 14, 14, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]]Failed

SHA-256 / 3584e81f50219a2726de2a6f21a2ec1995652048a45eb7ff5b0f94f439f2e355

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):
        out=[]; batch=None
        for kind,device,code,now,repeat in c:
            eligible=kind=='down' and repeat
            if eligible:
                if batch is not None and batch[0]==device and batch[1]==code:
                    batch[3]=now
                    batch[4]+=1
                else:
                    if batch is not None: out.append(['repeat']+batch)
                    batch=[device,code,now,now,1]
            else:
                if batch is not None:
                    out.append(['repeat']+batch)
                    batch=None
                out.append(['raw',kind,device,code,now])
        if batch is not None: out.append(['repeat']+batch)
        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('repeat-coalescing scenario 0', solve([[]] * N), [[]] * N)
check('repeat-coalescing scenario 1', solve([[['down', 'a', 'A', 10, False]]] * N), [[['raw', 'down', 'a', 'A', 10]]] * N)
check('repeat-coalescing scenario 2', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'A', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 12, 2]]] * N)
check('repeat-coalescing scenario 3', solve([[['down', 'a', 'A', 10, True], ['down', 'b', 'A', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'b', 'A', 12, 12, 1]]] * N)
check('repeat-coalescing scenario 4', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'B', 12, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'a', 'B', 12, 12, 1]]] * N)
check('repeat-coalescing scenario 5', solve([[['down', 'a', 'A', 10, True], ['up', 'a', 'A', 12, False], ['down', 'a', 'A', 14, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]] * N)
check('repeat-coalescing scenario 6', solve([[['up', 'a', 'A', 10, True]]] * N), [[['raw', 'up', 'a', 'A', 10]]] * N)
check('repeat-coalescing scenario 7', solve([[['down', 'a', 'A', 10, True], ['text', 'a', 'A', 12, False]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]] * N)
check('repeat-coalescing scenario 8', solve([[['down', 'a', 'A', 10, True], ['down', 'a', 'A', 12, False], ['down', 'a', 'A', 14, True]]] * N), [[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]] * 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
repeat-coalescing scenario 0[[]][[]]Passed
repeat-coalescing scenario 1[[['raw', 'down', 'a', 'A', 10]]][[['raw', 'down', 'a', 'A', 10]]]Passed
repeat-coalescing scenario 2[[['repeat', 'a', 'A', 10, 12, 2]]][[['repeat', 'a', 'A', 10, 12, 2]]]Passed
repeat-coalescing scenario 3[[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'b', 'A', 12, 12, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'b', 'A', 12, 12, 1]]]Passed
repeat-coalescing scenario 4[[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'a', 'B', 12, 12, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['repeat', 'a', 'B', 12, 12, 1]]]Passed
repeat-coalescing scenario 5[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'up', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]]Passed
repeat-coalescing scenario 6[[['raw', 'up', 'a', 'A', 10]]][[['raw', 'up', 'a', 'A', 10]]]Passed
repeat-coalescing scenario 7[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'text', 'a', 'A', 12]]]Passed
repeat-coalescing scenario 8[[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]][[['repeat', 'a', 'A', 10, 10, 1], ['raw', 'down', 'a', 'A', 12], ['repeat', 'a', 'A', 14, 14, 1]]]Passed

SHA-256 / f87e5892d5f30c2cf4572ebc9d0b187087480175a0e6084fce3466c98404e4ca

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:05.057461+00:00.

Case digest / 7af8dcf90e3c53997d2d598f9aa91a5c263c8e36071b6afeb80c79c9575554f9