FA-7881 / Keyboard accessibility / Open access
Roving tabindex navigation: Home fails to reach the first enabled item · case 01
Home fails to reach the first enabled item.
ROOT CAUSE
The home operation uses `if key == 'Home': return current` where the contract requires `if key == 'Home': return enabled[0]`.
VERIFIED REPAIR
Implement the home operation as `if key == 'Home': return enabled[0]`.
Unsuccessful approach: Routing Home to the last item swaps endpoint semantics.
Case contract
Home and End select enabled endpoints; horizontal arrows honor directionality and wrap; a removed current item resets to the first enabled item.
Why this case matters
A deterministic model of roving tabindex navigation; 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(enabled, current, key, rtl):
if not enabled: return None
if key == 'Home': return current
if key == 'End': return enabled[-1]
step = (-1 if key == 'Left' else 1) * (-1 if rtl else 1)
if current not in enabled: return enabled[0]
return enabled[(enabled.index(current) + step) % len(enabled)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('home', solve([1,3,7], 3, 'Home', False), 1)
check('end', solve([1,3,7], 3, 'End', False), 7)
check('rtl right', solve([1,3,7], 3, 'Right', True), 1)
check('ltr right', solve([1,3,7], 3, 'Right', False), 7)
check('removed', solve([1,3,7], 8, 'Right', False), 1)
check('wrap', solve([1,3,7], 7, 'Right', False), 1)
check('empty', solve([], 0, 'Home', False), None)
check('parameterized arrow', solve(list(range(N+3)), N, 'Right', False), N+1)
for repetition in range(N):
check('repeat empty', solve([], 0, 'Home', 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 |
|---|---|---|---|
| home | 3 | 1 | Failed |
| end | 7 | 7 | Passed |
| rtl right | 1 | 1 | Passed |
| ltr right | 7 | 7 | Passed |
| removed | 1 | 1 | Passed |
| wrap | 1 | 1 | Passed |
| empty | None | None | Passed |
| parameterized arrow | 2 | 2 | Passed |
| repeat empty | None | None | Passed |
SHA-256 / 1f028ce419b24bba5deedee82feccafaa6157c218868fd694c0531bd3283eb68
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(enabled, current, key, rtl):
if not enabled: return None
if key == 'Home': return enabled[-1]
if key == 'End': return enabled[-1]
step = (-1 if key == 'Left' else 1) * (-1 if rtl else 1)
if current not in enabled: return enabled[0]
return enabled[(enabled.index(current) + step) % len(enabled)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('home', solve([1,3,7], 3, 'Home', False), 1)
check('end', solve([1,3,7], 3, 'End', False), 7)
check('rtl right', solve([1,3,7], 3, 'Right', True), 1)
check('ltr right', solve([1,3,7], 3, 'Right', False), 7)
check('removed', solve([1,3,7], 8, 'Right', False), 1)
check('wrap', solve([1,3,7], 7, 'Right', False), 1)
check('empty', solve([], 0, 'Home', False), None)
check('parameterized arrow', solve(list(range(N+3)), N, 'Right', False), N+1)
for repetition in range(N):
check('repeat empty', solve([], 0, 'Home', 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 |
|---|---|---|---|
| home | 7 | 1 | Failed |
| end | 7 | 7 | Passed |
| rtl right | 1 | 1 | Passed |
| ltr right | 7 | 7 | Passed |
| removed | 1 | 1 | Passed |
| wrap | 1 | 1 | Passed |
| empty | None | None | Passed |
| parameterized arrow | 2 | 2 | Passed |
| repeat empty | None | None | Passed |
SHA-256 / 181169c2b851e02c03935f3ca96084d3e8acdb9d18ff4d7297719edafae45618
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(enabled, current, key, rtl):
if not enabled: return None
if key == 'Home': return enabled[0]
if key == 'End': return enabled[-1]
step = (-1 if key == 'Left' else 1) * (-1 if rtl else 1)
if current not in enabled: return enabled[0]
return enabled[(enabled.index(current) + step) % len(enabled)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('home', solve([1,3,7], 3, 'Home', False), 1)
check('end', solve([1,3,7], 3, 'End', False), 7)
check('rtl right', solve([1,3,7], 3, 'Right', True), 1)
check('ltr right', solve([1,3,7], 3, 'Right', False), 7)
check('removed', solve([1,3,7], 8, 'Right', False), 1)
check('wrap', solve([1,3,7], 7, 'Right', False), 1)
check('empty', solve([], 0, 'Home', False), None)
check('parameterized arrow', solve(list(range(N+3)), N, 'Right', False), N+1)
for repetition in range(N):
check('repeat empty', solve([], 0, 'Home', 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 |
|---|---|---|---|
| home | 1 | 1 | Passed |
| end | 7 | 7 | Passed |
| rtl right | 1 | 1 | Passed |
| ltr right | 7 | 7 | Passed |
| removed | 1 | 1 | Passed |
| wrap | 1 | 1 | Passed |
| empty | None | None | Passed |
| parameterized arrow | 2 | 2 | Passed |
| repeat empty | None | None | Passed |
SHA-256 / e682b0bd63403014ba0e32c92b4cff3ac8d294f86c791f9d2b91ae33a2741024
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:16.130199+00:00.
Case digest / 224bdb8884b05ecc99ba4f3ea9a95b2432732092bd340140661477bf0541d69a