An AI review control is not usable merely because it is visible. Before releasing an advisory workflow, demonstrate that an operator can reach both approval and rejection by keyboard, retain orientation during asynchronous updates and discover the result without chasing a disappearing notification. Test the browser semantics separately from what a named screen reader actually announces. An accessibility-tree entry is evidence of exposure, not proof that somebody heard the message.
This article reports a synthetic browser fixture, not customer deployment results or a full accessibility audit. Its decision is narrow: whether a review interaction preserves a usable keyboard path and meaningful status semantics while the application is otherwise healthy. It does not establish correct human judgment, backend authorisation or machine safety.
Separate three kinds of oversight evidence
The supplier-instruction acceptance test establishes whether operators can execute the documented procedure. The automation-bias evaluation asks whether presentation helps reviewers recognise incorrect advice. The independent intervention-channel test addresses a failed main interface. Here the interface responds normally, yet its interaction may exclude an operator. These failures need different tests and owners.
Use WCAG 2.2 as a technical reference for keyboard operation, focus visibility, use of colour, names and roles, and status messages. Relevant criteria include 2.1.1, 2.4.7, 1.4.1, 4.1.2 and 4.1.3. This selection is not the complete standard. A successful automated scan against selected rules is not a WCAG conformance determination.
The EU AI Act original Official Journal text provides regulatory context, not a prescription for this browser suite. Do not equate WCAG checks with AI Act conformity or assume Article 16(l) universally mandates these exact tests. Counsel must review the current consolidated law and authentic amendments, system classification, provider/deployer roles, applicable accessibility rules and application dates. This is engineering guidance, not legal advice.
Build an advisory fixture before touching operational controls
The executed fixture presents a persistent recommendation: inspect a pump bearing, advisory only, with no machine action. Two native buttons are named “Approve inspection” and “Reject recommendation”. A text warning states that sensor evidence is incomplete; it does not rely on red colouring. A separate persistent history paragraph records the decision. Neither button is an emergency stop, and the cover's physical console is an illustration rather than a safety-system design.
The status region exists before updates: <p id="status" role="status" aria-atomic="true"></p>. Native buttons provide keyboard activation without custom key handlers. A visible focus outline uses a three-pixel blue border treatment with offset. The asynchronous simulation changes only status and history text, not the focused button's DOM identity.
While saving, the activated button receives aria-disabled="true" and a shared busy guard ignores further activations. Unlike the native disabled attribute, aria-disabled does not itself prevent activation: the handler must enforce the guard. That trade-off preserves focus in this fixture but adds implementation responsibility. A production request still needs server-side authorisation, idempotency and an explicit failure/retry state. The fixture has no server and cannot prove any of them.
The proposed interaction sequence is review evidence, choose an action, expose saving status, persist a result, then expose completion without moving focus. Do not automatically advance to the next recommendation: that changes context and deserves a separate focus policy. A user must still be able to inspect the decision just made.
Decide which changes deserve an announcement
The W3C explanation of status messages distinguishes brief information about an action's result or progress from arbitrary new content. A new evidence panel is not automatically a status message. Give the concise result appropriate semantics; do not place the entire streaming model response in an assertive live region.
| Change | Interaction decision | Required check |
|---|---|---|
| Saving or completion | Polite status; retain focus | Expose full result, not a bare number |
| Important nonmodal warning | Consider alert; retain warning text | No stolen focus or premature removal |
| Decision requires interruption | Explicit dialog and focus policy | Entry, exit and return focus tested |
| New model evidence | Keep inspectable content separate | Do not announce every streamed token |
| Same event repeated | One notification owner | Verify actual speech with named AT |
The ARIA alert pattern warns against moving focus for an alert, automatically disappearing alerts and excessive interruption. Ordinary completion should not be promoted to an urgent alert just to make it louder. If the workflow genuinely requires an interrupting decision, design and test a dialog with its own focus handling rather than disguising it as a status toast.
Use one owner for the live-region update. A component announcing locally while a global notification service repeats the same message can create duplicate output. Deduplicate by event identity in a real application, not solely by the message string: two distinct decisions may have identical wording. The fixture's string guard is deliberately local and is not a production event protocol.
What the browser experiment observed
The run used Playwright 1.64.1, Chromium 156.0.8078.4 and axe-core 4.10.3. It loaded a local HTML fixture and issued keyboard commands. A configured 100 ms timer simulated saving; this is not a measured service latency or a recommended performance target. No network request, real operator or screen reader participated.
The recorded focus trace was Tab → approve, Tab → reject, Shift+Tab → approve, Enter → approve. After the simulated completion, focus still identified the approve button. A subsequent Tab and Space activated rejection and changed the persistent history to “Recommendation rejected. No machine action.” The status mutation log contained “Saving review decision.” followed by “Review decision saved.” These are DOM changes, not recorded speech.
| Executed probe | Observation | Boundary |
|---|---|---|
| Tab; Tab; Shift+Tab; Enter | approve; reject; approve; approve | Local fixture only |
| Space on rejection | Persistent rejected result | No backend action |
| Selected axe rules | No violations reported | Not a complete audit |
| Chromium accessibility tree | Two buttons and one status role | Not recorded speech |
| Four injected defects | All detected by bespoke assertions | Risk checks, not AT compatibility |
The selected axe rule tags were wcag2a, wcag2aa, wcag21aa and wcag22aa. The scan returned no violations for that fixture. Chromium's accessibility tree exposed two button roles and a status role. These findings support the tested DOM contract only. They do not establish that all applicable criteria passed, that the status was announced once, or that NVDA, JAWS or VoiceOver behaves identically.
Four deliberately broken variants tested the bespoke assertions. Replacing the focused button lost its focus identity. Removing the warning text left a colour-only signal. Clearing the status after a configured 10 ms removed the persistent result. Adding another status region violated the fixture's single-owner policy. Each negative control was detected. The duplicate-region check flags a risk; without listening through assistive technology it cannot prove duplicate speech. Multiple live regions are not universally invalid.
Acceptance checklist for the real interface
Check 1 — Freeze the interface build, browser, operating system, display language, operator role and assistive-technology versions. Include the actual evidence view, not just the two action buttons. Record which combinations remain untested.
Check 2 — Navigate forward and backward without a mouse. Activate both decisions, open evidence and return, retry a failure and escape any modal. Inspect visible focus, logical order and unobscured controls. Retain a focus trace through rerenders; stable framework keys and native elements reduce avoidable regressions.
Check 3 — Test saving, completion, rejection, server error, expired permission and uncertain outcome separately. Preserve meaningful result text. Never announce “saved” because a request was sent. Check the authoritative response and reconcile an ambiguous timeout before offering a retry that might repeat a business action.
Check 4 — Run automated checks and inspect the accessibility tree. Then test announcements with a named screen reader/browser combination and representative users where appropriate. Record actual wording, order, interruption and repetition. A screenshot cannot establish these observations.
Check 5 — Inject focus loss, colour-only warnings, premature disappearance and duplicate notification ownership. A suite that passes only the correct implementation is weaker than one that demonstrably rejects the intended defects. Keep the failure fixtures alongside the positive case.
Check 6 — Assign owners for component semantics, notification delivery, backend decision truth and accessibility testing. Reopen affected evidence after component-library upgrades, routing changes, translation changes or new streaming behaviour. Restrict any participant recordings and obtain the required organisational permissions.
Cost, limits and the release decision
Persistent status and history consume space, especially on mobile. Aggressive announcements consume attention. Preserving focus can retain a control that is temporarily unavailable, requiring clear state and guarded activation. Automatically moving focus can instead disrupt reading. There is no universal notification policy that avoids these trade-offs; define it against the task and test the supported user configurations.
Automated checks are fast and repeatable but cannot establish usable spoken interaction or comprehension. Manual assistive-technology testing costs time and must be maintained as browsers and components change. Start with the consequential path and expand coverage explicitly rather than calling an untested matrix supported.
For an implementation review, bring one approval screen, its asynchronous state transitions and the supported browser/assistive-technology combinations. I help platform teams turn those into reproducible interaction tests, an evidence pack and bounded release criteria. Keep unresolved screen-reader behaviour visible in the release decision instead of converting a clean automated scan into an accessibility guarantee.


