FAILURE MAP
← Case archive

FA-53896 / Accessibility interaction semantics / Open access

Text position at a link end still resolves to that link · case 01

Text position at a link end still resolves to that link.

Verified by executionVariant 1 · 6 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The query end decision in the hyperlink spans adapter violates its declared contract.

VERIFIED REPAIR

Apply the exact contract at the query end decision: start <= offset < end

Unsuccessful approach: The local repair substitutes start < offset <= end but still mishandles the regression fixtures.

Case contract

Input [text_length,links,offset] where links [id,start,end,url,enabled]. Admit only nonempty URL, enabled and nonempty interval after clamping. Sort by start then shorter interval then input order; dedupe IDs after sorting. Query offset resolves the first matching half-open span, or None. Return [ordered descriptors,hit_id]. URLs remain exact including fragments; IDs are retained even when URL is shared.

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):
    length,links,offset = data
    valid = []
    for i,(ident,start,end,url,enabled) in enumerate(links):
        if not enabled or not url: continue
        start,end = max(0,start),min(length,end)
        if start >= end: continue
        valid.append((start,end-start,i,ident,end,url))
    valid.sort(key=lambda x:(x[0],x[1],x[2]))
    seen = set()
    rows = []
    for start,width,i,ident,end,url in valid:
        if ident in seen: continue
        seen.add(ident)
        rows.append([ident,start,end,url])
    hit = next((ident for ident,start,end,url in rows if start <= offset <= end),None)
    return [rows,hit]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([N+5,[['wide',N,N+4,'/a#x',True],['small',N,N+2,'/a#y',True]],N+1],), [[['small',N,N+2,'/a#y'],['wide',N,N+4,'/a#x']],'small'])
