FAILURE MAP
← Case archive

FA-8386 / Tree accessibility / Open access

Tree keyboard expansion: Right-arrow on an expanded parent focuses its last child · case 01

Right-arrow on an expanded parent focuses its last child.

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

ROOT CAUSE

The enter child operation uses `node = kids[-1]` where the contract requires `node = kids[0]`.

VERIFIED REPAIR

Implement the enter child operation as `node = kids[0]`.

Unsuccessful approach: Keeping focus on the parent prevents descending.

Case contract

Right expands then enters the first child; Left collapses only the current branch or focuses its parent; roots retain focus; collapse-all clears every expansion.

Why this case matters

A deterministic model of tree keyboard expansion; 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(node, expanded, parents, children, key):
    expanded = set(expanded)
    kids = children.get(node, [])
    if key == 'Right' and kids:
        if node not in expanded: expanded.add(node)
        else: node = kids[-1]
    elif key == 'Left':
        if node in expanded: expanded.remove(node)
        else: node = parents.get(node, node)
    elif key == 'CollapseAll': expanded.clear()
    return (node, sorted(expanded))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('expand', solve('a', ['z'], {}, {'a':['b','c']}, 'Right'), ('a', ['a', 'z']))
check('descend', solve('a', ['a'], {}, {'a':['b','c']}, 'Right'), ('b', ['a']))
check('collapse', solve('a', ['a','z'], {}, {'a':['b']}, 'Left'), ('a', ['z']))
check('parent', solve('b', [], {'b':'a'}, {}, 'Left'), ('a', []))
check('root', solve('a', [], {}, {}, 'Left'), ('a', []))
check('all', solve('a', ['a','z'], {}, {}, 'CollapseAll'), ('a', []))
check('parameterized child count', solve('a', [], {}, {'a':list(range(N))}, 'Right'), ('a',['a']))
for repetition in range(N):
    check('repeat all', solve('a', ['a','z'], {}, {}, 'CollapseAll'), ('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
expand['a', ['a', 'z']]['a', ['a', 'z']]Passed
descend['c', ['a']]['b', ['a']]Failed
collapse['a', ['z']]['a', ['z']]Passed
parent['a', []]['a', []]Passed
root['a', []]['a', []]Passed
all['a', []]['a', []]Passed
parameterized child count['a', ['a']]['a', ['a']]Passed
repeat all['a', []]['a', []]Passed

SHA-256 / de7ea0a2f1e28f9157d9c7228f1705fa7ca0d9c60f71ee1f30400a4114a1cae8

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(node, expanded, parents, children, key):
    expanded = set(expanded)
    kids = children.get(node, [])
    if key == 'Right' and kids:
        if node not in expanded: expanded.add(node)
        else: node = node
    elif key == 'Left':
        if node in expanded: expanded.remove(node)
        else: node = parents.get(node, node)
    elif key == 'CollapseAll': expanded.clear()
    return (node, sorted(expanded))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('expand', solve('a', ['z'], {}, {'a':['b','c']}, 'Right'), ('a', ['a', 'z']))
check('descend', solve('a', ['a'], {}, {'a':['b','c']}, 'Right'), ('b', ['a']))
check('collapse', solve('a', ['a','z'], {}, {'a':['b']}, 'Left'), ('a', ['z']))
check('parent', solve('b', [], {'b':'a'}, {}, 'Left'), ('a', []))
check('root', solve('a', [], {}, {}, 'Left'), ('a', []))
check('all', solve('a', ['a','z'], {}, {}, 'CollapseAll'), ('a', []))
check('parameterized child count', solve('a', [], {}, {'a':list(range(N))}, 'Right'), ('a',['a']))
for repetition in range(N):
    check('repeat all', solve('a', ['a','z'], {}, {}, 'CollapseAll'), ('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
expand['a', ['a', 'z']]['a', ['a', 'z']]Passed
descend['a', ['a']]['b', ['a']]Failed
collapse['a', ['z']]['a', ['z']]Passed
parent['a', []]['a', []]Passed
root['a', []]['a', []]Passed
all['a', []]['a', []]Passed
parameterized child count['a', ['a']]['a', ['a']]Passed
repeat all['a', []]['a', []]Passed

SHA-256 / 277676f442897ee21b03a98f0afce6b45e150238f6764f5ae43f29c27618d357

3 / The verified repair

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

N = 1
observations = []
def solve(node, expanded, parents, children, key):
    expanded = set(expanded)
    kids = children.get(node, [])
    if key == 'Right' and kids:
        if node not in expanded: expanded.add(node)
        else: node = kids[0]
    elif key == 'Left':
        if node in expanded: expanded.remove(node)
        else: node = parents.get(node, node)
    elif key == 'CollapseAll': expanded.clear()
    return (node, sorted(expanded))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('expand', solve('a', ['z'], {}, {'a':['b','c']}, 'Right'), ('a', ['a', 'z']))
check('descend', solve('a', ['a'], {}, {'a':['b','c']}, 'Right'), ('b', ['a']))
check('collapse', solve('a', ['a','z'], {}, {'a':['b']}, 'Left'), ('a', ['z']))
check('parent', solve('b', [], {'b':'a'}, {}, 'Left'), ('a', []))
check('root', solve('a', [], {}, {}, 'Left'), ('a', []))
check('all', solve('a', ['a','z'], {}, {}, 'CollapseAll'), ('a', []))
check('parameterized child count', solve('a', [], {}, {'a':list(range(N))}, 'Right'), ('a',['a']))
for repetition in range(N):
    check('repeat all', solve('a', ['a','z'], {}, {}, 'CollapseAll'), ('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
expand['a', ['a', 'z']]['a', ['a', 'z']]Passed
descend['b', ['a']]['b', ['a']]Passed
collapse['a', ['z']]['a', ['z']]Passed
parent['a', []]['a', []]Passed
root['a', []]['a', []]Passed
all['a', []]['a', []]Passed
parameterized child count['a', ['a']]['a', ['a']]Passed
repeat all['a', []]['a', []]Passed

SHA-256 / d8cc0e4d8b47f71a93b2eb97d9a27e6666808598de5a935b5c45db1e6e515900

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

Case digest / 9b95adf83f8a5aa49aa2d924e12deb16b4ad4e502b1fc8d40314ef40169609b6