FA-54821 / Accessibility interaction semantics / Open access
Native clipped regions remain semantically hit-testable · case 01
Native clipped regions remain semantically hit-testable.
ROOT CAUSE
The native clip decision in the platform hit adapter adapter violates its declared contract.
VERIFIED REPAIR
Apply the exact contract at the native clip decision: if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
Unsuccessful approach: The local repair substitutes if clip is not None and not (clip[0] <= x <= clip[2] and clip[1] <= y <= clip[3]): continue but still mishandles the regression fixtures.
Case contract
Input [window_origin,scroll,point,records,expected_window]. Pointer is screen coordinates. Convert to document coordinates by subtracting window_origin and adding scroll. Records [id,window,rect,z,exposed,transparent,clip,proxy,enabled]; rect and optional clip are [x0,y0,x1,y1], half-open. Zero/reversed rectangles never hit. Reject other windows or unexposed records. Transparent records do not themselves hit. Reject points outside clip. Among hits largest z wins, ties retain first input. Disabled semantics remain inspectable. Return proxy ID when nonempty, else own ID, plus [document_x,document_y]. None when no hit. This is semantic hit selection, not pixel rendering or focus navigation.
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):
origin,scroll,point,records,window = data
x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
hits = []
for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
if owner != window or not exposed or transparent: continue
x0,y0,x1,y1 = rect
if not (x0 <= x < x1 and y0 <= y < y1): continue
if False: continue
hits.append((z,-index,proxy if proxy else ident))
if not hits: return None
return [max(hits,key=lambda hit:(hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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 | ['a', [3, 4]] | ['a', [3, 4]] | Passed |
| contract fixture 2 | ['proxy', [1, 1]] | ['proxy', [1, 1]] | Passed |
| contract fixture 3 | ['first', [1, 1]] | ['first', [1, 1]] | Passed |
| contract fixture 4 | None | None | Passed |
| contract fixture 5 | None | None | Passed |
| contract fixture 6 | ['a', [2, 2]] | None | Failed |
| contract fixture 7 | ['a', [0, 0]] | ['a', [0, 0]] | Passed |
| contract fixture 8 | None | None | Passed |
SHA-256 / 22749c03449c0e74e8b53e8aa9daf9d7af5bebeaa16dcce915be70e77d9c62c1
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(data):
origin,scroll,point,records,window = data
x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
hits = []
for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
if owner != window or not exposed or transparent: continue
x0,y0,x1,y1 = rect
if not (x0 <= x < x1 and y0 <= y < y1): continue
if clip is not None and not (clip[0] <= x <= clip[2] and clip[1] <= y <= clip[3]): continue
hits.append((z,-index,proxy if proxy else ident))
if not hits: return None
return [max(hits,key=lambda hit:(hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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 | ['a', [3, 4]] | ['a', [3, 4]] | Passed |
| contract fixture 2 | ['proxy', [1, 1]] | ['proxy', [1, 1]] | Passed |
| contract fixture 3 | ['first', [1, 1]] | ['first', [1, 1]] | Passed |
| contract fixture 4 | None | None | Passed |
| contract fixture 5 | None | None | Passed |
| contract fixture 6 | ['a', [2, 2]] | None | Failed |
| contract fixture 7 | ['a', [0, 0]] | ['a', [0, 0]] | Passed |
| contract fixture 8 | None | None | Passed |
SHA-256 / dcc15ead22d526acb7dbca0dc700f2bd152393338d38311341ae24c2af926f2a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(data):
origin,scroll,point,records,window = data
x,y = point[0]-origin[0]+scroll[0],point[1]-origin[1]+scroll[1]
hits = []
for index,(ident,owner,rect,z,exposed,transparent,clip,proxy,enabled) in enumerate(records):
if owner != window or not exposed or transparent: continue
x0,y0,x1,y1 = rect
if not (x0 <= x < x1 and y0 <= y < y1): continue
if clip is not None and not (clip[0] <= x < clip[2] and clip[1] <= y < clip[3]): continue
hits.append((z,-index,proxy if proxy else ident))
if not hits: return None
return [max(hits,key=lambda hit:(hit[0],hit[1]))[2],[x,y]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([[N,10],[N+1,3],[N+1,11],[['a','w',[0,0,8,8],1,True,False,None,'',True]],'w'],), ['a',[N+2,4]])
check('contract fixture 2', solve([[0,0],[0,0],[1,1],[['back','w',[0,0,4,4],1,True,False,None,'',True],['front','w',[0,0,4,4],5,True,False,None,'proxy',False]],'w'],), ['proxy',[1,1]])
check('contract fixture 3', solve([[0,0],[0,0],[1,1],[['first','w',[0,0,4,4],2,True,False,None,'',True],['second','w',[0,0,4,4],2,True,False,None,'',True]],'w'],), ['first',[1,1]])
check('contract fixture 4', solve([[0,0],[0,0],[1,1],[['a','other',[0,0,4,4],1,True,False,None,'',True],['b','w',[0,0,4,4],2,False,False,None,'',True],['c','w',[0,0,4,4],3,True,True,None,'',True]],'w'],), None)
check('contract fixture 5', solve([[0,0],[0,0],[4,1],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), None)
check('contract fixture 6', solve([[0,0],[0,0],[2,2],[['a','w',[0,0,4,4],1,True,False,[0,0,2,2],'',True]],'w'],), None)
check('contract fixture 7', solve([[0,0],[0,0],[0,0],[['a','w',[0,0,4,4],1,True,False,None,'',True]],'w'],), ['a',[0,0]])
check('contract fixture 8', solve([[0,0],[0,0],[1,1],[],'w'],), None)
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 | ['a', [3, 4]] | ['a', [3, 4]] | Passed |
| contract fixture 2 | ['proxy', [1, 1]] | ['proxy', [1, 1]] | Passed |
| contract fixture 3 | ['first', [1, 1]] | ['first', [1, 1]] | Passed |
| contract fixture 4 | None | None | Passed |
| contract fixture 5 | None | None | Passed |
| contract fixture 6 | None | None | Passed |
| contract fixture 7 | ['a', [0, 0]] | ['a', [0, 0]] | Passed |
| contract fixture 8 | None | None | Passed |
SHA-256 / f0de5cfd5d853c2425745a98bc1f6541813d8fa765e0fca7e82b5dd47d52ed6a
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:51.839973+00:00.
Case digest / f0b8cd44453beef03e0917921cc04369ac27783fe903bd7d22071f1528e519e6