FAILURE MAP
← Case archive

FA-8471 / Assistive semantics / Open access

Accessible relationship resolution: Relationships resolve to incompatible widget roles · case 01

Relationships resolve to incompatible widget roles.

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

ROOT CAUSE

The role operation uses `if False: continue` where the contract requires `if registry[ident]['role'] != required_role: continue`.

VERIFIED REPAIR

Implement the role operation as `if registry[ident]['role'] != required_role: continue`.

Unsuccessful approach: Rejecting matching roles reverses compatibility.

Case contract

Resolve target IDs in caller order, deduplicate, and exclude self references, missing nodes, incompatible roles and hidden targets.

Why this case matters

A deterministic model of accessible relationship resolution; this isolates one interface invariant without requiring a browser.

1 / The failure

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

N = 1
observations = []
def solve(ids, registry, role, required_role, self_id):
    seen = set()
    result = []
    for ident in ids:
        if ident == self_id: continue
        if ident in seen: continue
        if ident not in registry: continue
        if False: continue
        if registry[ident]['hidden']: continue
        seen.add(ident)
        result.append(ident)
    return result
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('self', solve(['self','a'], {'self':{'role':'panel','hidden':False},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('dedup', solve(['a','a','b'], {'a':{'role':'panel','hidden':False},'b':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a', 'b'])
check('missing', solve(['a','gone','b'], {'a':{'role':'panel','hidden':False},'b':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a', 'b'])
check('role', solve(['bad','a'], {'bad':{'role':'button','hidden':False},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('hidden', solve(['bad','a'], {'bad':{'role':'panel','hidden':True},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('parameterized relationship identity', solve([str(N)], {str(N):dict(role='panel',hidden=False)}, 'tab', 'panel', 'self'), [str(N)])
for repetition in range(N):
    check('repeat hidden', solve(['bad','a'], {'bad':{'role':'panel','hidden':True},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['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
self['a']['a']Passed
dedup['a', 'b']['a', 'b']Passed
missing['a', 'b']['a', 'b']Passed
role['bad', 'a']['a']Failed
hidden['a']['a']Passed
parameterized relationship identity['1']['1']Passed
repeat hidden['a']['a']Passed

SHA-256 / d612d975689c7f80f9d0f16f515f3e5c65f86497107d347cdcb06d14339b2451

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(ids, registry, role, required_role, self_id):
    seen = set()
    result = []
    for ident in ids:
        if ident == self_id: continue
        if ident in seen: continue
        if ident not in registry: continue
        if registry[ident]['role'] == required_role: continue
        if registry[ident]['hidden']: continue
        seen.add(ident)
        result.append(ident)
    return result
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('self', solve(['self','a'], {'self':{'role':'panel','hidden':False},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('dedup', solve(['a','a','b'], {'a':{'role':'panel','hidden':False},'b':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a', 'b'])
check('missing', solve(['a','gone','b'], {'a':{'role':'panel','hidden':False},'b':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a', 'b'])
check('role', solve(['bad','a'], {'bad':{'role':'button','hidden':False},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('hidden', solve(['bad','a'], {'bad':{'role':'panel','hidden':True},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('parameterized relationship identity', solve([str(N)], {str(N):dict(role='panel',hidden=False)}, 'tab', 'panel', 'self'), [str(N)])
for repetition in range(N):
    check('repeat hidden', solve(['bad','a'], {'bad':{'role':'panel','hidden':True},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['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
self[]['a']Failed
dedup[]['a', 'b']Failed
missing[]['a', 'b']Failed
role['bad']['a']Failed
hidden[]['a']Failed
parameterized relationship identity[]['1']Failed
repeat hidden[]['a']Failed

SHA-256 / e2fe19990191a59a48f0f62015dfe1af4e13b10cd634aaa86a810c33bec15f12

3 / The verified repair

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

N = 1
observations = []
def solve(ids, registry, role, required_role, self_id):
    seen = set()
    result = []
    for ident in ids:
        if ident == self_id: continue
        if ident in seen: continue
        if ident not in registry: continue
        if registry[ident]['role'] != required_role: continue
        if registry[ident]['hidden']: continue
        seen.add(ident)
        result.append(ident)
    return result
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('self', solve(['self','a'], {'self':{'role':'panel','hidden':False},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('dedup', solve(['a','a','b'], {'a':{'role':'panel','hidden':False},'b':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a', 'b'])
check('missing', solve(['a','gone','b'], {'a':{'role':'panel','hidden':False},'b':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a', 'b'])
check('role', solve(['bad','a'], {'bad':{'role':'button','hidden':False},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('hidden', solve(['bad','a'], {'bad':{'role':'panel','hidden':True},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['a'])
check('parameterized relationship identity', solve([str(N)], {str(N):dict(role='panel',hidden=False)}, 'tab', 'panel', 'self'), [str(N)])
for repetition in range(N):
    check('repeat hidden', solve(['bad','a'], {'bad':{'role':'panel','hidden':True},'a':{'role':'panel','hidden':False}}, 'tab', 'panel', 'self'), ['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
self['a']['a']Passed
dedup['a', 'b']['a', 'b']Passed
missing['a', 'b']['a', 'b']Passed
role['a']['a']Passed
hidden['a']['a']Passed
parameterized relationship identity['1']['1']Passed
repeat hidden['a']['a']Passed

SHA-256 / 35c8f31361a84cc49c4586cbfae276274bf94ce235f540c7055c04419979d112

Verification & scope

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

Case digest / 2c2b0defb333d8085c8fdc54cba5fd79a408e7997ca05d02429e5b0444c86f6f