FAILURE MAP
← Case archive

FA-39066 / Tree accessibility / Open access

Hierarchical clipboard root normalization: Copied branches are exposed as pending cut · case 01

Copied branches are exposed as pending cut produces the wrong hierarchical widget state in a regression fixture.

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

ROOT CAUSE

The subtree-clipboard contract is violated at `allowed if d['mode']=='cut' else []` by replacing it with `allowed`.

VERIFIED REPAIR

Restore `allowed if d['mode']=='cut' else []` at this fault site while retaining the other tree state decisions.

Unsuccessful approach: The partial repair `[]` still violates a boundary or preservation case.

Case contract

Copy or cut operates on selected topmost roots only, excluding descendants of a selected root. Roots follow tree order. Cut excludes read-only roots, retains protected selection, and advertises a move only within the same tree generation. Clipboard payload carries selected root paths and descendants once.

Why this case matters

Offline executable model of a hierarchical accessibility interaction; inputs are bounded and valid as stipulated. No browser, assistive technology, or normative ARIA conformance is claimed.

1 / The failure

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

N = 1
observations = []
def solve(d):
    selected=set(d['selected'])&set(d['rows'])
    roots=[x for x in d['rows'] if x in selected and not any(a in selected for a in d['ancestors'].get(x,[]))]
    allowed=[x for x in roots if d['mode']=='copy' or x not in d['readonly']]
    closure=[x for x in d['rows'] if x in allowed or any(a in allowed for a in d['ancestors'].get(x,[]))]
    paths={x:d['ancestors'].get(x,[])+[x] for x in allowed}
    cut=allowed
    valid=d['clipboard_generation']==d['generation']
    effect='move' if cut and valid and d['same_tree'] else ('copy' if allowed else 'none')
    remaining=[x for x in d['selected'] if x not in closure] if effect=='move' else d['selected']
    focus=allowed[0] if allowed else d['focus']
    return [allowed,closure,paths,cut,effect,remaining,focus]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {1: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 0, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 2: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 3: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 4: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 5: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])]}
for label, data, expected in cases[N]:
    check(label, solve(data), expected)
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
cut normalized[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']Passed
copy protected[['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a'][['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']Failed
several roots[['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a'][['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']Passed
stale cut[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']Passed
cross tree[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']Passed
no selection[[], [], {}, [], 'none', [], 'c'][[], [], {}, [], 'none', [], 'c']Passed
descendant alone[['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'][['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b']Passed

SHA-256 / 2a6f59c182d1857fd2d4e51eaacb3ec559c60e7b824899b97cf2cb9701bd739c

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(d):
    selected=set(d['selected'])&set(d['rows'])
    roots=[x for x in d['rows'] if x in selected and not any(a in selected for a in d['ancestors'].get(x,[]))]
    allowed=[x for x in roots if d['mode']=='copy' or x not in d['readonly']]
    closure=[x for x in d['rows'] if x in allowed or any(a in allowed for a in d['ancestors'].get(x,[]))]
    paths={x:d['ancestors'].get(x,[])+[x] for x in allowed}
    cut=[]
    valid=d['clipboard_generation']==d['generation']
    effect='move' if cut and valid and d['same_tree'] else ('copy' if allowed else 'none')
    remaining=[x for x in d['selected'] if x not in closure] if effect=='move' else d['selected']
    focus=allowed[0] if allowed else d['focus']
    return [allowed,closure,paths,cut,effect,remaining,focus]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {1: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 0, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 2: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 3: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 4: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 5: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])]}
for label, data, expected in cases[N]:
    check(label, solve(data), expected)
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
cut normalized[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, [], 'copy', ['a', 'b', 'q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']Failed
copy protected[['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a'][['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']Passed
several roots[['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a'][['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']Failed
stale cut[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, [], 'copy', ['a', 'b', 'q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']Failed
cross tree[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, [], 'copy', ['a', 'b', 'q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']Failed
no selection[[], [], {}, [], 'none', [], 'c'][[], [], {}, [], 'none', [], 'c']Passed
descendant alone[['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, [], 'copy', ['b'], 'b'][['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b']Failed

SHA-256 / 24c6a35aa05d0d1977c3ef9f679918b3bab8e66d31da77bec6ef41c52707e48f

3 / The verified repair

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

N = 1
observations = []
def solve(d):
    selected=set(d['selected'])&set(d['rows'])
    roots=[x for x in d['rows'] if x in selected and not any(a in selected for a in d['ancestors'].get(x,[]))]
    allowed=[x for x in roots if d['mode']=='copy' or x not in d['readonly']]
    closure=[x for x in d['rows'] if x in allowed or any(a in allowed for a in d['ancestors'].get(x,[]))]
    paths={x:d['ancestors'].get(x,[])+[x] for x in allowed}
    cut=allowed if d['mode']=='cut' else []
    valid=d['clipboard_generation']==d['generation']
    effect='move' if cut and valid and d['same_tree'] else ('copy' if allowed else 'none')
    remaining=[x for x in d['selected'] if x not in closure] if effect=='move' else d['selected']
    focus=allowed[0] if allowed else d['focus']
    return [allowed,closure,paths,cut,effect,remaining,focus]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {1: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 0, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 1, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 2: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 1, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 2, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 3: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 2, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 3, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 4: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 3, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 4, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])], 5: [('cut normalized', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']), ('copy protected', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'copy', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']), ('several roots', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': [], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']), ('stale cut', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 4, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('cross tree', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['a', 'b', 'q'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': False, 'focus': 'c'}, [['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']), ('no selection', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': [], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [[], [], {}, [], 'none', [], 'c']), ('descendant alone', {'rows': ['z', 'a', 'b', 'c', 'q', 'v0', 'v1', 'v2', 'v3', 'v4'], 'selected': ['b'], 'ancestors': {'a': ['z'], 'b': ['z', 'a'], 'c': ['z', 'a', 'b']}, 'mode': 'cut', 'readonly': ['q'], 'clipboard_generation': 5, 'generation': 5, 'same_tree': True, 'focus': 'c'}, [['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'])]}
for label, data, expected in cases[N]:
    check(label, solve(data), expected)
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
cut normalized[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'move', ['q'], 'a']Passed
copy protected[['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a'][['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, [], 'copy', ['a', 'b', 'q'], 'a']Passed
several roots[['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a'][['a', 'q'], ['a', 'b', 'c', 'q'], {'a': ['z', 'a'], 'q': ['q']}, ['a', 'q'], 'move', [], 'a']Passed
stale cut[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']Passed
cross tree[['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a'][['a'], ['a', 'b', 'c'], {'a': ['z', 'a']}, ['a'], 'copy', ['a', 'b', 'q'], 'a']Passed
no selection[[], [], {}, [], 'none', [], 'c'][[], [], {}, [], 'none', [], 'c']Passed
descendant alone[['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b'][['b'], ['b', 'c'], {'b': ['z', 'a', 'b']}, ['b'], 'move', [], 'b']Passed

SHA-256 / 2df50c75efd7213985a426362aebf1743059d180dd34d96a9cd36e24b00569a4

Verification & scope

Synthetic deterministic hierarchical-widget data contract; not an implementation of a browser accessibility tree. 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:43:17.520649+00:00.

Case digest / 427319590353a2b5bab95b55028def6d9c84a89829fcf48b89a93903f34905bc