FA-22796 / Autocomplete interactions / Open access
Undoable autocomplete acceptance: undo restores text but leaves accepted suggestion submitted · case 01
The undo-value completion transition produces an incorrect observable state.
ROOT CAUSE
At completion-undo/undo-value, the implementation evaluates `d['after']['value']` instead of preserving the specified completion transition.
VERIFIED REPAIR
Implement the undo-value contract using `d['before']['value']`.
Unsuccessful approach: The attempted repair uses `None`, which still violates a normal or boundary completion fixture.
Case contract
A completion acceptance is one undo transaction containing draft, committed identity and caret. Undo restores the pre-accept snapshot; redo restores the accepted snapshot. A subsequent edit discards redo, transient hover never enters the stack, and history snapshots own their data.
Why this case matters
Autocomplete couples draft text, suggestion identity and asynchronous presentation; this bounded lifecycle model isolates one observable interaction defect.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(event, d):
if event == 'undo-text': return d['before']['text']
if event == 'undo-value': return d['after']['value']
if event == 'undo-caret': return d['before']['caret']
if event == 'redo-text': return d['after']['text']
if event == 'redo-value': return d['after']['value']
if event == 'redo-caret': return d['after']['caret']
if event == 'edit': return []
if event == 'transaction': return d['undo']+[d['before']]
if event == 'hover': return d['undo']
if event == 'redo-divergence': return d['draft']==d['before']['text']
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'before':{'text':'pea','value':None,'caret':3},'after':{'text':'pear','value':'p1','caret':4},'undo':['u1'],'redo':['r1'],'hover':'p2','draft':'pear!','epoch':N}
boundary = {'before':{'text':'','value':'','caret':0},'after':{'text':'x','value':'x1','caret':1},'undo':[],'redo':[],'hover':None,'draft':'','epoch':N}
check('normal undo-text', solve('undo-text', normal), 'pea')
check('boundary undo-text', solve('undo-text', boundary), '')
check('normal undo-value', solve('undo-value', normal), None)
check('boundary undo-value', solve('undo-value', boundary), '')
check('normal undo-caret', solve('undo-caret', normal), 3)
check('boundary undo-caret', solve('undo-caret', boundary), 0)
check('normal redo-text', solve('redo-text', normal), 'pear')
check('boundary redo-text', solve('redo-text', boundary), 'x')
check('normal redo-value', solve('redo-value', normal), 'p1')
check('boundary redo-value', solve('redo-value', boundary), 'x1')
check('normal redo-caret', solve('redo-caret', normal), 4)
check('boundary redo-caret', solve('redo-caret', boundary), 1)
check('normal edit', solve('edit', normal), [])
check('boundary edit', solve('edit', boundary), [])
check('normal transaction', solve('transaction', normal), ['u1',{'text':'pea','value':None,'caret':3}])
check('boundary transaction', solve('transaction', boundary), [{'text':'','value':'','caret':0}])
check('normal hover', solve('hover', normal), ['u1'])
check('boundary hover', solve('hover', boundary), [])
check('normal redo-divergence', solve('redo-divergence', normal), False)
check('boundary redo-divergence', solve('redo-divergence', boundary), True)
variant = dict(normal, **{'after':{'text':'p'*N,'value':'p','caret':N}})
check('variant query or selection payload', solve('redo-text', variant), 'p'*N)
check('unknown completion event', solve('unrecognized', normal), {'unchanged': True})
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 |
|---|---|---|---|
| normal undo-text | pea | pea | Passed |
| boundary undo-text | | | Passed |
| normal undo-value | p1 | None | Failed |
| boundary undo-value | x1 | | Failed |
| normal undo-caret | 3 | 3 | Passed |
| boundary undo-caret | 0 | 0 | Passed |
| normal redo-text | pear | pear | Passed |
| boundary redo-text | x | x | Passed |
| normal redo-value | p1 | p1 | Passed |
| boundary redo-value | x1 | x1 | Passed |
| normal redo-caret | 4 | 4 | Passed |
| boundary redo-caret | 1 | 1 | Passed |
| normal edit | [] | [] | Passed |
| boundary edit | [] | [] | Passed |
| normal transaction | ['u1', {'caret': 3, 'text': 'pea', 'value': None}] | ['u1', {'caret': 3, 'text': 'pea', 'value': None}] | Passed |
| boundary transaction | [{'caret': 0, 'text': '', 'value': ''}] | [{'caret': 0, 'text': '', 'value': ''}] | Passed |
| normal hover | ['u1'] | ['u1'] | Passed |
| boundary hover | [] | [] | Passed |
| normal redo-divergence | False | False | Passed |
| boundary redo-divergence | True | True | Passed |
| variant query or selection payload | p | p | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / c97456fe5fa852c98e4d098864ff68f69c21574c4aa47a5c2cd2f35c5d6e0f17
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(event, d):
if event == 'undo-text': return d['before']['text']
if event == 'undo-value': return None
if event == 'undo-caret': return d['before']['caret']
if event == 'redo-text': return d['after']['text']
if event == 'redo-value': return d['after']['value']
if event == 'redo-caret': return d['after']['caret']
if event == 'edit': return []
if event == 'transaction': return d['undo']+[d['before']]
if event == 'hover': return d['undo']
if event == 'redo-divergence': return d['draft']==d['before']['text']
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'before':{'text':'pea','value':None,'caret':3},'after':{'text':'pear','value':'p1','caret':4},'undo':['u1'],'redo':['r1'],'hover':'p2','draft':'pear!','epoch':N}
boundary = {'before':{'text':'','value':'','caret':0},'after':{'text':'x','value':'x1','caret':1},'undo':[],'redo':[],'hover':None,'draft':'','epoch':N}
check('normal undo-text', solve('undo-text', normal), 'pea')
check('boundary undo-text', solve('undo-text', boundary), '')
check('normal undo-value', solve('undo-value', normal), None)
check('boundary undo-value', solve('undo-value', boundary), '')
check('normal undo-caret', solve('undo-caret', normal), 3)
check('boundary undo-caret', solve('undo-caret', boundary), 0)
check('normal redo-text', solve('redo-text', normal), 'pear')
check('boundary redo-text', solve('redo-text', boundary), 'x')
check('normal redo-value', solve('redo-value', normal), 'p1')
check('boundary redo-value', solve('redo-value', boundary), 'x1')
check('normal redo-caret', solve('redo-caret', normal), 4)
check('boundary redo-caret', solve('redo-caret', boundary), 1)
check('normal edit', solve('edit', normal), [])
check('boundary edit', solve('edit', boundary), [])
check('normal transaction', solve('transaction', normal), ['u1',{'text':'pea','value':None,'caret':3}])
check('boundary transaction', solve('transaction', boundary), [{'text':'','value':'','caret':0}])
check('normal hover', solve('hover', normal), ['u1'])
check('boundary hover', solve('hover', boundary), [])
check('normal redo-divergence', solve('redo-divergence', normal), False)
check('boundary redo-divergence', solve('redo-divergence', boundary), True)
variant = dict(normal, **{'after':{'text':'p'*N,'value':'p','caret':N}})
check('variant query or selection payload', solve('redo-text', variant), 'p'*N)
check('unknown completion event', solve('unrecognized', normal), {'unchanged': True})
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 |
|---|---|---|---|
| normal undo-text | pea | pea | Passed |
| boundary undo-text | | | Passed |
| normal undo-value | None | None | Passed |
| boundary undo-value | None | | Failed |
| normal undo-caret | 3 | 3 | Passed |
| boundary undo-caret | 0 | 0 | Passed |
| normal redo-text | pear | pear | Passed |
| boundary redo-text | x | x | Passed |
| normal redo-value | p1 | p1 | Passed |
| boundary redo-value | x1 | x1 | Passed |
| normal redo-caret | 4 | 4 | Passed |
| boundary redo-caret | 1 | 1 | Passed |
| normal edit | [] | [] | Passed |
| boundary edit | [] | [] | Passed |
| normal transaction | ['u1', {'caret': 3, 'text': 'pea', 'value': None}] | ['u1', {'caret': 3, 'text': 'pea', 'value': None}] | Passed |
| boundary transaction | [{'caret': 0, 'text': '', 'value': ''}] | [{'caret': 0, 'text': '', 'value': ''}] | Passed |
| normal hover | ['u1'] | ['u1'] | Passed |
| boundary hover | [] | [] | Passed |
| normal redo-divergence | False | False | Passed |
| boundary redo-divergence | True | True | Passed |
| variant query or selection payload | p | p | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 58458a90e8e1a01e1c6736ca808681211fd4242d78ce693129ff547261179307
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(event, d):
if event == 'undo-text': return d['before']['text']
if event == 'undo-value': return d['before']['value']
if event == 'undo-caret': return d['before']['caret']
if event == 'redo-text': return d['after']['text']
if event == 'redo-value': return d['after']['value']
if event == 'redo-caret': return d['after']['caret']
if event == 'edit': return []
if event == 'transaction': return d['undo']+[d['before']]
if event == 'hover': return d['undo']
if event == 'redo-divergence': return d['draft']==d['before']['text']
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'before':{'text':'pea','value':None,'caret':3},'after':{'text':'pear','value':'p1','caret':4},'undo':['u1'],'redo':['r1'],'hover':'p2','draft':'pear!','epoch':N}
boundary = {'before':{'text':'','value':'','caret':0},'after':{'text':'x','value':'x1','caret':1},'undo':[],'redo':[],'hover':None,'draft':'','epoch':N}
check('normal undo-text', solve('undo-text', normal), 'pea')
check('boundary undo-text', solve('undo-text', boundary), '')
check('normal undo-value', solve('undo-value', normal), None)
check('boundary undo-value', solve('undo-value', boundary), '')
check('normal undo-caret', solve('undo-caret', normal), 3)
check('boundary undo-caret', solve('undo-caret', boundary), 0)
check('normal redo-text', solve('redo-text', normal), 'pear')
check('boundary redo-text', solve('redo-text', boundary), 'x')
check('normal redo-value', solve('redo-value', normal), 'p1')
check('boundary redo-value', solve('redo-value', boundary), 'x1')
check('normal redo-caret', solve('redo-caret', normal), 4)
check('boundary redo-caret', solve('redo-caret', boundary), 1)
check('normal edit', solve('edit', normal), [])
check('boundary edit', solve('edit', boundary), [])
check('normal transaction', solve('transaction', normal), ['u1',{'text':'pea','value':None,'caret':3}])
check('boundary transaction', solve('transaction', boundary), [{'text':'','value':'','caret':0}])
check('normal hover', solve('hover', normal), ['u1'])
check('boundary hover', solve('hover', boundary), [])
check('normal redo-divergence', solve('redo-divergence', normal), False)
check('boundary redo-divergence', solve('redo-divergence', boundary), True)
variant = dict(normal, **{'after':{'text':'p'*N,'value':'p','caret':N}})
check('variant query or selection payload', solve('redo-text', variant), 'p'*N)
check('unknown completion event', solve('unrecognized', normal), {'unchanged': True})
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 |
|---|---|---|---|
| normal undo-text | pea | pea | Passed |
| boundary undo-text | | | Passed |
| normal undo-value | None | None | Passed |
| boundary undo-value | | | Passed |
| normal undo-caret | 3 | 3 | Passed |
| boundary undo-caret | 0 | 0 | Passed |
| normal redo-text | pear | pear | Passed |
| boundary redo-text | x | x | Passed |
| normal redo-value | p1 | p1 | Passed |
| boundary redo-value | x1 | x1 | Passed |
| normal redo-caret | 4 | 4 | Passed |
| boundary redo-caret | 1 | 1 | Passed |
| normal edit | [] | [] | Passed |
| boundary edit | [] | [] | Passed |
| normal transaction | ['u1', {'caret': 3, 'text': 'pea', 'value': None}] | ['u1', {'caret': 3, 'text': 'pea', 'value': None}] | Passed |
| boundary transaction | [{'caret': 0, 'text': '', 'value': ''}] | [{'caret': 0, 'text': '', 'value': ''}] | Passed |
| normal hover | ['u1'] | ['u1'] | Passed |
| boundary hover | [] | [] | Passed |
| normal redo-divergence | False | False | Passed |
| boundary redo-divergence | True | True | Passed |
| variant query or selection payload | p | p | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 377cb2d0eaa908bb8212d1f3b120d412509cbebb386995d3875d72df722f8c26
Verification & scope
Stipulated deterministic widget transition model; inputs are validated snapshots. It does not model browser event dispatch, network transport, or linguistic standards. 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:40:41.689114+00:00.
Case digest / 9596f6651ce34983fe052fd88416ad5ed8a5e282e0afbb004c47190d9347da2a