FAILURE MAP
← Case archive

FA-54656 / Accessibility interaction semantics / Open access

Defunct accessibility objects retain readable properties · case 01

Defunct accessibility objects retain readable properties.

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

ROOT CAUSE

The dead read decision in the property query batch adapter violates its declared contract.

VERIFIED REPAIR

Apply the exact contract at the dead read decision: record is None or not record[0]

Unsuccessful approach: The local repair substitutes record is None or record[0] is None but still mishandles the regression fixtures.

Case contract

Input [objects,queries,revision,expected_revision]. objects map IDs to [alive,properties]; queries [id,property]. Allowed props name,value,description,role; a missing property is unsupported while an existing None is successful null. Results retain query order and duplicates, each [status,value]; status stale for every query when revisions differ, gone for missing/defunct object, unsupported for unknown/absent property, ok otherwise. Empty queries produce empty output. Return [revision,results], actual revision always. Values are returned as JSON-compatible content; object aliasing is outside this query-only model.

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):
    objects,queries,revision,expected = data
    results = []
    for ident,prop in queries:
        if expected != revision: results.append(['stale',None]); continue
        record = objects.get(ident)
        if record is None: results.append(['gone',None]); continue
        values = record[1]
        if prop not in {'name','value','description','role'} or prop not in values:
            results.append(['unsupported',None]); continue
        results.append(['ok',values.get(prop)])
    return [revision,results]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([{'a':[True,{'name':'A'+str(N),'value':None,'description':'','role':'image'}]},[['a','name'],['a','value'],['a','description'],['a','name']],N,N],), [N,[['ok','A'+str(N)],['ok',None],['ok',''],['ok','A'+str(N)]]])
check('contract fixture 2', solve([{'a':[True,{'secret':'s','name':'A'}]},[['a','secret'],['a','role']],N,N],), [N,[['unsupported',None],['unsupported',None]]])
check('contract fixture 3', solve([{'dead':[False,{'name':'secret'}]},[['missing','name'],['dead','name']],N,N],), [N,[['gone',None],['gone',None]]])
check('contract fixture 4', solve([{'a':[True,{'name':'A'}]},[['a','name'],['missing','role']],N,N-1],), [N,[['stale',None],['stale',None]]])
check('contract fixture 5', solve([{'a':[True,{'name':'A'}]},[['a','name']],N,N+1],), [N,[['stale',None]]])
check('contract fixture 6', solve([{},[],N,N],), [N,[]])
check('contract fixture 7', solve([{'z':[True,{'name':'Z'}],'a':[True,{'name':'A'}]},[['z','name'],['a','name']],N,N],), [N,[['ok','Z'],['ok','A']]])
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[1, [['ok', 'A1'], ['ok', None], ['ok', ''], ['ok', 'A1']]][1, [['ok', 'A1'], ['ok', None], ['ok', ''], ['ok', 'A1']]]Passed
contract fixture 2[1, [['unsupported', None], ['unsupported', None]]][1, [['unsupported', None], ['unsupported', None]]]Passed
contract fixture 3[1, [['gone', None], ['ok', 'secret']]][1, [['gone', None], ['gone', None]]]Failed
contract fixture 4[1, [['stale', None], ['stale', None]]][1, [['stale', None], ['stale', None]]]Passed
contract fixture 5[1, [['stale', None]]][1, [['stale', None]]]Passed
contract fixture 6[1, []][1, []]Passed
contract fixture 7[1, [['ok', 'Z'], ['ok', 'A']]][1, [['ok', 'Z'], ['ok', 'A']]]Passed

SHA-256 / 1d63c5c546dc5a0a481488587a86a2872382b949a0dc91878b00ac913cec87f5

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(data):
    objects,queries,revision,expected = data
    results = []
    for ident,prop in queries:
        if expected != revision: results.append(['stale',None]); continue
        record = objects.get(ident)
        if record is None or record[0] is None: results.append(['gone',None]); continue
        values = record[1]
        if prop not in {'name','value','description','role'} or prop not in values:
            results.append(['unsupported',None]); continue
        results.append(['ok',values.get(prop)])
    return [revision,results]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([{'a':[True,{'name':'A'+str(N),'value':None,'description':'','role':'image'}]},[['a','name'],['a','value'],['a','description'],['a','name']],N,N],), [N,[['ok','A'+str(N)],['ok',None],['ok',''],['ok','A'+str(N)]]])
