FA-53841 / Accessibility interaction semantics / Open access
Alternative text spans retain a one-character object extent · case 01
Alternative text spans retain a one-character object extent.
ROOT CAUSE
The object end decision in the embedded text objects adapter violates its declared contract.
VERIFIED REPAIR
Apply the exact contract at the object end decision: [index,start,len(text),value]
Unsuccessful approach: The local repair substitutes [index,start,start+len(value),value] but still mishandles the regression fixtures.
Case contract
Input [tokens,alt_mode] where tokens are [kind,text,exposed], kinds text, object, break, decoration. Ignore unexposed or decoration tokens. Text is copied exactly; break becomes LF; object becomes U+FFFC unless alt_mode, when nonempty alternative text is used and empty alternative falls back to U+FFFC. Return [flattened,objects] with objects [token_index,start,end,alternative]. All offsets are codepoints in output; ordinary text does not add object mappings. Adjacent objects remain separate; zero-length text has no effect.
Why this case matters
Offline accessibility bridge model with explicit policy; useful for testing semantic API adapters independently of browser implementations.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(data):
tokens,alt_mode = data
text = ''
objects = []
for index,(kind,value,exposed) in enumerate(tokens):
if not exposed or kind == 'decoration': continue
start = len(text)
if kind == 'text': text += value
elif kind == 'break': text += '\n'
elif kind == 'object':
text += value if alt_mode and value else '\ufffc'
objects.append([index,start,start+1,value])
return [text,objects]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[['text','A'*N,True],['object','Cat',True],['text','Z',True]],False],), ['A'*N+'Z',[[1,N,N+1,'Cat']]])
check('contract fixture 2', solve([[['text','A'*N,True],['object','Cat',True],['object','',True]],True],), ['A'*N+'Cat',[[1,N,N+3,'Cat'],[2,N+3,N+4,'']]])
check('contract fixture 3', solve([[['decoration','*',True],['object','Hidden',False],['text','X',True]],False],), ['X',[]])
check('contract fixture 4', solve([[['text','A',True],['break','ignored',True],['text','B',True]],False],), ['A\nB',[]])
check('contract fixture 5', solve([[['object','A',True],['object','B',True]],False],), ['',[[0,0,1,'A'],[1,1,2,'B']]])
check('contract fixture 6', solve([[['text','',True]],True],), ['',[]])
check('contract fixture 7', solve([[['text',' A ',True]],False],), [' A ',[]])
check('contract fixture 8', solve([[],False],), ['',[]])
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 |
|---|---|---|---|
| contract fixture 1 | ['AZ', [[1, 1, 2, 'Cat']]] | ['AZ', [[1, 1, 2, 'Cat']]] | Passed |
| contract fixture 2 | ['ACat', [[1, 1, 2, 'Cat'], [2, 4, 5, '']]] | ['ACat', [[1, 1, 4, 'Cat'], [2, 4, 5, '']]] | Failed |
| contract fixture 3 | ['X', []] | ['X', []] | Passed |
| contract fixture 4 | ['A\nB', []] | ['A\nB', []] | Passed |
| contract fixture 5 | ['', [[0, 0, 1, 'A'], [1, 1, 2, 'B']]] | ['', [[0, 0, 1, 'A'], [1, 1, 2, 'B']]] | Passed |
| contract fixture 6 | ['', []] | ['', []] | Passed |
| contract fixture 7 | [' A ', []] | [' A ', []] | Passed |
| contract fixture 8 | ['', []] | ['', []] | Passed |
SHA-256 / 9736212ec08d3fd7d7762fb8a251549e943ef16937cc4bc3a4343fc6bf373fcd
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(data):
tokens,alt_mode = data
text = ''
objects = []
for index,(kind,value,exposed) in enumerate(tokens):
if not exposed or kind == 'decoration': continue
start = len(text)
if kind == 'text': text += value
elif kind == 'break': text += '\n'
elif kind == 'object':
text += value if alt_mode and value else '\ufffc'
objects.append([index,start,start+len(value),value])
return [text,objects]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[['text','A'*N,True],['object','Cat',True],['text','Z',True]],False],), ['A'*N+'Z',[[1,N,N+1,'Cat']]])
check('contract fixture 2', solve([[['text','A'*N,True],['object','Cat',True],['object','',True]],True],), ['A'*N+'Cat',[[1,N,N+3,'Cat'],[2,N+3,N+4,'']]])
check('contract fixture 3', solve([[['decoration','*',True],['object','Hidden',False],['text','X',True]],False],), ['X',[]])
check('contract fixture 4', solve([[['text','A',True],['break','ignored',True],['text','B',True]],False],), ['A\nB',[]])
check('contract fixture 5', solve([[['object','A',True],['object','B',True]],False],), ['',[[0,0,1,'A'],[1,1,2,'B']]])
check('contract fixture 6', solve([[['text','',True]],True],), ['',[]])
check('contract fixture 7', solve([[['text',' A ',True]],False],), [' A ',[]])
check('contract fixture 8', solve([[],False],), ['',[]])
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 |
|---|---|---|---|
| contract fixture 1 | ['AZ', [[1, 1, 4, 'Cat']]] | ['AZ', [[1, 1, 2, 'Cat']]] | Failed |
| contract fixture 2 | ['ACat', [[1, 1, 4, 'Cat'], [2, 4, 4, '']]] | ['ACat', [[1, 1, 4, 'Cat'], [2, 4, 5, '']]] | Failed |
| contract fixture 3 | ['X', []] | ['X', []] | Passed |
| contract fixture 4 | ['A\nB', []] | ['A\nB', []] | Passed |
| contract fixture 5 | ['', [[0, 0, 1, 'A'], [1, 1, 2, 'B']]] | ['', [[0, 0, 1, 'A'], [1, 1, 2, 'B']]] | Passed |
| contract fixture 6 | ['', []] | ['', []] | Passed |
| contract fixture 7 | [' A ', []] | [' A ', []] | Passed |
| contract fixture 8 | ['', []] | ['', []] | Passed |
SHA-256 / 200e45b80410632c0ab71a7f0cf8308e88953eea6dd94c3f9495db39a9f3150b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(data):
tokens,alt_mode = data
text = ''
objects = []
for index,(kind,value,exposed) in enumerate(tokens):
if not exposed or kind == 'decoration': continue
start = len(text)
if kind == 'text': text += value
elif kind == 'break': text += '\n'
elif kind == 'object':
text += value if alt_mode and value else '\ufffc'
objects.append([index,start,len(text),value])
return [text,objects]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[['text','A'*N,True],['object','Cat',True],['text','Z',True]],False],), ['A'*N+'Z',[[1,N,N+1,'Cat']]])
check('contract fixture 2', solve([[['text','A'*N,True],['object','Cat',True],['object','',True]],True],), ['A'*N+'Cat',[[1,N,N+3,'Cat'],[2,N+3,N+4,'']]])
check('contract fixture 3', solve([[['decoration','*',True],['object','Hidden',False],['text','X',True]],False],), ['X',[]])
check('contract fixture 4', solve([[['text','A',True],['break','ignored',True],['text','B',True]],False],), ['A\nB',[]])
check('contract fixture 5', solve([[['object','A',True],['object','B',True]],False],), ['',[[0,0,1,'A'],[1,1,2,'B']]])
check('contract fixture 6', solve([[['text','',True]],True],), ['',[]])
check('contract fixture 7', solve([[['text',' A ',True]],False],), [' A ',[]])
check('contract fixture 8', solve([[],False],), ['',[]])
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 |
|---|---|---|---|
| contract fixture 1 | ['AZ', [[1, 1, 2, 'Cat']]] | ['AZ', [[1, 1, 2, 'Cat']]] | Passed |
| contract fixture 2 | ['ACat', [[1, 1, 4, 'Cat'], [2, 4, 5, '']]] | ['ACat', [[1, 1, 4, 'Cat'], [2, 4, 5, '']]] | Passed |
| contract fixture 3 | ['X', []] | ['X', []] | Passed |
| contract fixture 4 | ['A\nB', []] | ['A\nB', []] | Passed |
| contract fixture 5 | ['', [[0, 0, 1, 'A'], [1, 1, 2, 'B']]] | ['', [[0, 0, 1, 'A'], [1, 1, 2, 'B']]] | Passed |
| contract fixture 6 | ['', []] | ['', []] | Passed |
| contract fixture 7 | [' A ', []] | [' A ', []] | Passed |
| contract fixture 8 | ['', []] | ['', []] | Passed |
SHA-256 / 2e972e4ed1fff71f315d4e17658bf5aade7afd94b3d5ef2b942d7a23421b9d6d
Verification & scope
Stipulated finite adapter contract, not a claim of platform accessibility or ARIA conformance. 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:45:42.724957+00:00.
Case digest / 4bbd6b003143f203c6a32a5e9c568ca28f872589661d0db0a39f396c13e4eb9a