FA-32086 / Keyboard interactions / Open access
Composition replacement against document revisions: A committed or rejected composition remains live for later duplicate submission · case 01
The event trace violates the close pending rule and produces incorrect keyboard state or command output.
ROOT CAUSE
A committed or rejected composition remains live for later duplicate submission.
VERIFIED REPAIR
Use the contract transition `pending=None elif kind=='cancel'` at the close pending fault site; preserve the other state transitions.
Unsuccessful approach: The partial repair changes this transition to pending=[lo,hi,revision,preedit] elif kind=='cancel', which still violates the model contract on the explicit regression traces.
Case contract
Case [document,revision,events]. Events [kind,a,b,text]. Begin captures valid range [a,b) and current revision with preedit text; update replaces pending preedit; external replaces entire document and increments revision. Commit applies pending replacement only if captured revision still equals current, otherwise counts stale conflict; either path closes pending. Cancel discards pending. Return document, revision, pending [lo,hi,base,text] or None, conflicts. 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):
document,revision,events=c
pending=None; conflicts=0
for kind,a,b,text in events:
if kind=='begin': pending=[a,b,revision,text]
elif kind=='update' and pending is not None: pending[3]=text
elif kind=='external': document=text; revision+=1
elif kind=='commit' and pending is not None:
lo,hi,base,preedit=pending
if base==revision:
document=document[:lo]+preedit+document[hi:]
revision+=1
else: conflicts+=1
pending=pending
elif kind=='cancel': pending=None
return [document,revision,pending,conflicts]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composition-revision scenario 0', solve([['abcd', 4, []]] * N), [['abcd', 4, None, 0]] * N)
check('composition-revision scenario 1', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['commit', 0, 0, '']]]] * N), [['aXd', 5, None, 0]] * N)
check('composition-revision scenario 2', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['update', 0, 0, 'YZ'], ['commit', 0, 0, '']]]] * N), [['aYZd', 5, None, 0]] * N)
check('composition-revision scenario 3', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['external', 0, 0, 'new'], ['commit', 0, 0, '']]]] * N), [['new', 5, None, 1]] * N)
check('composition-revision scenario 4', solve([['abcd', 4, [['external', 0, 0, 'one'], ['external', 0, 0, 'two']]]] * N), [['two', 6, None, 0]] * N)
check('composition-revision scenario 5', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['external', 0, 0, 'one'], ['external', 0, 0, 'two'], ['commit', 0, 0, ''], ['begin', 0, 1, 'Z'], ['external', 0, 0, 'three'], ['commit', 0, 0, '']]]] * N), [['three', 7, None, 2]] * N)
check('composition-revision scenario 6', solve([['abcd', 4, [['begin', 0, 0, ''], ['cancel', 0, 0, '']]]] * N), [['abcd', 4, None, 0]] * N)
check('composition-revision scenario 7', solve([['abcd', 0, [['begin', 1, 3, 'X'], ['commit', 0, 0, ''], ['commit', 0, 0, '']]]] * N), [['aXd', 1, None, 0]] * 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 |
|---|---|---|---|
| composition-revision scenario 0 | [['abcd', 4, None, 0]] | [['abcd', 4, None, 0]] | Passed |
| composition-revision scenario 1 | [['aXd', 5, [1, 3, 4, 'X'], 0]] | [['aXd', 5, None, 0]] | Failed |
| composition-revision scenario 2 | [['aYZd', 5, [1, 3, 4, 'YZ'], 0]] | [['aYZd', 5, None, 0]] | Failed |
| composition-revision scenario 3 | [['new', 5, [1, 3, 4, 'X'], 1]] | [['new', 5, None, 1]] | Failed |
| composition-revision scenario 4 | [['two', 6, None, 0]] | [['two', 6, None, 0]] | Passed |
| composition-revision scenario 5 | [['three', 7, [0, 1, 6, 'Z'], 2]] | [['three', 7, None, 2]] | Failed |
| composition-revision scenario 6 | [['abcd', 4, None, 0]] | [['abcd', 4, None, 0]] | Passed |
| composition-revision scenario 7 | [['aXd', 1, [1, 3, 0, 'X'], 1]] | [['aXd', 1, None, 0]] | Failed |
SHA-256 / ebffbff9de7029efc03bed4a187cc1bd7d5d9007a1b019ea7cf8143e5993e34d
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):
document,revision,events=c
pending=None; conflicts=0
for kind,a,b,text in events:
if kind=='begin': pending=[a,b,revision,text]
elif kind=='update' and pending is not None: pending[3]=text
elif kind=='external': document=text; revision+=1
elif kind=='commit' and pending is not None:
lo,hi,base,preedit=pending
if base==revision:
document=document[:lo]+preedit+document[hi:]
revision+=1
else: conflicts+=1
pending=[lo,hi,revision,preedit]
elif kind=='cancel': pending=None
return [document,revision,pending,conflicts]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composition-revision scenario 0', solve([['abcd', 4, []]] * N), [['abcd', 4, None, 0]] * N)
check('composition-revision scenario 1', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['commit', 0, 0, '']]]] * N), [['aXd', 5, None, 0]] * N)
check('composition-revision scenario 2', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['update', 0, 0, 'YZ'], ['commit', 0, 0, '']]]] * N), [['aYZd', 5, None, 0]] * N)
check('composition-revision scenario 3', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['external', 0, 0, 'new'], ['commit', 0, 0, '']]]] * N), [['new', 5, None, 1]] * N)
check('composition-revision scenario 4', solve([['abcd', 4, [['external', 0, 0, 'one'], ['external', 0, 0, 'two']]]] * N), [['two', 6, None, 0]] * N)
check('composition-revision scenario 5', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['external', 0, 0, 'one'], ['external', 0, 0, 'two'], ['commit', 0, 0, ''], ['begin', 0, 1, 'Z'], ['external', 0, 0, 'three'], ['commit', 0, 0, '']]]] * N), [['three', 7, None, 2]] * N)
check('composition-revision scenario 6', solve([['abcd', 4, [['begin', 0, 0, ''], ['cancel', 0, 0, '']]]] * N), [['abcd', 4, None, 0]] * N)
check('composition-revision scenario 7', solve([['abcd', 0, [['begin', 1, 3, 'X'], ['commit', 0, 0, ''], ['commit', 0, 0, '']]]] * N), [['aXd', 1, None, 0]] * 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 |
|---|---|---|---|
| composition-revision scenario 0 | [['abcd', 4, None, 0]] | [['abcd', 4, None, 0]] | Passed |
| composition-revision scenario 1 | [['aXd', 5, [1, 3, 5, 'X'], 0]] | [['aXd', 5, None, 0]] | Failed |
| composition-revision scenario 2 | [['aYZd', 5, [1, 3, 5, 'YZ'], 0]] | [['aYZd', 5, None, 0]] | Failed |
| composition-revision scenario 3 | [['new', 5, [1, 3, 5, 'X'], 1]] | [['new', 5, None, 1]] | Failed |
| composition-revision scenario 4 | [['two', 6, None, 0]] | [['two', 6, None, 0]] | Passed |
| composition-revision scenario 5 | [['three', 7, [0, 1, 7, 'Z'], 2]] | [['three', 7, None, 2]] | Failed |
| composition-revision scenario 6 | [['abcd', 4, None, 0]] | [['abcd', 4, None, 0]] | Passed |
| composition-revision scenario 7 | [['aX', 2, [1, 3, 2, 'X'], 0]] | [['aXd', 1, None, 0]] | Failed |
SHA-256 / 064767f297359b0fa5f26675d7901d5c53eec8839e9a038abcd5dd5543d1ca88
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):
document,revision,events=c
pending=None; conflicts=0
for kind,a,b,text in events:
if kind=='begin': pending=[a,b,revision,text]
elif kind=='update' and pending is not None: pending[3]=text
elif kind=='external': document=text; revision+=1
elif kind=='commit' and pending is not None:
lo,hi,base,preedit=pending
if base==revision:
document=document[:lo]+preedit+document[hi:]
revision+=1
else: conflicts+=1
pending=None
elif kind=='cancel': pending=None
return [document,revision,pending,conflicts]
return [run(c) for c in cases]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composition-revision scenario 0', solve([['abcd', 4, []]] * N), [['abcd', 4, None, 0]] * N)
check('composition-revision scenario 1', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['commit', 0, 0, '']]]] * N), [['aXd', 5, None, 0]] * N)
check('composition-revision scenario 2', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['update', 0, 0, 'YZ'], ['commit', 0, 0, '']]]] * N), [['aYZd', 5, None, 0]] * N)
check('composition-revision scenario 3', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['external', 0, 0, 'new'], ['commit', 0, 0, '']]]] * N), [['new', 5, None, 1]] * N)
check('composition-revision scenario 4', solve([['abcd', 4, [['external', 0, 0, 'one'], ['external', 0, 0, 'two']]]] * N), [['two', 6, None, 0]] * N)
check('composition-revision scenario 5', solve([['abcd', 4, [['begin', 1, 3, 'X'], ['external', 0, 0, 'one'], ['external', 0, 0, 'two'], ['commit', 0, 0, ''], ['begin', 0, 1, 'Z'], ['external', 0, 0, 'three'], ['commit', 0, 0, '']]]] * N), [['three', 7, None, 2]] * N)
check('composition-revision scenario 6', solve([['abcd', 4, [['begin', 0, 0, ''], ['cancel', 0, 0, '']]]] * N), [['abcd', 4, None, 0]] * N)
check('composition-revision scenario 7', solve([['abcd', 0, [['begin', 1, 3, 'X'], ['commit', 0, 0, ''], ['commit', 0, 0, '']]]] * N), [['aXd', 1, None, 0]] * 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 |
|---|---|---|---|
| composition-revision scenario 0 | [['abcd', 4, None, 0]] | [['abcd', 4, None, 0]] | Passed |
| composition-revision scenario 1 | [['aXd', 5, None, 0]] | [['aXd', 5, None, 0]] | Passed |
| composition-revision scenario 2 | [['aYZd', 5, None, 0]] | [['aYZd', 5, None, 0]] | Passed |
| composition-revision scenario 3 | [['new', 5, None, 1]] | [['new', 5, None, 1]] | Passed |
| composition-revision scenario 4 | [['two', 6, None, 0]] | [['two', 6, None, 0]] | Passed |
| composition-revision scenario 5 | [['three', 7, None, 2]] | [['three', 7, None, 2]] | Passed |
| composition-revision scenario 6 | [['abcd', 4, None, 0]] | [['abcd', 4, None, 0]] | Passed |
| composition-revision scenario 7 | [['aXd', 1, None, 0]] | [['aXd', 1, None, 0]] | Passed |
SHA-256 / 1716ae8042814704e7f822e0aae27ac4b9e47d4ef83ad742654827f3399a5289
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:08.541593+00:00.
Case digest / 23be0a079983bbc75be405f11a715f7e1264dcab89a1d9a8207982de49a938a3