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.
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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