check('contract fixture 2', solve([5,[['a',-3,2,'/a',True],['b',2,8,'/b',True]],2],), [[['a',0,2,'/a'],['b',2,5,'/b']],'b'])
check('contract fixture 3', solve([5,[['a',1,1,'/a',True],['b',4,2,'/b',True],['c',0,3,'',True],['d',0,3,'/d',False]],0],), [[],None])
check('contract fixture 4', solve([6,[['a',3,6,'later',True],['a',0,2,'early',True]],1],), [[['a',0,2,'early']],'a'])
check('contract fixture 5', solve([3,[['a',0,3,'/same',True],['b',0,3,'/same',True]],3],), [[['a',0,3,'/same'],['b',0,3,'/same']],None])
check('contract fixture 6', solve([0,[],0],), [[],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 fixtureActualExpectedOutcome
contract fixture 1[[['small', 1, 3, '/a#y'], ['wide', 1, 5, '/a#x']], 'small'][[['small', 1, 3, '/a#y'], ['wide', 1, 5, '/a#x']], 'small']Passed
contract fixture 2[[['a', 0, 2, '/a'], ['b', 2, 5, '/b']], 'a'][[['a', 0, 2, '/a'], ['b', 2, 5, '/b']], 'b']Failed
contract fixture 3[[], None][[], None]Passed
contract fixture 4[[['a', 0, 2, 'early']], 'a'][[['a', 0, 2, 'early']], 'a']Passed
contract fixture 5[[['a', 0, 3, '/same'], ['b', 0, 3, '/same']], 'a'][[['a', 0, 3, '/same'], ['b', 0, 3, '/same']], None]Failed
contract fixture 6[[], None][[], None]Passed

SHA-256 / 17f1e62a8b4d786918aedabd27e792f47569a59f63ad6d5068e9859163690ecd

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    length,links,offset = data
    valid = []
    for i,(ident,start,end,url,enabled) in enumerate(links):
        if not enabled or not url: continue
        start,end = max(0,start),min(length,end)
        if start >= end: continue
        valid.append((start,end-start,i,ident,end,url))
    valid.sort(key=lambda x:(x[0],x[1],x[2]))
    seen = set()
    rows = []
    for start,width,i,ident,end,url in valid:
        if ident in seen: continue
        seen.add(ident)
        rows.append([ident,start,end,url])
    hit = next((ident for ident,start,end,url in rows if start < offset <= end),None)
    return [rows,hit]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([N+5,[['wide',N,N+4,'/a#x',True],['small',N,N+2,'/a#y',True]],N+1],), [[['small',N,N+2,'/a#y'],['wide',N,N+4,'/a#x']],'small'])
check('contract fixture 2', solve([5,[['a',-3,2,'/a',True],['b',2,8,'/b',True]],2],), [[['a',0,2,'/a'],['b',2,5,'/b']],'b'])
check('contract fixture 3', solve([5,[['a',1,1,'/a',True],['b',4,2,'/b',True],['c',0,3,'',True],['d',0,3,'/d',False]],0],), [[],None])
check('contract fixture 4', solve([6,[['a',3,6,'later',True],['a',0,2,'early',True]],1],), [[['a',0,2,'early']],'a'])
check('contract fixture 5', solve([3,[['a',0,3,'/same',True],['b',0,3,'/same',True]],3],), [[['a',0,3,'/same'],['b',0,3,'/same']],None])
check('contract fixture 6', solve([0,[],0],), [[],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 fixtureActualExpectedOutcome
contract fixture 1[[['small', 1, 3, '/a#y'], ['wide', 1, 5, '/a#x']], 'small'][[['small', 1, 3, '/a#y'], ['wide', 1, 5, '/a#x']], 'small']Passed
contract fixture 2[[['a', 0, 2, '/a'], ['b', 2, 5, '/b']], 'a'][[['a', 0, 2, '/a'], ['b', 2, 5, '/b']], 'b']Failed
contract fixture 3[[], None][[], None]Passed
contract fixture 4[[['a', 0, 2, 'early']], 'a'][[['a', 0, 2, 'early']], 'a']Passed
contract fixture 5[[['a', 0, 3, '/same'], ['b', 0, 3, '/same']], 'a'][[['a', 0, 3, '/same'], ['b', 0, 3, '/same']], None]Failed
contract fixture 6[[], None][[], None]Passed

SHA-256 / b98f7ed9943af504bda2ab95c870a40f1cd820dc2fe31fd7ab914414b74c6885

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data):
    length,links,offset = data
    valid = []
    for i,(ident,start,end,url,enabled) in enumerate(links):
        if not enabled or not url: continue
        start,end = max(0,start),min(length,end)
        if start >= end: continue
        valid.append((start,end-start,i,ident,end,url))
    valid.sort(key=lambda x:(x[0],x[1],x[2]))
    seen = set()
    rows = []
    for start,width,i,ident,end,url in valid:
        if ident in seen: continue
        seen.add(ident)
        rows.append([ident,start,end,url])
    hit = next((ident for ident,start,end,url in rows if start <= offset < end),None)
    return [rows,hit]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([N+5,[['wide',N,N+4,'/a#x',True],['small',N,N+2,'/a#y',True]],N+1],), [[['small',N,N+2,'/a#y'],['wide',N,N+4,'/a#x']],'small'])
check('contract fixture 2', solve([5,[['a',-3,2,'/a',True],['b',2,8,'/b',True]],2],), [[['a',0,2,'/a'],['b',2,5,'/b']],'b'])
check('contract fixture 3', solve([5,[['a',1,1,'/a',True],['b',4,2,'/b',True],['c',0,3,'',True],['d',0,3,'/d',False]],0],), [[],None])
check('contract fixture 4', solve([6,[['a',3,6,'later',True],['a',0,2,'early',True]],1],), [[['a',0,2,'early']],'a'])
check('contract fixture 5', solve([3,[['a',0,3,'/same',True],['b',0,3,'/same',True]],3],), [[['a',0,3,'/same'],['b',0,3,'/same']],None])
check('contract fixture 6', solve([0,[],0],), [[],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 fixtureActualExpectedOutcome
contract fixture 1[[['small', 1, 3, '/a#y'], ['wide', 1, 5, '/a#x']], 'small'][[['small', 1, 3, '/a#y'], ['wide', 1, 5, '/a#x']], 'small']Passed
contract fixture 2[[['a', 0, 2, '/a'], ['b', 2, 5, '/b']], 'b'][[['a', 0, 2, '/a'], ['b', 2, 5, '/b']], 'b']Passed
contract fixture 3[[], None][[], None]Passed
contract fixture 4[[['a', 0, 2, 'early']], 'a'][[['a', 0, 2, 'early']], 'a']Passed
contract fixture 5[[['a', 0, 3, '/same'], ['b', 0, 3, '/same']], None][[['a', 0, 3, '/same'], ['b', 0, 3, '/same']], None]Passed
contract fixture 6[[], None][[], None]Passed

SHA-256 / f4654d835f55847af12997f87b94c7f2e1def26a29178e6b84b9e32d343f7cde

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:43.275581+00:00.

Case digest / 82ae1db708fdddeb8704c411a0ca350517542d40e0ed455aa9edb288e4e428b3