FA-22966 / Autocomplete interactions / Open access
Mention suggestion insertion: mention caret omits the trigger width · case 01
The caret completion transition produces an incorrect observable state.
ROOT CAUSE
At mention-completion/caret, the implementation evaluates `d['start']+len(d['label'])` instead of preserving the specified completion transition.
VERIFIED REPAIR
Implement the caret contract using `d['start']+len(d['trigger'])+len(d['label'])`.
Unsuccessful approach: The attempted repair uses `d['end']`, which still violates a normal or boundary completion fixture.
Case contract
A mention completion replaces only the active trigger span and stores a stable entity identifier separately from visible text. The trigger character is preserved exactly once, a trailing delimiter is added only when absent, and a stale mention query cannot replace a different trigger span. Offsets are code points.
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 == 'text': return d['text'][:d['start']]+d['trigger']+d['label']+d['text'][d['end']:]
if event == 'identity': return d['id']
if event == 'trigger': return d['trigger']+d['label']
if event == 'query': return d['query']
if event == 'delimiter': return '' if d['after'].startswith(' ') else ' '
if event == 'caret': return d['start']+len(d['label'])
if event == 'span': return [d['start'],d['start']+len(d['trigger'])+len(d['label'])]
if event == 'stale': return d['span_epoch']==d['epoch']
if event == 'tail': return d['text'][d['end']:]
if event == 'descriptor': return [d['trigger'],d['query']]
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'text':'Hi @al now','start':3,'end':6,'label':'Alice','id':'u'+str(N),'trigger':'@','after':' now','query':'al','span_epoch':N-1,'epoch':N,'other':'#topic'}
boundary = {'text':'@','start':0,'end':1,'label':'','id':'','trigger':'@','after':'','query':'','span_epoch':N,'epoch':N,'other':''}
check('normal text', solve('text', normal), 'Hi @Alice now')
check('boundary text', solve('text', boundary), '@')
check('normal identity', solve('identity', normal), 'u'+str(N))
check('boundary identity', solve('identity', boundary), '')
check('normal trigger', solve('trigger', normal), '@Alice')
check('boundary trigger', solve('trigger', boundary), '@')
check('normal query', solve('query', normal), 'al')
check('boundary query', solve('query', boundary), '')
check('normal delimiter', solve('delimiter', normal), '')
check('boundary delimiter', solve('delimiter', boundary), ' ')
check('normal caret', solve('caret', normal), 9)
check('boundary caret', solve('caret', boundary), 1)
check('normal span', solve('span', normal), [3,9])
check('boundary span', solve('span', boundary), [0,1])
check('normal stale', solve('stale', normal), False)
check('boundary stale', solve('stale', boundary), True)
check('normal tail', solve('tail', normal), ' now')
check('boundary tail', solve('tail', boundary), '')
check('normal descriptor', solve('descriptor', normal), ['@','al'])
check('boundary descriptor', solve('descriptor', boundary), ['@',''])
variant = dict(normal, **{'id':'person'+str(N)})
check('variant query or selection payload', solve('identity', variant), 'person'+str(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 text | Hi @Alice now | Hi @Alice now | Passed |
| boundary text | @ | @ | Passed |
| normal identity | u1 | u1 | Passed |
| boundary identity | | | Passed |
| normal trigger | @Alice | @Alice | Passed |
| boundary trigger | @ | @ | Passed |
| normal query | al | al | Passed |
| boundary query | | | Passed |
| normal delimiter | | | Passed |
| boundary delimiter | | | Passed |
| normal caret | 8 | 9 | Failed |
| boundary caret | 0 | 1 | Failed |
| normal span | [3, 9] | [3, 9] | Passed |
| boundary span | [0, 1] | [0, 1] | Passed |
| normal stale | False | False | Passed |
| boundary stale | True | True | Passed |
| normal tail | now | now | Passed |
| boundary tail | | | Passed |
| normal descriptor | ['@', 'al'] | ['@', 'al'] | Passed |
| boundary descriptor | ['@', ''] | ['@', ''] | Passed |
| variant query or selection payload | person1 | person1 | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 41da8592f5a3becd3ad4bca13d925554a041b3fa3387741d8a9d2b33f5535689
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 == 'text': return d['text'][:d['start']]+d['trigger']+d['label']+d['text'][d['end']:]
if event == 'identity': return d['id']
if event == 'trigger': return d['trigger']+d['label']
if event == 'query': return d['query']
if event == 'delimiter': return '' if d['after'].startswith(' ') else ' '
if event == 'caret': return d['end']
if event == 'span': return [d['start'],d['start']+len(d['trigger'])+len(d['label'])]
if event == 'stale': return d['span_epoch']==d['epoch']
if event == 'tail': return d['text'][d['end']:]
if event == 'descriptor': return [d['trigger'],d['query']]
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'text':'Hi @al now','start':3,'end':6,'label':'Alice','id':'u'+str(N),'trigger':'@','after':' now','query':'al','span_epoch':N-1,'epoch':N,'other':'#topic'}
boundary = {'text':'@','start':0,'end':1,'label':'','id':'','trigger':'@','after':'','query':'','span_epoch':N,'epoch':N,'other':''}
check('normal text', solve('text', normal), 'Hi @Alice now')
check('boundary text', solve('text', boundary), '@')
check('normal identity', solve('identity', normal), 'u'+str(N))
check('boundary identity', solve('identity', boundary), '')
check('normal trigger', solve('trigger', normal), '@Alice')
check('boundary trigger', solve('trigger', boundary), '@')
check('normal query', solve('query', normal), 'al')
check('boundary query', solve('query', boundary), '')
check('normal delimiter', solve('delimiter', normal), '')
check('boundary delimiter', solve('delimiter', boundary), ' ')
check('normal caret', solve('caret', normal), 9)
check('boundary caret', solve('caret', boundary), 1)
check('normal span', solve('span', normal), [3,9])
check('boundary span', solve('span', boundary), [0,1])
check('normal stale', solve('stale', normal), False)
check('boundary stale', solve('stale', boundary), True)
check('normal tail', solve('tail', normal), ' now')
check('boundary tail', solve('tail', boundary), '')
check('normal descriptor', solve('descriptor', normal), ['@','al'])
check('boundary descriptor', solve('descriptor', boundary), ['@',''])
variant = dict(normal, **{'id':'person'+str(N)})
check('variant query or selection payload', solve('identity', variant), 'person'+str(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 text | Hi @Alice now | Hi @Alice now | Passed |
| boundary text | @ | @ | Passed |
| normal identity | u1 | u1 | Passed |
| boundary identity | | | Passed |
| normal trigger | @Alice | @Alice | Passed |
| boundary trigger | @ | @ | Passed |
| normal query | al | al | Passed |
| boundary query | | | Passed |
| normal delimiter | | | Passed |
| boundary delimiter | | | Passed |
| normal caret | 6 | 9 | Failed |
| boundary caret | 1 | 1 | Passed |
| normal span | [3, 9] | [3, 9] | Passed |
| boundary span | [0, 1] | [0, 1] | Passed |
| normal stale | False | False | Passed |
| boundary stale | True | True | Passed |
| normal tail | now | now | Passed |
| boundary tail | | | Passed |
| normal descriptor | ['@', 'al'] | ['@', 'al'] | Passed |
| boundary descriptor | ['@', ''] | ['@', ''] | Passed |
| variant query or selection payload | person1 | person1 | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 709326456a2a35aae484a1252c05ca781f33ab97cc9fe104e4e4a2133ea5e89e
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 == 'text': return d['text'][:d['start']]+d['trigger']+d['label']+d['text'][d['end']:]
if event == 'identity': return d['id']
if event == 'trigger': return d['trigger']+d['label']
if event == 'query': return d['query']
if event == 'delimiter': return '' if d['after'].startswith(' ') else ' '
if event == 'caret': return d['start']+len(d['trigger'])+len(d['label'])
if event == 'span': return [d['start'],d['start']+len(d['trigger'])+len(d['label'])]
if event == 'stale': return d['span_epoch']==d['epoch']
if event == 'tail': return d['text'][d['end']:]
if event == 'descriptor': return [d['trigger'],d['query']]
return {'unchanged': True}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
normal = {'text':'Hi @al now','start':3,'end':6,'label':'Alice','id':'u'+str(N),'trigger':'@','after':' now','query':'al','span_epoch':N-1,'epoch':N,'other':'#topic'}
boundary = {'text':'@','start':0,'end':1,'label':'','id':'','trigger':'@','after':'','query':'','span_epoch':N,'epoch':N,'other':''}
check('normal text', solve('text', normal), 'Hi @Alice now')
check('boundary text', solve('text', boundary), '@')
check('normal identity', solve('identity', normal), 'u'+str(N))
check('boundary identity', solve('identity', boundary), '')
check('normal trigger', solve('trigger', normal), '@Alice')
check('boundary trigger', solve('trigger', boundary), '@')
check('normal query', solve('query', normal), 'al')
check('boundary query', solve('query', boundary), '')
check('normal delimiter', solve('delimiter', normal), '')
check('boundary delimiter', solve('delimiter', boundary), ' ')
check('normal caret', solve('caret', normal), 9)
check('boundary caret', solve('caret', boundary), 1)
check('normal span', solve('span', normal), [3,9])
check('boundary span', solve('span', boundary), [0,1])
check('normal stale', solve('stale', normal), False)
check('boundary stale', solve('stale', boundary), True)
check('normal tail', solve('tail', normal), ' now')
check('boundary tail', solve('tail', boundary), '')
check('normal descriptor', solve('descriptor', normal), ['@','al'])
check('boundary descriptor', solve('descriptor', boundary), ['@',''])
variant = dict(normal, **{'id':'person'+str(N)})
check('variant query or selection payload', solve('identity', variant), 'person'+str(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 text | Hi @Alice now | Hi @Alice now | Passed |
| boundary text | @ | @ | Passed |
| normal identity | u1 | u1 | Passed |
| boundary identity | | | Passed |
| normal trigger | @Alice | @Alice | Passed |
| boundary trigger | @ | @ | Passed |
| normal query | al | al | Passed |
| boundary query | | | Passed |
| normal delimiter | | | Passed |
| boundary delimiter | | | Passed |
| normal caret | 9 | 9 | Passed |
| boundary caret | 1 | 1 | Passed |
| normal span | [3, 9] | [3, 9] | Passed |
| boundary span | [0, 1] | [0, 1] | Passed |
| normal stale | False | False | Passed |
| boundary stale | True | True | Passed |
| normal tail | now | now | Passed |
| boundary tail | | | Passed |
| normal descriptor | ['@', 'al'] | ['@', 'al'] | Passed |
| boundary descriptor | ['@', ''] | ['@', ''] | Passed |
| variant query or selection payload | person1 | person1 | Passed |
| unknown completion event | {'unchanged': True} | {'unchanged': True} | Passed |
SHA-256 / 485a99c33af736944bc8b12c2aca5d41ff951a888cb256a26b00b738ea6c8a47
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:43.313525+00:00.
Case digest / 977b363da784a508390504f7e8625aa081535ab99ad75e62e974a6ffad4d3c90