FA-11406 / Accessibility interaction semantics / Open access
Name flattening leaves line breaks as spoken separators · case 01
Text fragments produce excess spaces or lose intentional nonbreaking characters.
ROOT CAUSE
Text is joined without applying the model’s ASCII whitespace normalization.
VERIFIED REPAIR
Collapse only ASCII whitespace runs after joining fragments, preserving all other characters.
Unsuccessful approach: Using split() collapses Unicode nonbreaking spaces that this contract preserves.
Case contract
Join text fragments with one ASCII space, collapse runs of ASCII space, tab, CR, LF, form feed and vertical tab to one space, and trim those ASCII characters at either end. Preserve nonbreaking spaces and other Unicode characters exactly.
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(parts):
return ' '.join(parts)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('ASCII line boundaries', solve([' Item\n',str(N)+'\t name ']), 'Item '+str(N)+' name')
check('nonbreaking space preserved', solve(['A\u00a0'+str(N)]), 'A\u00a0'+str(N))
check('nonbreaking edge preserved', solve(['\u00a0'+str(N)+'\u00a0']), '\u00a0'+str(N)+'\u00a0')
check('empty fragments', solve(['',str(N),'']), str(N))
check('all whitespace', solve([' \r\n','\f\v']), '')
check('empty list', solve([]), '')
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 |
|---|---|---|---|
| ASCII line boundaries | Item
1 name | Item 1 name | Failed |
| nonbreaking space preserved | A 1 | A 1 | Passed |
| nonbreaking edge preserved | 1 | 1 | Passed |
| empty fragments | 1 | 1 | Failed |
| all whitespace |
| | Failed |
| empty list | | | Passed |
SHA-256 / acaf874ae8153a719babefaaa19837944908ca5b0c4f913e80c92fc5276d8eea
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(parts):
return ' '.join(' '.join(parts).split())
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('ASCII line boundaries', solve([' Item\n',str(N)+'\t name ']), 'Item '+str(N)+' name')
check('nonbreaking space preserved', solve(['A\u00a0'+str(N)]), 'A\u00a0'+str(N))
check('nonbreaking edge preserved', solve(['\u00a0'+str(N)+'\u00a0']), '\u00a0'+str(N)+'\u00a0')
check('empty fragments', solve(['',str(N),'']), str(N))
check('all whitespace', solve([' \r\n','\f\v']), '')
check('empty list', solve([]), '')
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 |
|---|---|---|---|
| ASCII line boundaries | Item 1 name | Item 1 name | Passed |
| nonbreaking space preserved | A 1 | A 1 | Failed |
| nonbreaking edge preserved | 1 | 1 | Failed |
| empty fragments | 1 | 1 | Passed |
| all whitespace | | | Passed |
| empty list | | | Passed |
SHA-256 / 848f992232e38345386435d616ea8909c7afd606a9cbad73f82751ef4eba31b8
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(parts):
text = ' '.join(parts)
result = []
pending = False
for char in text:
if char in ' \t\r\n\f\v':
pending = bool(result)
else:
if pending: result.append(' ')
result.append(char)
pending = False
return ''.join(result)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('ASCII line boundaries', solve([' Item\n',str(N)+'\t name ']), 'Item '+str(N)+' name')
check('nonbreaking space preserved', solve(['A\u00a0'+str(N)]), 'A\u00a0'+str(N))
check('nonbreaking edge preserved', solve(['\u00a0'+str(N)+'\u00a0']), '\u00a0'+str(N)+'\u00a0')
check('empty fragments', solve(['',str(N),'']), str(N))
check('all whitespace', solve([' \r\n','\f\v']), '')
check('empty list', solve([]), '')
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 |
|---|---|---|---|
| ASCII line boundaries | Item 1 name | Item 1 name | Passed |
| nonbreaking space preserved | A 1 | A 1 | Passed |
| nonbreaking edge preserved | 1 | 1 | Passed |
| empty fragments | 1 | 1 | Passed |
| all whitespace | | | Passed |
| empty list | | | Passed |
SHA-256 / da9540c9e8172826f9fc121e691eded5310cb181f142379de13da908b7e8af77
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.656540+00:00.
Case digest / 5875f3d5f028f28094f06bccc4d675bca572a709884783bfd05cb45dfdbf475a