FA-23116 / Autocomplete interactions / Open access
Autocomplete query activation policy: read-only completion launches editable search requests · case 01
The readonly completion transition produces an incorrect observable state.
ROOT CAUSE
At activation-policy/readonly, the implementation evaluates `True` instead of preserving the specified completion transition.
VERIFIED REPAIR
Implement the readonly contract using `not d['readonly']`.
Unsuccessful approach: The attempted repair uses `False`, which still violates a normal or boundary completion fixture.
Case contract
This stipulated picker searches only after minimum draft length unless explicit browse is requested. Empty-query browse uses recent suggestions, composition blocks query emission, and disabled/read-only interaction suppresses new requests. Draft erasure cancels pending search and clears query-bound results.
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 == 'threshold': return len(d['draft'])>=d['minimum']
if event == 'browse': return d['browse']
if event == 'recent': return d['recent'] if not d['draft'] else []
if event == 'deferred-browse': return {'defer_browse':d['browse'] and d['composing'],'query':None if d['composing'] else d['draft']}
if event == 'disabled': return not d['disabled']
if event == 'readonly': return True
if event == 'erase-pending': return None
if event == 'erase-results': return []
if event == 'empty-query-mode': return 'recent' if not d['draft'] and d['browse'] else 'type-more' if len(d['draft'])<d['minimum'] else 'results'
if event == 'browse-descriptor': return {'mode':'browse' if d['browse'] else 'query','text':d['draft']}
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'draft':'p','minimum':2,'browse':False,'recent':['a'],'composing':True,'disabled':True,'readonly':True,'pending':'pe','rows':['p1'],'epoch':N}
boundary = {'draft':'','minimum':0,'browse':True,'recent':[],'composing':False,'disabled':False,'readonly':False,'pending':None,'rows':[],'epoch':N}
check('normal threshold', solve('threshold', normal), False)
check('boundary threshold', solve('threshold', boundary), True)
check('normal browse', solve('browse', normal), False)
check('boundary browse', solve('browse', boundary), True)
check('normal recent', solve('recent', normal), [])
check('boundary recent', solve('recent', boundary), [])
check('normal deferred-browse', solve('deferred-browse', normal), {'defer_browse':False,'query':None})
check('boundary deferred-browse', solve('deferred-browse', boundary), {'defer_browse':False,'query':''})
check('normal disabled', solve('disabled', normal), False)
check('boundary disabled', solve('disabled', boundary), True)
check('normal readonly', solve('readonly', normal), False)
check('boundary readonly', solve('readonly', boundary), True)
check('normal erase-pending', solve('erase-pending', normal), None)
check('boundary erase-pending', solve('erase-pending', boundary), None)
check('normal erase-results', solve('erase-results', normal), [])
check('boundary erase-results', solve('erase-results', boundary), [])
check('normal empty-query-mode', solve('empty-query-mode', normal), 'type-more')
check('boundary empty-query-mode', solve('empty-query-mode', boundary), 'recent')
check('normal browse-descriptor', solve('browse-descriptor', normal), {'mode':'query','text':'p'})
check('boundary browse-descriptor', solve('browse-descriptor', boundary), {'mode':'browse','text':''})
variant = dict(normal, **{'draft':'x'*N,'minimum':N})
check('variant query or selection payload', solve('threshold', variant), True)
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 threshold | False | False | Passed |
| boundary threshold | True | True | Passed |
| normal browse | False | False | Passed |
| boundary browse | True | True | Passed |
| normal recent | [] | [] | Passed |
| boundary recent | [] | [] | Passed |
| normal deferred-browse | {'defer_browse': False, 'query': None} | {'defer_browse': False, 'query': None} | Passed |
| boundary deferred-browse | {'defer_browse': False, 'query': ''} | {'defer_browse': False, 'query': ''} | Passed |
| normal disabled | False | False | Passed |
| boundary disabled | True | True | Passed |
| normal readonly | True | False | Failed |
| boundary readonly | True | True | Passed |
| normal erase-pending | None | None | Passed |
| boundary erase-pending | None | None | Passed |
| normal erase-results | [] | [] | Passed |
| boundary erase-results | [] | [] | Passed |
| normal empty-query-mode | type-more | type-more | Passed |
| boundary empty-query-mode | recent | recent | Passed |
| normal browse-descriptor | {'mode': 'query', 'text': 'p'} | {'mode': 'query', 'text': 'p'} | Passed |
| boundary browse-descriptor | {'mode': 'browse', 'text': ''} | {'mode': 'browse', 'text': ''} | Passed |
| variant query or selection payload | True | True | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 772afcc2ce5d82627ac0538bc0b222f9cac715b1cd3cc228fbb502f4e186f4cb
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 == 'threshold': return len(d['draft'])>=d['minimum']
if event == 'browse': return d['browse']
if event == 'recent': return d['recent'] if not d['draft'] else []
if event == 'deferred-browse': return {'defer_browse':d['browse'] and d['composing'],'query':None if d['composing'] else d['draft']}
if event == 'disabled': return not d['disabled']
if event == 'readonly': return False
if event == 'erase-pending': return None
if event == 'erase-results': return []
if event == 'empty-query-mode': return 'recent' if not d['draft'] and d['browse'] else 'type-more' if len(d['draft'])<d['minimum'] else 'results'
if event == 'browse-descriptor': return {'mode':'browse' if d['browse'] else 'query','text':d['draft']}
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'draft':'p','minimum':2,'browse':False,'recent':['a'],'composing':True,'disabled':True,'readonly':True,'pending':'pe','rows':['p1'],'epoch':N}
boundary = {'draft':'','minimum':0,'browse':True,'recent':[],'composing':False,'disabled':False,'readonly':False,'pending':None,'rows':[],'epoch':N}
check('normal threshold', solve('threshold', normal), False)
check('boundary threshold', solve('threshold', boundary), True)
check('normal browse', solve('browse', normal), False)
check('boundary browse', solve('browse', boundary), True)
check('normal recent', solve('recent', normal), [])
check('boundary recent', solve('recent', boundary), [])
check('normal deferred-browse', solve('deferred-browse', normal), {'defer_browse':False,'query':None})
check('boundary deferred-browse', solve('deferred-browse', boundary), {'defer_browse':False,'query':''})
check('normal disabled', solve('disabled', normal), False)
check('boundary disabled', solve('disabled', boundary), True)
check('normal readonly', solve('readonly', normal), False)
check('boundary readonly', solve('readonly', boundary), True)
check('normal erase-pending', solve('erase-pending', normal), None)
check('boundary erase-pending', solve('erase-pending', boundary), None)
check('normal erase-results', solve('erase-results', normal), [])
check('boundary erase-results', solve('erase-results', boundary), [])
check('normal empty-query-mode', solve('empty-query-mode', normal), 'type-more')
check('boundary empty-query-mode', solve('empty-query-mode', boundary), 'recent')
check('normal browse-descriptor', solve('browse-descriptor', normal), {'mode':'query','text':'p'})
check('boundary browse-descriptor', solve('browse-descriptor', boundary), {'mode':'browse','text':''})
variant = dict(normal, **{'draft':'x'*N,'minimum':N})
check('variant query or selection payload', solve('threshold', variant), True)
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 threshold | False | False | Passed |
| boundary threshold | True | True | Passed |
| normal browse | False | False | Passed |
| boundary browse | True | True | Passed |
| normal recent | [] | [] | Passed |
| boundary recent | [] | [] | Passed |
| normal deferred-browse | {'defer_browse': False, 'query': None} | {'defer_browse': False, 'query': None} | Passed |
| boundary deferred-browse | {'defer_browse': False, 'query': ''} | {'defer_browse': False, 'query': ''} | Passed |
| normal disabled | False | False | Passed |
| boundary disabled | True | True | Passed |
| normal readonly | False | False | Passed |
| boundary readonly | False | True | Failed |
| normal erase-pending | None | None | Passed |
| boundary erase-pending | None | None | Passed |
| normal erase-results | [] | [] | Passed |
| boundary erase-results | [] | [] | Passed |
| normal empty-query-mode | type-more | type-more | Passed |
| boundary empty-query-mode | recent | recent | Passed |
| normal browse-descriptor | {'mode': 'query', 'text': 'p'} | {'mode': 'query', 'text': 'p'} | Passed |
| boundary browse-descriptor | {'mode': 'browse', 'text': ''} | {'mode': 'browse', 'text': ''} | Passed |
| variant query or selection payload | True | True | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 03eb3755065240b495c9e76729d350b3e1738288ca09514eb24a2782d68c37aa
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 == 'threshold': return len(d['draft'])>=d['minimum']
if event == 'browse': return d['browse']
if event == 'recent': return d['recent'] if not d['draft'] else []
if event == 'deferred-browse': return {'defer_browse':d['browse'] and d['composing'],'query':None if d['composing'] else d['draft']}
if event == 'disabled': return not d['disabled']
if event == 'readonly': return not d['readonly']
if event == 'erase-pending': return None
if event == 'erase-results': return []
if event == 'empty-query-mode': return 'recent' if not d['draft'] and d['browse'] else 'type-more' if len(d['draft'])<d['minimum'] else 'results'
if event == 'browse-descriptor': return {'mode':'browse' if d['browse'] else 'query','text':d['draft']}
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'draft':'p','minimum':2,'browse':False,'recent':['a'],'composing':True,'disabled':True,'readonly':True,'pending':'pe','rows':['p1'],'epoch':N}
boundary = {'draft':'','minimum':0,'browse':True,'recent':[],'composing':False,'disabled':False,'readonly':False,'pending':None,'rows':[],'epoch':N}
check('normal threshold', solve('threshold', normal), False)
check('boundary threshold', solve('threshold', boundary), True)
check('normal browse', solve('browse', normal), False)
check('boundary browse', solve('browse', boundary), True)
check('normal recent', solve('recent', normal), [])
check('boundary recent', solve('recent', boundary), [])
check('normal deferred-browse', solve('deferred-browse', normal), {'defer_browse':False,'query':None})
check('boundary deferred-browse', solve('deferred-browse', boundary), {'defer_browse':False,'query':''})
check('normal disabled', solve('disabled', normal), False)
check('boundary disabled', solve('disabled', boundary), True)
check('normal readonly', solve('readonly', normal), False)
check('boundary readonly', solve('readonly', boundary), True)
check('normal erase-pending', solve('erase-pending', normal), None)
check('boundary erase-pending', solve('erase-pending', boundary), None)
check('normal erase-results', solve('erase-results', normal), [])
check('boundary erase-results', solve('erase-results', boundary), [])
check('normal empty-query-mode', solve('empty-query-mode', normal), 'type-more')
check('boundary empty-query-mode', solve('empty-query-mode', boundary), 'recent')
check('normal browse-descriptor', solve('browse-descriptor', normal), {'mode':'query','text':'p'})
check('boundary browse-descriptor', solve('browse-descriptor', boundary), {'mode':'browse','text':''})
variant = dict(normal, **{'draft':'x'*N,'minimum':N})
check('variant query or selection payload', solve('threshold', variant), True)
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 threshold | False | False | Passed |
| boundary threshold | True | True | Passed |
| normal browse | False | False | Passed |
| boundary browse | True | True | Passed |
| normal recent | [] | [] | Passed |
| boundary recent | [] | [] | Passed |
| normal deferred-browse | {'defer_browse': False, 'query': None} | {'defer_browse': False, 'query': None} | Passed |
| boundary deferred-browse | {'defer_browse': False, 'query': ''} | {'defer_browse': False, 'query': ''} | Passed |
| normal disabled | False | False | Passed |
| boundary disabled | True | True | Passed |
| normal readonly | False | False | Passed |
| boundary readonly | True | True | Passed |
| normal erase-pending | None | None | Passed |
| boundary erase-pending | None | None | Passed |
| normal erase-results | [] | [] | Passed |
| boundary erase-results | [] | [] | Passed |
| normal empty-query-mode | type-more | type-more | Passed |
| boundary empty-query-mode | recent | recent | Passed |
| normal browse-descriptor | {'mode': 'query', 'text': 'p'} | {'mode': 'query', 'text': 'p'} | Passed |
| boundary browse-descriptor | {'mode': 'browse', 'text': ''} | {'mode': 'browse', 'text': ''} | Passed |
| variant query or selection payload | True | True | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 75b09fb0bba0850df55fe097809c062d4ba1606ac138c248e3865c13cb6dc32e
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:44.734254+00:00.
Case digest / 2a156daefb7f18b65b42ad4a51dedea470deb602472d60b9ca1762a6beb99855