FA-11396 / Accessibility interaction semantics / Open access
Removing a presentational wrapper deletes its meaningful descendants · case 01
A text-bearing child disappears when its structural wrapper has no exposed role.
ROOT CAUSE
Suppressing wrapper semantics is confused with suppressing the entire subtree.
VERIFIED REPAIR
Map each presentational wrapper to its nearest exposed ancestor before assigning child parents.
Unsuccessful approach: Keeping every descendant as a root preserves content but destroys the nearest meaningful parent relationship.
Case contract
Input is preorder [id,parent,presentational] with unique IDs and earlier parents. Return [id,exposed_parent] for nonpresentational nodes. Presentational nodes disappear but their descendants retain the nearest nonpresentational ancestor, or None.
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):
gone = set()
result = []
for ident,parent,presentation in nodes:
if presentation or parent in gone: gone.add(ident)
else: result.append([ident,parent])
return result
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('nested wrapper', solve([('a',None,False),('w','a',True),(str(N),'w',False)]), [['a',None],[str(N),'a']])
check('root wrapper', solve([('w',None,True),(str(N),'w',False)]), [[str(N),None]])
check('multiple wrappers', solve([('a',None,False),('w','a',True),('v','w',True),(str(N),'v',False)]), [['a',None],[str(N),'a']])
check('meaningful child parent', solve([('a',None,False),('b','a',False),(str(N),'b',False)]), [['a',None],['b','a'],[str(N),'b']])
check('only wrapper', solve([(str(N),None,True)]), [])
check('empty', 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| nested wrapper | [['a', None]] | [['a', None], ['1', 'a']] | Failed |
| root wrapper | [] | [['1', None]] | Failed |
| multiple wrappers | [['a', None]] | [['a', None], ['1', 'a']] | Failed |
| meaningful child parent | [['a', None], ['b', 'a'], ['1', 'b']] | [['a', None], ['b', 'a'], ['1', 'b']] | Passed |
| only wrapper | [] | [] | Passed |
| empty | [] | [] | Passed |
SHA-256 / aaf2e652d045c496359d4e8925f19bc65f69a20ce6b2d21e16c913eaf1d8f809
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(nodes):
present = {ident for ident,parent,presentation in nodes if presentation}
return [[ident, None if parent in present else parent] for ident,parent,presentation in nodes if not presentation]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('nested wrapper', solve([('a',None,False),('w','a',True),(str(N),'w',False)]), [['a',None],[str(N),'a']])
check('root wrapper', solve([('w',None,True),(str(N),'w',False)]), [[str(N),None]])
check('multiple wrappers', solve([('a',None,False),('w','a',True),('v','w',True),(str(N),'v',False)]), [['a',None],[str(N),'a']])
check('meaningful child parent', solve([('a',None,False),('b','a',False),(str(N),'b',False)]), [['a',None],['b','a'],[str(N),'b']])
check('only wrapper', solve([(str(N),None,True)]), [])
check('empty', 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| nested wrapper | [['a', None], ['1', None]] | [['a', None], ['1', 'a']] | Failed |
| root wrapper | [['1', None]] | [['1', None]] | Passed |
| multiple wrappers | [['a', None], ['1', None]] | [['a', None], ['1', 'a']] | Failed |
| meaningful child parent | [['a', None], ['b', 'a'], ['1', 'b']] | [['a', None], ['b', 'a'], ['1', 'b']] | Passed |
| only wrapper | [] | [] | Passed |
| empty | [] | [] | Passed |
SHA-256 / 53bd37219f654ea40cf05b02a92d44e822b1a30f49cb8a0f3a5bf24a19238c11
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(nodes):
nearest = {None: None}
result = []
for ident,parent,presentation in nodes:
ancestor = nearest[parent]
nearest[ident] = ancestor if presentation else ident
if not presentation: result.append([ident,ancestor])
return result
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('nested wrapper', solve([('a',None,False),('w','a',True),(str(N),'w',False)]), [['a',None],[str(N),'a']])
check('root wrapper', solve([('w',None,True),(str(N),'w',False)]), [[str(N),None]])
check('multiple wrappers', solve([('a',None,False),('w','a',True),('v','w',True),(str(N),'v',False)]), [['a',None],[str(N),'a']])
check('meaningful child parent', solve([('a',None,False),('b','a',False),(str(N),'b',False)]), [['a',None],['b','a'],[str(N),'b']])
check('only wrapper', solve([(str(N),None,True)]), [])
check('empty', 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| nested wrapper | [['a', None], ['1', 'a']] | [['a', None], ['1', 'a']] | Passed |
| root wrapper | [['1', None]] | [['1', None]] | Passed |
| multiple wrappers | [['a', None], ['1', 'a']] | [['a', None], ['1', 'a']] | Passed |
| meaningful child parent | [['a', None], ['b', 'a'], ['1', 'b']] | [['a', None], ['b', 'a'], ['1', 'b']] | Passed |
| only wrapper | [] | [] | Passed |
| empty | [] | [] | Passed |
SHA-256 / 31848d8967daba617f1d8126ac18d396289f17d42cf901d1afdfa760aa6e373c
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.493339+00:00.
Case digest / 47110da19cce9cd7af9a1a9c4bb3106cb84c897e8ad53d58cbf1c37f0aa158a9