FA-8176 / Disclosure widgets / Open access
Tooltip trigger and dismissal: Pointer leave hides a tooltip still needed by keyboard focus · case 01
Pointer leave hides a tooltip still needed by keyboard focus.
ROOT CAUSE
The leave operation uses `if event == 'leave': return False` where the contract requires `if event == 'leave': return bool(focused)`.
VERIFIED REPAIR
Implement the leave operation as `if event == 'leave': return bool(focused)`.
Unsuccessful approach: Always keeping it open prevents pointer-only dismissal.
Case contract
Disabled triggers hide content; Escape dismisses regardless of trigger state; focus/enter open; blur and leave preserve the other active trigger.
Why this case matters
A deterministic model of tooltip trigger and dismissal; 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(state, event, focused, hovered, disabled):
if disabled: return False
if event == 'escape': return False
if event == 'focus': return True
if event == 'enter': return True
if event == 'blur': return bool(hovered)
if event == 'leave': return False
return state
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disable', solve(True, 'none', False, False, True), False)
check('escape', solve(True, 'escape', True, True, False), False)
check('focus', solve(False, 'focus', True, False, False), True)
check('blur hovered', solve(True, 'blur', False, True, False), True)
check('blur abandoned', solve(True, 'blur', False, False, False), False)
check('leave focused', solve(True, 'leave', True, False, False), True)
check('leave abandoned', solve(True, 'leave', False, False, False), False)
check('parameterized remaining trigger', solve(True, 'blur', False, bool(N%2), False), bool(N%2))
for repetition in range(N):
check('repeat leave abandoned', solve(True, 'leave', False, False, False), False)
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 |
|---|---|---|---|
| disable | False | False | Passed |
| escape | False | False | Passed |
| focus | True | True | Passed |
| blur hovered | True | True | Passed |
| blur abandoned | False | False | Passed |
| leave focused | False | True | Failed |
| leave abandoned | False | False | Passed |
| parameterized remaining trigger | True | True | Passed |
| repeat leave abandoned | False | False | Passed |
SHA-256 / 470228ae61770464c998b2d5a1ed40e2a2559f53d13d2b45a56891ce75a6afd2
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(state, event, focused, hovered, disabled):
if disabled: return False
if event == 'escape': return False
if event == 'focus': return True
if event == 'enter': return True
if event == 'blur': return bool(hovered)
if event == 'leave': return True
return state
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disable', solve(True, 'none', False, False, True), False)
check('escape', solve(True, 'escape', True, True, False), False)
check('focus', solve(False, 'focus', True, False, False), True)
check('blur hovered', solve(True, 'blur', False, True, False), True)
check('blur abandoned', solve(True, 'blur', False, False, False), False)
check('leave focused', solve(True, 'leave', True, False, False), True)
check('leave abandoned', solve(True, 'leave', False, False, False), False)
check('parameterized remaining trigger', solve(True, 'blur', False, bool(N%2), False), bool(N%2))
for repetition in range(N):
check('repeat leave abandoned', solve(True, 'leave', False, False, False), False)
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 |
|---|---|---|---|
| disable | False | False | Passed |
| escape | False | False | Passed |
| focus | True | True | Passed |
| blur hovered | True | True | Passed |
| blur abandoned | False | False | Passed |
| leave focused | True | True | Passed |
| leave abandoned | True | False | Failed |
| parameterized remaining trigger | True | True | Passed |
| repeat leave abandoned | True | False | Failed |
SHA-256 / 85a918a0aeb61ec0f0040c61996954bd6420d0d0bff3a53a53458b54b6003450
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(state, event, focused, hovered, disabled):
if disabled: return False
if event == 'escape': return False
if event == 'focus': return True
if event == 'enter': return True
if event == 'blur': return bool(hovered)
if event == 'leave': return bool(focused)
return state
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disable', solve(True, 'none', False, False, True), False)
check('escape', solve(True, 'escape', True, True, False), False)
check('focus', solve(False, 'focus', True, False, False), True)
check('blur hovered', solve(True, 'blur', False, True, False), True)
check('blur abandoned', solve(True, 'blur', False, False, False), False)
check('leave focused', solve(True, 'leave', True, False, False), True)
check('leave abandoned', solve(True, 'leave', False, False, False), False)
check('parameterized remaining trigger', solve(True, 'blur', False, bool(N%2), False), bool(N%2))
for repetition in range(N):
check('repeat leave abandoned', solve(True, 'leave', False, False, False), False)
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 |
|---|---|---|---|
| disable | False | False | Passed |
| escape | False | False | Passed |
| focus | True | True | Passed |
| blur hovered | True | True | Passed |
| blur abandoned | False | False | Passed |
| leave focused | True | True | Passed |
| leave abandoned | False | False | Passed |
| parameterized remaining trigger | True | True | Passed |
| repeat leave abandoned | False | False | Passed |
SHA-256 / c75368672f7ce71ffb7a703eb2ba69ccbf407ff753a76cc5311461e6cb8448b7
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:19.032533+00:00.
Case digest / 690483aeca080ef5f7f107b89cc5f23fad54fc107f6bccfcff9b2defb84803b9