FAILURE MAP
← Case archive

FA-8401 / Tree accessibility / Open access

Tree keyboard expansion: Collapse-all leaves unrelated expanded branches open · case 01

Collapse-all leaves unrelated expanded branches open.

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

ROOT CAUSE

The collapse all operation uses `elif key == 'CollapseAll': expanded.discard(node)` where the contract requires `elif key == 'CollapseAll': expanded.clear()`.

VERIFIED REPAIR

Implement the collapse all operation as `elif key == 'CollapseAll': expanded.clear()`.

Unsuccessful approach: Adding the current node opens a branch instead of closing all.

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[0]
    elif key == 'Left':
        if node in expanded: expanded.remove(node)
        else: node = parents.get(node, node)
    elif key == 'CollapseAll': expanded.discard(node)
    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', ['z']]['a', []]Failed
parameterized child count['a', ['a']]['a', ['a']]Passed
repeat all['a', ['z']]['a', []]Failed

SHA-256 / 1bf6133744ea5663a6eca333c6a7e4d1442251c0100efe1f2759a80c46c902e8

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 = kids[0]
    elif key == 'Left':
        if node in expanded: expanded.remove(node)
        else: node = parents.get(node, node)
    elif key == 'CollapseAll': expanded.add(node)
    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', 'z']]['a', []]Failed
parameterized child count['a', ['a']]['a', ['a']]Passed
repeat all['a', ['a', 'z']]['a', []]Failed

SHA-256 / 01acf5e6a11aba2c5b5a8379de52fe51ee5c8fbe59c9c407bdb308eefe7de09b

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

Case digest / 9da93dd1b8899f19ff07289d0aa56e678267fc21310b7c13d49db73cee277d97