FA-54801 / Accessibility interaction semantics / Open access
Objects from another native window win semantic hit testing · case 01
Objects from another native window win semantic hit testing.
ROOT CAUSE
The native window decision in the platform hit adapter adapter violates its declared contract.
VERIFIED REPAIR
Apply the exact contract at the native window decision: owner != window or not exposed or transparent
Unsuccessful approach: The local repair substitutes owner != window and not exposed or transparent 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 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 | ['a', [1, 1]] | None | Failed |
| 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 / 85e5461ea2bf68a688c961763ac3a2ae67ad8274b6a20e618bc1f84d3dfb7e8c
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 and 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 | ['b', [1, 1]] | None | Failed |
| 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 / 34b525f4039d407458216d82329847e2b1fcf8cb767a2a62faae480dab98383d
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.759453+00:00.
Case digest / 893890921282646df5c667f60ca5969e59a9234ae70ea3b5a8fea8937f407767