check('contract fixture 2', solve([{'a':[True,{'secret':'s','name':'A'}]},[['a','secret'],['a','role']],N,N],), [N,[['unsupported',None],['unsupported',None]]])
check('contract fixture 3', solve([{'dead':[False,{'name':'secret'}]},[['missing','name'],['dead','name']],N,N],), [N,[['gone',None],['gone',None]]])
check('contract fixture 4', solve([{'a':[True,{'name':'A'}]},[['a','name'],['missing','role']],N,N-1],), [N,[['stale',None],['stale',None]]])
check('contract fixture 5', solve([{'a':[True,{'name':'A'}]},[['a','name']],N,N+1],), [N,[['stale',None]]])
check('contract fixture 6', solve([{},[],N,N],), [N,[]])
check('contract fixture 7', solve([{'z':[True,{'name':'Z'}],'a':[True,{'name':'A'}]},[['z','name'],['a','name']],N,N],), [N,[['ok','Z'],['ok','A']]])
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[1, [['ok', 'A1'], ['ok', None], ['ok', ''], ['ok', 'A1']]][1, [['ok', 'A1'], ['ok', None], ['ok', ''], ['ok', 'A1']]]Passed
contract fixture 2[1, [['unsupported', None], ['unsupported', None]]][1, [['unsupported', None], ['unsupported', None]]]Passed
contract fixture 3[1, [['gone', None], ['ok', 'secret']]][1, [['gone', None], ['gone', None]]]Failed
contract fixture 4[1, [['stale', None], ['stale', None]]][1, [['stale', None], ['stale', None]]]Passed
contract fixture 5[1, [['stale', None]]][1, [['stale', None]]]Passed
contract fixture 6[1, []][1, []]Passed
contract fixture 7[1, [['ok', 'Z'], ['ok', 'A']]][1, [['ok', 'Z'], ['ok', 'A']]]Passed

SHA-256 / 2790b043199bb1b5e406f26d920e19698546615e1813279d0da0409fa2c1e164

3 / The verified repair

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

N = 1
observations = []
def solve(data):
    objects,queries,revision,expected = data
    results = []
    for ident,prop in queries:
        if expected != revision: results.append(['stale',None]); continue
        record = objects.get(ident)
        if record is None or not record[0]: results.append(['gone',None]); continue
        values = record[1]
        if prop not in {'name','value','description','role'} or prop not in values:
            results.append(['unsupported',None]); continue
        results.append(['ok',values.get(prop)])
    return [revision,results]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('contract fixture 1', solve([{'a':[True,{'name':'A'+str(N),'value':None,'description':'','role':'image'}]},[['a','name'],['a','value'],['a','description'],['a','name']],N,N],), [N,[['ok','A'+str(N)],['ok',None],['ok',''],['ok','A'+str(N)]]])
check('contract fixture 2', solve([{'a':[True,{'secret':'s','name':'A'}]},[['a','secret'],['a','role']],N,N],), [N,[['unsupported',None],['unsupported',None]]])
check('contract fixture 3', solve([{'dead':[False,{'name':'secret'}]},[['missing','name'],['dead','name']],N,N],), [N,[['gone',None],['gone',None]]])
check('contract fixture 4', solve([{'a':[True,{'name':'A'}]},[['a','name'],['missing','role']],N,N-1],), [N,[['stale',None],['stale',None]]])
check('contract fixture 5', solve([{'a':[True,{'name':'A'}]},[['a','name']],N,N+1],), [N,[['stale',None]]])
check('contract fixture 6', solve([{},[],N,N],), [N,[]])
check('contract fixture 7', solve([{'z':[True,{'name':'Z'}],'a':[True,{'name':'A'}]},[['z','name'],['a','name']],N,N],), [N,[['ok','Z'],['ok','A']]])
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[1, [['ok', 'A1'], ['ok', None], ['ok', ''], ['ok', 'A1']]][1, [['ok', 'A1'], ['ok', None], ['ok', ''], ['ok', 'A1']]]Passed
contract fixture 2[1, [['unsupported', None], ['unsupported', None]]][1, [['unsupported', None], ['unsupported', None]]]Passed
contract fixture 3[1, [['gone', None], ['gone', None]]][1, [['gone', None], ['gone', None]]]Passed
contract fixture 4[1, [['stale', None], ['stale', None]]][1, [['stale', None], ['stale', None]]]Passed
contract fixture 5[1, [['stale', None]]][1, [['stale', None]]]Passed
contract fixture 6[1, []][1, []]Passed
contract fixture 7[1, [['ok', 'Z'], ['ok', 'A']]][1, [['ok', 'Z'], ['ok', 'A']]]Passed

SHA-256 / 648cdba9b1de295fe6afb170cb655067067abfa9d9367d15fa7efa9450647d53

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

Case digest / 1afa196b71957320281b472bedd8b5655360e7fe2b4272a0112e1ea4f71188fb