FA-53386 / Accessibility interaction semantics / Open access
Role fallback retains the explicit-source marker · case 01
Role fallback retains the explicit-source marker.
ROOT CAUSE
The fallback provenance decision in the role negotiation adapter violates its declared contract.
THE FAILURE
The fallback provenance decision in the role negotiation adapter violates its declared contract.
Unsuccessful approach: The local repair substitutes source = 'fallback' if not supported else 'native' but still mishandles the regression fixtures.
Case contract
Resolve an adapter role from ordered author tokens, native role, interactivity, required-role constraint and platform support. Supported abstract roles are group, link, image, button, article, generic and presentation. Skip unknown and abstract tokens (command, structure). Only first usable explicit token wins. Presentation is ignored on interactive objects; required native role (when required true) rejects incompatible overrides except native itself. Unsupported platform roles fall back to native if supported, otherwise generic. Generic yields no interface; link and button yield action, image yields image, article/group yield container. Return [role,interface,source] where source is explicit, native, or fallback.
Why this case matters
Offline accessibility bridge model with explicit policy; useful for testing semantic API adapters independently of browser implementations.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(data):
tokens,native,interactive,required,supported = data
known = {'group','link','image','button','article','generic','presentation'}
chosen = None
source = 'native'
for token in tokens.split():
if token not in known: continue
if token == 'presentation' and interactive: continue
if required and token != native: continue
chosen = token
source = 'explicit'
break
if chosen is None: chosen = native
if chosen not in supported:
chosen = native if native in supported else 'generic'
source = 'explicit'
interface = {'link':'action','button':'action','image':'image','article':'container','group':'container'}.get(chosen)
return [chosen,interface,source]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('ordered fallback', solve(['unknown command group link','image',False,False,['group','link','image']],), ['group','container','explicit'])
check('interactive presentation', solve(['presentation link','button',True,False,['presentation','link','button']],), ['link','action','explicit'])
check('required role', solve(['link image','image',False,True,['image','link']],), ['image','image','explicit'])
check('native fallback', solve(['article','image',False,False,['image']],), ['image','image','fallback'])
check('no supported native', solve(['group','image',False,False,[]],), ['generic',None,'fallback'])
check('empty uses native', solve([' '*N,'button',True,False,['button']],), ['button','action','native'])
check('unknown only', solve(['unknown'+str(N),['article','image','button','group','link'][N-1],False,False,['article','image','button','group','link']],), [['article','image','button','group','link'][N-1],['container','image','action','container','action'][N-1],'native'])
check('presentation retained', solve(['presentation','image',False,False,['presentation']],), ['presentation',None,'explicit'])
check('tab separated', solve(['unknown\timage','group',False,False,['image','group']],), ['image','image','explicit'])
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 |
|---|---|---|---|
| ordered fallback | ['group', 'container', 'explicit'] | ['group', 'container', 'explicit'] | Passed |
| interactive presentation | ['link', 'action', 'explicit'] | ['link', 'action', 'explicit'] | Passed |
| required role | ['image', 'image', 'explicit'] | ['image', 'image', 'explicit'] | Passed |
| native fallback | ['image', 'image', 'explicit'] | ['image', 'image', 'fallback'] | Failed |
| no supported native | ['generic', None, 'explicit'] | ['generic', None, 'fallback'] | Failed |
| empty uses native | ['button', 'action', 'native'] | ['button', 'action', 'native'] | Passed |
| unknown only | ['article', 'container', 'native'] | ['article', 'container', 'native'] | Passed |
| presentation retained | ['presentation', None, 'explicit'] | ['presentation', None, 'explicit'] | Passed |
| tab separated | ['image', 'image', 'explicit'] | ['image', 'image', 'explicit'] | Passed |
SHA-256 / bac8e8135f6cbee981762d8bb5320309307a3dd66d6c452e367428a248e62414
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(data):
tokens,native,interactive,required,supported = data
known = {'group','link','image','button','article','generic','presentation'}
chosen = None
source = 'native'
for token in tokens.split():
if token not in known: continue
if token == 'presentation' and interactive: continue
if required and token != native: continue
chosen = token
source = 'explicit'
break
if chosen is None: chosen = native
if chosen not in supported:
chosen = native if native in supported else 'generic'
source = 'fallback' if not supported else 'native'
interface = {'link':'action','button':'action','image':'image','article':'container','group':'container'}.get(chosen)
return [chosen,interface,source]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('ordered fallback', solve(['unknown command group link','image',False,False,['group','link','image']],), ['group','container','explicit'])
check('interactive presentation', solve(['presentation link','button',True,False,['presentation','link','button']],), ['link','action','explicit'])
check('required role', solve(['link image','image',False,True,['image','link']],), ['image','image','explicit'])
check('native fallback', solve(['article','image',False,False,['image']],), ['image','image','fallback'])
check('no supported native', solve(['group','image',False,False,[]],), ['generic',None,'fallback'])
check('empty uses native', solve([' '*N,'button',True,False,['button']],), ['button','action','native'])
check('unknown only', solve(['unknown'+str(N),['article','image','button','group','link'][N-1],False,False,['article','image','button','group','link']],), [['article','image','button','group','link'][N-1],['container','image','action','container','action'][N-1],'native'])
check('presentation retained', solve(['presentation','image',False,False,['presentation']],), ['presentation',None,'explicit'])
check('tab separated', solve(['unknown\timage','group',False,False,['image','group']],), ['image','image','explicit'])
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 |
|---|---|---|---|
| ordered fallback | ['group', 'container', 'explicit'] | ['group', 'container', 'explicit'] | Passed |
| interactive presentation | ['link', 'action', 'explicit'] | ['link', 'action', 'explicit'] | Passed |
| required role | ['image', 'image', 'explicit'] | ['image', 'image', 'explicit'] | Passed |
| native fallback | ['image', 'image', 'native'] | ['image', 'image', 'fallback'] | Failed |
| no supported native | ['generic', None, 'fallback'] | ['generic', None, 'fallback'] | Passed |
| empty uses native | ['button', 'action', 'native'] | ['button', 'action', 'native'] | Passed |
| unknown only | ['article', 'container', 'native'] | ['article', 'container', 'native'] | Passed |
| presentation retained | ['presentation', None, 'explicit'] | ['presentation', None, 'explicit'] | Passed |
| tab separated | ['image', 'image', 'explicit'] | ['image', 'image', 'explicit'] | Passed |
SHA-256 / 2d6ed39890db4946175b990134062f1cd3511096dba92d65782dfe7e9397d829
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 9 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗Verification & scope
Stipulated finite adapter contract, not a claim of platform accessibility or ARIA conformance. 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:45:38.550863+00:00.
Case digest / 78915859ad4095187bfc6cf76643deb95598b3f877e4c351bbe0c02d02947394