FAILURE MAP
← Case archive

FA-11391 / Accessibility interaction semantics / Open access

A visible child escapes a hidden ancestor · case 01

A descendant remains exposed despite a hidden container.

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

ROOT CAUSE

Each node is filtered independently instead of pruning hidden subtrees.

VERIFIED REPAIR

Carry the inherited hidden state through every ancestor.

Unsuccessful approach: Checking only the immediate parent still exposes grandchildren of a hidden node.

Case contract

Input is preorder [id,parent_id,hidden] for a forest with unique IDs and parents preceding children. Return exposed IDs in input order; any hidden ancestor excludes a node even if its own hidden flag is false.

Why this case matters

A controlled offline accessibility-data model. It isolates the stated contract; it does not simulate browser accessibility APIs or claim full ARIA conformance.

1 / The failure

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

N = 1
observations = []
def solve(nodes):
    return [ident for ident, parent, hidden in nodes if not hidden]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hidden grandparent', solve([('a',None,True),('b','a',False),(str(N),'b',False)]), [])
check('hidden parent', solve([('a',None,True),(str(N),'a',False)]), [])
check('visible ancestors', solve([('a',None,False),(str(N),'a',False)]), ['a',str(N)])
check('hidden leaf', solve([('a',None,False),(str(N),'a',True)]), ['a'])
check('independent roots', solve([('a',None,True),(str(N),None,False)]), [str(N)])
check('empty forest', solve([]), [])
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
hidden grandparent['b', '1'][]Failed
hidden parent['1'][]Failed
visible ancestors['a', '1']['a', '1']Passed
hidden leaf['a']['a']Passed
independent roots['1']['1']Passed
empty forest[][]Passed

SHA-256 / 5b3bc5c32f6190d4e8ca1be1fa67d580dfdda8f2c4a9a194a138fb9e12ff3392

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(nodes):
    flags = {ident: hidden for ident, parent, hidden in nodes}
    return [ident for ident, parent, hidden in nodes if not hidden and not flags.get(parent, False)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hidden grandparent', solve([('a',None,True),('b','a',False),(str(N),'b',False)]), [])
check('hidden parent', solve([('a',None,True),(str(N),'a',False)]), [])
check('visible ancestors', solve([('a',None,False),(str(N),'a',False)]), ['a',str(N)])
check('hidden leaf', solve([('a',None,False),(str(N),'a',True)]), ['a'])
check('independent roots', solve([('a',None,True),(str(N),None,False)]), [str(N)])
check('empty forest', solve([]), [])
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
hidden grandparent['1'][]Failed
hidden parent[][]Passed
visible ancestors['a', '1']['a', '1']Passed
hidden leaf['a']['a']Passed
independent roots['1']['1']Passed
empty forest[][]Passed

SHA-256 / 51044f99f38625973eac4598bf69feb73f032f90190f14adc4eaab927f64196d

3 / The verified repair

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

N = 1
observations = []
def solve(nodes):
    excluded = {}
    result = []
    for ident, parent, hidden in nodes:
        excluded[ident] = hidden or excluded.get(parent, False)
        if not excluded[ident]: result.append(ident)
    return result
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hidden grandparent', solve([('a',None,True),('b','a',False),(str(N),'b',False)]), [])
check('hidden parent', solve([('a',None,True),(str(N),'a',False)]), [])
check('visible ancestors', solve([('a',None,False),(str(N),'a',False)]), ['a',str(N)])
check('hidden leaf', solve([('a',None,False),(str(N),'a',True)]), ['a'])
check('independent roots', solve([('a',None,True),(str(N),None,False)]), [str(N)])
check('empty forest', solve([]), [])
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
hidden grandparent[][]Passed
hidden parent[][]Passed
visible ancestors['a', '1']['a', '1']Passed
hidden leaf['a']['a']Passed
independent roots['1']['1']Passed
empty forest[][]Passed

SHA-256 / 5b1cd697dce82c1162e788a12f4b59281b44707ac9a69695b6ce8834df48ce2a

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

Case digest / 7c7e936550c8f54676a80b1990bd679b64416da90f8d68ce30674025a82c25f9