FA-8106 / Menu interactions / Open access
Menu item activation: Disabled menu commands still invoke actions · case 01
Disabled menu commands still invoke actions.
ROOT CAUSE
The disabled activation operation uses `if False:` where the contract requires `if item['disabled']:`.
VERIFIED REPAIR
Implement the disabled activation operation as `if item['disabled']:`.
Unsuccessful approach: Blocking enabled commands disables the entire menu.
Case contract
Disabled items and nonactivation keys do nothing; click, Enter and Space activate; submenu transfers focus; checks toggle; radios select; leaf commands close.
Why this case matters
A deterministic model of menu item activation; 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(item, opened, checked, event):
if False: return (opened, checked, None)
if event not in ('click', 'Enter', 'Space'): return (opened, checked, None)
if item['kind'] == 'submenu': return (True, checked, 'focus-child')
if item['kind'] == 'checkbox': return (opened, not checked, 'change')
if item['kind'] == 'radio': return (opened, True, 'change')
return (False, checked, 'invoke')
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve(dict(disabled=True,kind='command'), True, False, 'click'), (True, False, None))
check('enter', solve(dict(disabled=False,kind='command'), True, False, 'Enter'), (False, False, 'invoke'))
check('space', solve(dict(disabled=False,kind='command'), True, False, 'Space'), (False, False, 'invoke'))
check('submenu', solve(dict(disabled=False,kind='submenu'), False, False, 'click'), (True, False, 'focus-child'))
check('checkbox off', solve(dict(disabled=False,kind='checkbox'), True, True, 'click'), (True, False, 'change'))
check('radio stays', solve(dict(disabled=False,kind='radio'), True, True, 'click'), (True, True, 'change'))
check('ignore arrow', solve(dict(disabled=False,kind='command'), True, False, 'Left'), (True, False, None))
check('parameterized checked state', solve(dict(disabled=False,kind='checkbox'), True, bool(N%2), 'Space'), (True, not bool(N%2), 'change'))
for repetition in range(N):
check('repeat ignore arrow', solve(dict(disabled=False,kind='command'), True, False, 'Left'), (True, False, None))
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 |
|---|---|---|---|
| disabled | [False, False, 'invoke'] | [True, False, None] | Failed |
| enter | [False, False, 'invoke'] | [False, False, 'invoke'] | Passed |
| space | [False, False, 'invoke'] | [False, False, 'invoke'] | Passed |
| submenu | [True, False, 'focus-child'] | [True, False, 'focus-child'] | Passed |
| checkbox off | [True, False, 'change'] | [True, False, 'change'] | Passed |
| radio stays | [True, True, 'change'] | [True, True, 'change'] | Passed |
| ignore arrow | [True, False, None] | [True, False, None] | Passed |
| parameterized checked state | [True, False, 'change'] | [True, False, 'change'] | Passed |
| repeat ignore arrow | [True, False, None] | [True, False, None] | Passed |
SHA-256 / c96eae9946100ae2727aa8dd0d30e265e3d5197c077c899fea99f559a92bcea3
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(item, opened, checked, event):
if not item['disabled']: return (opened, checked, None)
if event not in ('click', 'Enter', 'Space'): return (opened, checked, None)
if item['kind'] == 'submenu': return (True, checked, 'focus-child')
if item['kind'] == 'checkbox': return (opened, not checked, 'change')
if item['kind'] == 'radio': return (opened, True, 'change')
return (False, checked, 'invoke')
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve(dict(disabled=True,kind='command'), True, False, 'click'), (True, False, None))
check('enter', solve(dict(disabled=False,kind='command'), True, False, 'Enter'), (False, False, 'invoke'))
check('space', solve(dict(disabled=False,kind='command'), True, False, 'Space'), (False, False, 'invoke'))
check('submenu', solve(dict(disabled=False,kind='submenu'), False, False, 'click'), (True, False, 'focus-child'))
check('checkbox off', solve(dict(disabled=False,kind='checkbox'), True, True, 'click'), (True, False, 'change'))
check('radio stays', solve(dict(disabled=False,kind='radio'), True, True, 'click'), (True, True, 'change'))
check('ignore arrow', solve(dict(disabled=False,kind='command'), True, False, 'Left'), (True, False, None))
check('parameterized checked state', solve(dict(disabled=False,kind='checkbox'), True, bool(N%2), 'Space'), (True, not bool(N%2), 'change'))
for repetition in range(N):
check('repeat ignore arrow', solve(dict(disabled=False,kind='command'), True, False, 'Left'), (True, False, None))
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 |
|---|---|---|---|
| disabled | [False, False, 'invoke'] | [True, False, None] | Failed |
| enter | [True, False, None] | [False, False, 'invoke'] | Failed |
| space | [True, False, None] | [False, False, 'invoke'] | Failed |
| submenu | [False, False, None] | [True, False, 'focus-child'] | Failed |
| checkbox off | [True, True, None] | [True, False, 'change'] | Failed |
| radio stays | [True, True, None] | [True, True, 'change'] | Failed |
| ignore arrow | [True, False, None] | [True, False, None] | Passed |
| parameterized checked state | [True, True, None] | [True, False, 'change'] | Failed |
| repeat ignore arrow | [True, False, None] | [True, False, None] | Passed |
SHA-256 / 78efe85c47862ea4d14f518d6e2ccec7be6c6d2a2c8e32302122d5ecd05471b3
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(item, opened, checked, event):
if item['disabled']: return (opened, checked, None)
if event not in ('click', 'Enter', 'Space'): return (opened, checked, None)
if item['kind'] == 'submenu': return (True, checked, 'focus-child')
if item['kind'] == 'checkbox': return (opened, not checked, 'change')
if item['kind'] == 'radio': return (opened, True, 'change')
return (False, checked, 'invoke')
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve(dict(disabled=True,kind='command'), True, False, 'click'), (True, False, None))
check('enter', solve(dict(disabled=False,kind='command'), True, False, 'Enter'), (False, False, 'invoke'))
check('space', solve(dict(disabled=False,kind='command'), True, False, 'Space'), (False, False, 'invoke'))
check('submenu', solve(dict(disabled=False,kind='submenu'), False, False, 'click'), (True, False, 'focus-child'))
check('checkbox off', solve(dict(disabled=False,kind='checkbox'), True, True, 'click'), (True, False, 'change'))
check('radio stays', solve(dict(disabled=False,kind='radio'), True, True, 'click'), (True, True, 'change'))
check('ignore arrow', solve(dict(disabled=False,kind='command'), True, False, 'Left'), (True, False, None))
check('parameterized checked state', solve(dict(disabled=False,kind='checkbox'), True, bool(N%2), 'Space'), (True, not bool(N%2), 'change'))
for repetition in range(N):
check('repeat ignore arrow', solve(dict(disabled=False,kind='command'), True, False, 'Left'), (True, False, None))
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 |
|---|---|---|---|
| disabled | [True, False, None] | [True, False, None] | Passed |
| enter | [False, False, 'invoke'] | [False, False, 'invoke'] | Passed |
| space | [False, False, 'invoke'] | [False, False, 'invoke'] | Passed |
| submenu | [True, False, 'focus-child'] | [True, False, 'focus-child'] | Passed |
| checkbox off | [True, False, 'change'] | [True, False, 'change'] | Passed |
| radio stays | [True, True, 'change'] | [True, True, 'change'] | Passed |
| ignore arrow | [True, False, None] | [True, False, None] | Passed |
| parameterized checked state | [True, False, 'change'] | [True, False, 'change'] | Passed |
| repeat ignore arrow | [True, False, None] | [True, False, None] | Passed |
SHA-256 / 07c93b96f2669cf8ba42e57ef6c586338983f5ed2f64fc3e16d41412264ce883
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:18.174113+00:00.
Case digest / f01daa63073dfc0903d4445ddab63299f1d20d45d934270ce319efb462b05a22