FAILURE MAP
← Case archive

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.

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

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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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