FAILURE MAP
← Case archive

FA-8591 / Tab interfaces / Open access

Tab selection and activation mode: Next-tab traversal runs backwards · case 01

Next-tab traversal runs backwards.

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

ROOT CAUSE

The next operation uses `(available.index(focused)-1) % len(available)` where the contract requires `(available.index(focused)+1) % len(available)`.

VERIFIED REPAIR

Implement the next operation as `(available.index(focused)+1) % len(available)`.

Unsuccessful approach: Holding position prevents traversal entirely.

Case contract

Focus traverses enabled tabs; automatic mode activates on focus, manual mode requires Enter or Space; removed focus or selection falls back to first enabled tab.

Why this case matters

A deterministic model of tab selection and activation mode; 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(tabs, focused, selected, key, automatic, disabled):
    available = [t for t in tabs if t not in disabled]
    if not available: return (None, None)
    if focused not in available: focused = available[0]
    if key == 'Next': focused = available[(available.index(focused)-1) % len(available)]
    if key == 'Previous': focused = available[(available.index(focused)-1) % len(available)]
    if automatic or key in ('Enter','Space'): selected = focused
    if selected not in available: selected = available[0]
    return (focused, selected)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve(['a','b','c'], 'a', 'a', 'Next', True, ['b']), ('c', 'c'))
check('removed focus', solve(['a','b','c'], 'gone', 'a', 'none', False, []), ('a', 'a'))
check('next', solve(['a','b','c'], 'a', 'a', 'Next', True, []), ('b', 'b'))
check('manual', solve(['a','b','c'], 'a', 'a', 'Next', False, []), ('b', 'a'))
check('space', solve(['a','b'], 'b', 'a', 'Space', False, []), ('b', 'b'))
check('removed selection', solve(['a','b'], 'b', 'gone', 'none', False, []), ('b', 'a'))
check('empty', solve([], None, None, 'Next', True, []), (None, None))
check('parameterized tab identities', solve(list(range(N+2)), N, N, 'Next', True, []), (N+1,N+1))
for repetition in range(N):
    check('repeat empty', solve([], None, None, 'Next', True, []), (None, 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 fixtureActualExpectedOutcome
disabled['c', 'c']['c', 'c']Passed
removed focus['a', 'a']['a', 'a']Passed
next['c', 'c']['b', 'b']Failed
manual['c', 'a']['b', 'a']Failed
space['b', 'b']['b', 'b']Passed
removed selection['b', 'a']['b', 'a']Passed
empty[None, None][None, None]Passed
parameterized tab identities[0, 0][2, 2]Failed
repeat empty[None, None][None, None]Passed

SHA-256 / a33054ede78a5a743c75bb0483097014961c2033aa248e99e18b31f9e7cb0243

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(tabs, focused, selected, key, automatic, disabled):
    available = [t for t in tabs if t not in disabled]
    if not available: return (None, None)
    if focused not in available: focused = available[0]
    if key == 'Next': focused = available[available.index(focused)]
    if key == 'Previous': focused = available[(available.index(focused)-1) % len(available)]
    if automatic or key in ('Enter','Space'): selected = focused
    if selected not in available: selected = available[0]
    return (focused, selected)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve(['a','b','c'], 'a', 'a', 'Next', True, ['b']), ('c', 'c'))
check('removed focus', solve(['a','b','c'], 'gone', 'a', 'none', False, []), ('a', 'a'))
check('next', solve(['a','b','c'], 'a', 'a', 'Next', True, []), ('b', 'b'))
check('manual', solve(['a','b','c'], 'a', 'a', 'Next', False, []), ('b', 'a'))
check('space', solve(['a','b'], 'b', 'a', 'Space', False, []), ('b', 'b'))
check('removed selection', solve(['a','b'], 'b', 'gone', 'none', False, []), ('b', 'a'))
check('empty', solve([], None, None, 'Next', True, []), (None, None))
check('parameterized tab identities', solve(list(range(N+2)), N, N, 'Next', True, []), (N+1,N+1))
for repetition in range(N):
    check('repeat empty', solve([], None, None, 'Next', True, []), (None, 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 fixtureActualExpectedOutcome
disabled['a', 'a']['c', 'c']Failed
removed focus['a', 'a']['a', 'a']Passed
next['a', 'a']['b', 'b']Failed
manual['a', 'a']['b', 'a']Failed
space['b', 'b']['b', 'b']Passed
removed selection['b', 'a']['b', 'a']Passed
empty[None, None][None, None]Passed
parameterized tab identities[1, 1][2, 2]Failed
repeat empty[None, None][None, None]Passed

SHA-256 / 32aa4c73d1abc5a7045adc315dcec5e4730abf579db83117e81ed30cb32dfda4

3 / The verified repair

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

N = 1
observations = []
def solve(tabs, focused, selected, key, automatic, disabled):
    available = [t for t in tabs if t not in disabled]
    if not available: return (None, None)
    if focused not in available: focused = available[0]
    if key == 'Next': focused = available[(available.index(focused)+1) % len(available)]
    if key == 'Previous': focused = available[(available.index(focused)-1) % len(available)]
    if automatic or key in ('Enter','Space'): selected = focused
    if selected not in available: selected = available[0]
    return (focused, selected)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve(['a','b','c'], 'a', 'a', 'Next', True, ['b']), ('c', 'c'))
check('removed focus', solve(['a','b','c'], 'gone', 'a', 'none', False, []), ('a', 'a'))
check('next', solve(['a','b','c'], 'a', 'a', 'Next', True, []), ('b', 'b'))
check('manual', solve(['a','b','c'], 'a', 'a', 'Next', False, []), ('b', 'a'))
check('space', solve(['a','b'], 'b', 'a', 'Space', False, []), ('b', 'b'))
check('removed selection', solve(['a','b'], 'b', 'gone', 'none', False, []), ('b', 'a'))
check('empty', solve([], None, None, 'Next', True, []), (None, None))
check('parameterized tab identities', solve(list(range(N+2)), N, N, 'Next', True, []), (N+1,N+1))
for repetition in range(N):
    check('repeat empty', solve([], None, None, 'Next', True, []), (None, 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 fixtureActualExpectedOutcome
disabled['c', 'c']['c', 'c']Passed
removed focus['a', 'a']['a', 'a']Passed
next['b', 'b']['b', 'b']Passed
manual['b', 'a']['b', 'a']Passed
space['b', 'b']['b', 'b']Passed
removed selection['b', 'a']['b', 'a']Passed
empty[None, None][None, None]Passed
parameterized tab identities[2, 2][2, 2]Passed
repeat empty[None, None][None, None]Passed

SHA-256 / 24b067ee7c267640bce77689f59f81c95f3b775417fb66162bf9320502e4db9d

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

Case digest / cc09a16827ed1cad5b3829d51262ddd4b4ded18b480574a1952682978cc232fc