FA-11401 / Accessibility interaction semantics / Open access
A global recursion guard erases a repeated label branch · case 01
Shared text is lost in a label-reference graph, or a cycle prevents termination.
ROOT CAUSE
Reference traversal conflates previously visited nodes with ancestors on the current traversal path.
VERIFIED REPAIR
Cut only edges returning to the current recursion path and keep independent branch occurrences.
Unsuccessful approach: A global visited set stops cycles but incorrectly suppresses a shared node reached by two independent branches.
Case contract
Controlled label graph: each node has [local_text,ordered_reference_ids]. Resolve the root by concatenating its local text and recursively resolved references with spaces, omitting missing nodes and edges to path ancestors. Shared nodes contribute once per path. Graph size is bounded by fixtures.
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(graph, root):
def visit(key, depth=0):
if key not in graph or depth > len(graph): return []
text, refs = graph[key]
return ([text] if text else []) + [part for ref in refs for part in visit(ref,depth+1)]
return ' '.join(visit(root))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('self cycle', solve({'a':[str(N),['a']]}, 'a'), str(N))
check('two node cycle', solve({'a':['A',['b']], 'b':[str(N),['a']]}, 'a'), 'A '+str(N))
check('shared diamond', solve({'a':['',['b','c']], 'b':['B',['d']], 'c':['C',['d']], 'd':[str(N),[]]}, 'a'), 'B '+str(N)+' C '+str(N))
check('missing root', solve({}, str(N)), '')
check('dangling branch', solve({'a':[str(N),['gone']]}, 'a'), str(N))
check('ordered branches', solve({'a':['',['c','b']], 'b':['B',[]], 'c':[str(N),[]]}, 'a'), str(N)+' B')
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 |
|---|---|---|---|
| self cycle | 1 1 | 1 | Failed |
| two node cycle | A 1 A | A 1 | Failed |
| shared diamond | B 1 C 1 | B 1 C 1 | Passed |
| missing root | | | Passed |
| dangling branch | 1 | 1 | Passed |
| ordered branches | 1 B | 1 B | Passed |
SHA-256 / 00d0633c3e292ebdaad54b9751fc30805c5bd22617a33ced8fee6abeb2beca3b
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(graph, root):
seen = set()
def visit(key):
if key not in graph or key in seen: return []
seen.add(key)
text,refs = graph[key]
return ([text] if text else []) + [part for ref in refs for part in visit(ref)]
return ' '.join(visit(root))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('self cycle', solve({'a':[str(N),['a']]}, 'a'), str(N))
check('two node cycle', solve({'a':['A',['b']], 'b':[str(N),['a']]}, 'a'), 'A '+str(N))
check('shared diamond', solve({'a':['',['b','c']], 'b':['B',['d']], 'c':['C',['d']], 'd':[str(N),[]]}, 'a'), 'B '+str(N)+' C '+str(N))
check('missing root', solve({}, str(N)), '')
check('dangling branch', solve({'a':[str(N),['gone']]}, 'a'), str(N))
check('ordered branches', solve({'a':['',['c','b']], 'b':['B',[]], 'c':[str(N),[]]}, 'a'), str(N)+' B')
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 |
|---|---|---|---|
| self cycle | 1 | 1 | Passed |
| two node cycle | A 1 | A 1 | Passed |
| shared diamond | B 1 C | B 1 C 1 | Failed |
| missing root | | | Passed |
| dangling branch | 1 | 1 | Passed |
| ordered branches | 1 B | 1 B | Passed |
SHA-256 / b8870589e86541e7f9dd85dbe0c3884ec2895117b28eaf9b09fd0ec27fe70c0e
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(graph, root):
def visit(key, path):
if key not in graph or key in path: return []
text,refs = graph[key]
return ([text] if text else []) + [part for ref in refs for part in visit(ref,path | {key})]
return ' '.join(visit(root,set()))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('self cycle', solve({'a':[str(N),['a']]}, 'a'), str(N))
check('two node cycle', solve({'a':['A',['b']], 'b':[str(N),['a']]}, 'a'), 'A '+str(N))
check('shared diamond', solve({'a':['',['b','c']], 'b':['B',['d']], 'c':['C',['d']], 'd':[str(N),[]]}, 'a'), 'B '+str(N)+' C '+str(N))
check('missing root', solve({}, str(N)), '')
check('dangling branch', solve({'a':[str(N),['gone']]}, 'a'), str(N))
check('ordered branches', solve({'a':['',['c','b']], 'b':['B',[]], 'c':[str(N),[]]}, 'a'), str(N)+' B')
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 |
|---|---|---|---|
| self cycle | 1 | 1 | Passed |
| two node cycle | A 1 | A 1 | Passed |
| shared diamond | B 1 C 1 | B 1 C 1 | Passed |
| missing root | | | Passed |
| dangling branch | 1 | 1 | Passed |
| ordered branches | 1 B | 1 B | Passed |
SHA-256 / 2a57777aee75cd2c8d2e224a7cff2d69fbc272a0a5dc68aecf39ce35a3c94963
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.530977+00:00.
Case digest / 8a14a0f158ef723ecdf560fd9218fd9372ec5dc41d2add7810abb8b16f4f97ca