FAILURE MAP
← Case archive

FA-7906 / Text editing / Open access

Text selection replacement: An IME composition is overwritten before commitment · case 01

An IME composition is overwritten before commitment.

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

ROOT CAUSE

The composition operation uses `if False:` where the contract requires `if composing:`.

VERIFIED REPAIR

Implement the composition operation as `if composing:`.

Unsuccessful approach: Blocking noncomposition edits disables ordinary input.

Case contract

Composition is preserved; replace the normalized half-open selection and collapse both endpoints immediately after inserted text.

Why this case matters

A deterministic model of text selection replacement; this isolates one interface invariant without requiring a browser.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, anchor, focus, replacement, composing):
    if False: return (text, anchor, focus)
    lo = min(anchor, focus)
    hi = max(anchor, focus)
    result = text[:lo] + replacement + text[hi:]
    caret = lo + len(replacement)
    return (result, caret, caret)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composition', solve('abcdef', 1, 4, 'XY', True), ('abcdef', 1, 4))
check('forward', solve('abcdef', 1, 4, 'XY', False), ('aXYef', 3, 3))
check('backward', solve('abcdef', 4, 1, 'XY', False), ('aXYef', 3, 3))
check('insertion', solve('ab', 1, 1, 'XYZ', False), ('aXYZb', 4, 4))
check('delete', solve('abc', 0, 3, '', False), ('', 0, 0))
check('no selection', solve('abc', 2, 2, '', False), ('abc', 2, 2))
check('parameterized selected length', solve('a'*N, 0, N, 'X', False), ('X', 1, 1))
for repetition in range(N):
    check('repeat no selection', solve('abc', 2, 2, '', False), ('abc', 2, 2))
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['aXYef', 3, 3]['abcdef', 1, 4]Failed
forward['aXYef', 3, 3]['aXYef', 3, 3]Passed
backward['aXYef', 3, 3]['aXYef', 3, 3]Passed
insertion['aXYZb', 4, 4]['aXYZb', 4, 4]Passed
delete['', 0, 0]['', 0, 0]Passed
no selection['abc', 2, 2]['abc', 2, 2]Passed
parameterized selected length['X', 1, 1]['X', 1, 1]Passed
repeat no selection['abc', 2, 2]['abc', 2, 2]Passed

SHA-256 / 527e26c59b6831aee42129ab394004b6380fb8fea55dde91caa700143db34a4b

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, anchor, focus, replacement, composing):
    if not composing: return (text, anchor, focus)
    lo = min(anchor, focus)
    hi = max(anchor, focus)
    result = text[:lo] + replacement + text[hi:]
    caret = lo + len(replacement)
    return (result, caret, caret)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composition', solve('abcdef', 1, 4, 'XY', True), ('abcdef', 1, 4))
check('forward', solve('abcdef', 1, 4, 'XY', False), ('aXYef', 3, 3))
check('backward', solve('abcdef', 4, 1, 'XY', False), ('aXYef', 3, 3))
check('insertion', solve('ab', 1, 1, 'XYZ', False), ('aXYZb', 4, 4))
check('delete', solve('abc', 0, 3, '', False), ('', 0, 0))
check('no selection', solve('abc', 2, 2, '', False), ('abc', 2, 2))
check('parameterized selected length', solve('a'*N, 0, N, 'X', False), ('X', 1, 1))
for repetition in range(N):
    check('repeat no selection', solve('abc', 2, 2, '', False), ('abc', 2, 2))
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['aXYef', 3, 3]['abcdef', 1, 4]Failed
forward['abcdef', 1, 4]['aXYef', 3, 3]Failed
backward['abcdef', 4, 1]['aXYef', 3, 3]Failed
insertion['ab', 1, 1]['aXYZb', 4, 4]Failed
delete['abc', 0, 3]['', 0, 0]Failed
no selection['abc', 2, 2]['abc', 2, 2]Passed
parameterized selected length['a', 0, 1]['X', 1, 1]Failed
repeat no selection['abc', 2, 2]['abc', 2, 2]Passed

SHA-256 / b7371df21cc12f5b181dc42285dff1468f3019e9a0e54ad644eb9a0e413d0154

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, anchor, focus, replacement, composing):
    if composing: return (text, anchor, focus)
    lo = min(anchor, focus)
    hi = max(anchor, focus)
    result = text[:lo] + replacement + text[hi:]
    caret = lo + len(replacement)
    return (result, caret, caret)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composition', solve('abcdef', 1, 4, 'XY', True), ('abcdef', 1, 4))
check('forward', solve('abcdef', 1, 4, 'XY', False), ('aXYef', 3, 3))
check('backward', solve('abcdef', 4, 1, 'XY', False), ('aXYef', 3, 3))
check('insertion', solve('ab', 1, 1, 'XYZ', False), ('aXYZb', 4, 4))
check('delete', solve('abc', 0, 3, '', False), ('', 0, 0))
check('no selection', solve('abc', 2, 2, '', False), ('abc', 2, 2))
check('parameterized selected length', solve('a'*N, 0, N, 'X', False), ('X', 1, 1))
for repetition in range(N):
    check('repeat no selection', solve('abc', 2, 2, '', False), ('abc', 2, 2))
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['abcdef', 1, 4]['abcdef', 1, 4]Passed
forward['aXYef', 3, 3]['aXYef', 3, 3]Passed
backward['aXYef', 3, 3]['aXYef', 3, 3]Passed
insertion['aXYZb', 4, 4]['aXYZb', 4, 4]Passed
delete['', 0, 0]['', 0, 0]Passed
no selection['abc', 2, 2]['abc', 2, 2]Passed
parameterized selected length['X', 1, 1]['X', 1, 1]Passed
repeat no selection['abc', 2, 2]['abc', 2, 2]Passed

SHA-256 / fc2f2c1a50e0138b1115cb5974ca3f32bfb6e374e5c68d2b170eef373d133908

Verification & scope

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

Case digest / a8138f886a3577bf7d29ebc0f0aeb1f1e85c886c3e950615027339c0d94033dc