FA-11421 / Accessibility interaction semantics / Open access
Error text replaces persistent instructions in the description channel · case 01
Invalid controls lose their usage hint, or error text remains announced after validation succeeds.
ROOT CAUSE
The description is treated as a single interchangeable hint-or-error slot.
VERIFIED REPAIR
Keep instructions and add error text only while invalid; never modify the control name.
Unsuccessful approach: Always appending error text keeps stale errors after invalid state clears.
Case contract
Given a name, hint, error text and invalid boolean, return [name,description]. Description joins nonempty hint and (only when invalid) error with one space. Name is preserved verbatim. This models channel assembly, not reference resolution or validation timing.
Why this case matters
A controlled offline accessibility-data model. It isolates the stated contract; it does not simulate browser accessibility APIs or claim full ARIA conformance.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(name, hint, error, invalid):
return [name, error if invalid else hint]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hint remains with error', solve('Field '+str(N), 'Use digits', 'Required', True), ['Field '+str(N),'Use digits Required'])
check('valid suppresses stale error', solve(str(N), 'Use digits', 'Required', False), [str(N),'Use digits'])
check('no hint', solve(str(N), '', 'Required', True), [str(N),'Required'])
check('empty error retains hint', solve(str(N), 'Use digits', '', True), [str(N),'Use digits'])
check('empty channels', solve(str(N), '', '', False), [str(N),''])
check('name never replaced', solve('Name '+str(N), '', 'Error', False), ['Name '+str(N),''])
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 |
|---|---|---|---|
| hint remains with error | ['Field 1', 'Required'] | ['Field 1', 'Use digits Required'] | Failed |
| valid suppresses stale error | ['1', 'Use digits'] | ['1', 'Use digits'] | Passed |
| no hint | ['1', 'Required'] | ['1', 'Required'] | Passed |
| empty error retains hint | ['1', ''] | ['1', 'Use digits'] | Failed |
| empty channels | ['1', ''] | ['1', ''] | Passed |
| name never replaced | ['Name 1', ''] | ['Name 1', ''] | Passed |
SHA-256 / dcd00ea3251c93eb138667014bc4089443f8e087219c17529d5f24f65ed8dabc
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(name, hint, error, invalid):
return [name, ' '.join(part for part in [hint,error] if part)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hint remains with error', solve('Field '+str(N), 'Use digits', 'Required', True), ['Field '+str(N),'Use digits Required'])
check('valid suppresses stale error', solve(str(N), 'Use digits', 'Required', False), [str(N),'Use digits'])
check('no hint', solve(str(N), '', 'Required', True), [str(N),'Required'])
check('empty error retains hint', solve(str(N), 'Use digits', '', True), [str(N),'Use digits'])
check('empty channels', solve(str(N), '', '', False), [str(N),''])
check('name never replaced', solve('Name '+str(N), '', 'Error', False), ['Name '+str(N),''])
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 |
|---|---|---|---|
| hint remains with error | ['Field 1', 'Use digits Required'] | ['Field 1', 'Use digits Required'] | Passed |
| valid suppresses stale error | ['1', 'Use digits Required'] | ['1', 'Use digits'] | Failed |
| no hint | ['1', 'Required'] | ['1', 'Required'] | Passed |
| empty error retains hint | ['1', 'Use digits'] | ['1', 'Use digits'] | Passed |
| empty channels | ['1', ''] | ['1', ''] | Passed |
| name never replaced | ['Name 1', 'Error'] | ['Name 1', ''] | Failed |
SHA-256 / 12a374fff565c192790e2bd1c3fd5689b7d2d40585ee0ab1d46806930d82a31b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(name, hint, error, invalid):
return [name, ' '.join(part for part in [hint, error if invalid else ''] if part)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hint remains with error', solve('Field '+str(N), 'Use digits', 'Required', True), ['Field '+str(N),'Use digits Required'])
check('valid suppresses stale error', solve(str(N), 'Use digits', 'Required', False), [str(N),'Use digits'])
check('no hint', solve(str(N), '', 'Required', True), [str(N),'Required'])
check('empty error retains hint', solve(str(N), 'Use digits', '', True), [str(N),'Use digits'])
check('empty channels', solve(str(N), '', '', False), [str(N),''])
check('name never replaced', solve('Name '+str(N), '', 'Error', False), ['Name '+str(N),''])
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 |
|---|---|---|---|
| hint remains with error | ['Field 1', 'Use digits Required'] | ['Field 1', 'Use digits Required'] | Passed |
| valid suppresses stale error | ['1', 'Use digits'] | ['1', 'Use digits'] | Passed |
| no hint | ['1', 'Required'] | ['1', 'Required'] | Passed |
| empty error retains hint | ['1', 'Use digits'] | ['1', 'Use digits'] | Passed |
| empty channels | ['1', ''] | ['1', ''] | Passed |
| name never replaced | ['Name 1', ''] | ['Name 1', ''] | Passed |
SHA-256 / df3aca93a87b0751c12dd65b5a96e56153367aae2428ef6b86f34a5879070d47
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:47.818929+00:00.
Case digest / 471c3dc343b650dbae1408b9cbbde35b28116aba5ab4e9bcc7d7c879e8380a01