This plan prioritizes evidence we can validate. A working API spike is a starting point; it does not establish complete audit coverage.
The external-app validation record tracks pinned Wikipedia builds, capture results, toolchain constraints, and remaining coverage. It distinguishes successful evidence collection from app accessibility findings.
Tracking: #21.
The first implementation is aloud ios --apple-audit:
- Capture native findings on every navigated screen alongside tree checks.
- Keep target identity and capture-completion checks mandatory.
- Include raw JSON and XCTest artifacts in the evidence report.
- Leave findings report-only until severity and coverage are calibrated.
Release criteria: the simulator smoke workflow passes, then at least one external app is exercised in current-screen, deep-link, and bridge modes. Verify that background/foreground transitions do not change the requested screen. Only introduce gating or WCAG mappings with corresponding fixtures and explicit per-screen native-check coverage.
Tracking: #23.
The Xcode 27 harness is integrated as opt-in partial capture through
--voiceover real --no-gate. It preserves raw speech and identities,
retains limits/timeouts explicitly, and rejects unavailable targets and
system dialogs. Complete traversal is still unproven: Apple's Output
contains no documented focus identity or end flag.
Implemented: strict capture identities, no fallback or target relaunch,
raw source: "voiceover" evidence, toolchain versions, service-state
restoration, explicit stopping reasons, report/OpenACR provenance, and
conservative comparison policies. Tree-count baselines need no transcript
migration because they contain no transcript text. The simulator workflow
exercises repeated labels, dynamic content, scrolling, and modals.
The walker records every requested real-speech screen before navigation.
Report regeneration rejects missing screens, lost tree or transcript files,
computed replacements, and missing or mismatched raw VoiceOver records.
Still required before promotion to the default:
- Verify complete utterance text on supported runtimes; the external-app run observed long API strings ending at 64 characters, which Aloud preserves exactly. See the validation record.
- Establish a verified traversal-completion signal. Neither repeated
speech nor
noSpeechestablishes the end of a screen. - Pair moving or changing content with coherent tree/screenshot evidence; the current walker rejects changed screens and retains raw diagnostics.
- Expand repeatable validation to released OS runtimes and more external apps.
The first external captures use released Xcode 27 with simulator
24A434; the toolchain and OS runtime have separate build identities.
Tracking: #24.
The opt-in --talkback focus implementation uses a shell-restricted companion
inside the pinned source build. It invokes TalkBack's gesture controller,
records actual focus and speech requests, and requires backward and forward
native boundaries. Incomplete traversal fails with raw diagnostics retained.
See the protocol and limitations.
The native fixture covers nested containers, scrolling, duplicate labels, disabled controls, dialogs, target changes, permission denial, and restoration. Broader app and WebView compatibility remains an adoption-validation task; traversal evidence alone does not establish correct focus order or conformance.
Tracking: #25.
The opt-in --talkback focus --tts logging mode pairs a durable request ledger
with independent engine receipts and Android completion/interruption callbacks.
It keeps queued-but-flushed requests explicit, preserves incomplete evidence
after process death, and restores the original engine and related settings.
See logging TTS capture.
The native suite checks repeated IDs, 400 rapid requests with logcat overflow, queue replacement and stop, and engine/client restart recovery. The recording engine generates synthetic silence, not spoken words. Verified request accounting does not prove audible delivery or correct focus order.
Tracking: #26.
The opt-in --atf implementation captures native hints, stateDescription,
paneTitle, and the AndroidX role-description extra. Six pinned ATF 4.1.1
checks run against the same snapshot used by the existing tree rules.
Reports preserve check execution, NOT_RUN applicability results, stable
rule IDs, exact element identity, and potential overlap with tree findings.
Raw snapshots and hashed receipts are retained and revalidated on aggregation.
See setup and scope.
The controlled fixture demonstrates each selected check failing and then clearing after correction, plus read-only content, changing screens, process loss, permission denial, and cleanup. These checks remain report-only and add no OpenACR conformance claims. Broader app/framework validation and additional checks require their own fixtures before expanding the supported suite.
The experimental aloud web leg captures named Chromium page states with
axe-core findings, structural ARIA snapshots, screenshots, and scripted
keyboard/focus assertions. Browser packages are optional peers. Run identities,
expected states, artifact receipts, explicit speech sources, and cleanup
status survive re-aggregation. Web results are report-only, and web OpenACR
components remain not-evaluated.
The NVDA adapter captures Guidepup's formatted command output on a dedicated Windows desktop. It never substitutes structural text for speech and never claims full traversal. Its opt-in native acceptance workflow passed repeated Windows fixtures on 2026-09-20, including form errors, modal focus return, live regions, duplicate labels, and long output. External TodoMVC scenarios exercise creation, completion, and filtering with retained evidence. The Safari + VoiceOver adapter runs only on a disposable GitHub-hosted macOS runner. Hosted runs of its fixtures passed for the driver refinements and the late-speech wait; the reviewed environment and command logs are recorded in web validation. The USWDS accessibility harness drives its NVDA and VoiceOver suites through both drivers. See web setup and limits.
Next acceptance steps:
- Repeat Windows acceptance when browser, NVDA, or Guidepup versions change, and macOS acceptance when Safari, macOS, or Guidepup versions change; retain the exact environment identities and raw command output.
- Validate authenticated and changing page states on an external web app, including frames and shadow content, and record unsupported cases without loosening checks.
- Define separate scan, assertion, and capture-completeness policies before browser gating. Baselines must identify the browser/reader/OS/locale/viewport and rule suite.
- Validate additional browser and screen-reader combinations independently. A Playwright WebKit run must not be labeled as Safari coverage.
- Run the external TodoMVC scenarios with Safari + VoiceOver; today only the fixtures have run with that adapter.
One builder turns a findings document from any source into a draft
OpenACR: aloud acr, the @irs-public/aloud/acr library, and the
"aloud acr" GitHub Action. aloud openacr uses it for aloud's own audits.
The findings contract (src/acr/findings.schema.json) is versioned,
closed, and validated before anything is written; a conservative default
policy keeps unproven rows at not-evaluated, and overrides are limited by
status kind so nothing can turn a failure or a gap into supports. See
OpenACR drafts.
The harness integration guide documents an adapter from the USWDS accessibility harness's requirements report, tested against a fixture and a real report. The harness keeps its own copy and drafts one ACR per component in its workflow, with aloud pinned by commit.
Next steps:
- Keep the example adapter's status mapping in step with the harness's report and its own copy.
- Add web findings from
aloud webonce web evidence is validated and has a gating policy; until then web components staynot-evaluated. - Support more OpenACR catalogs (for example, the EN 301 549 editions) when a consumer needs them, each with its own fixture.