| name | a11y-hardening |
| description | Audit or remediate web accessibility barriers, with WCAG 2.2 Level AA as the minimum target. Use when asked to audit, fix, or test web accessibility, WCAG conformance, or screen-reader support in a web application. |
| license | MIT |
| metadata | {"version":"1.0.0"} |
A11y Hardening
Purpose: make web content accessible. Minimum target: WCAG 2.2 Level AA.
Definitions
- Scope: the exact pages, journeys, and states you will test.
- Matrix row: one combination of route, state, viewport, and input mode.
- Evidence: a recorded result that another person can reproduce.
Workflow checklist
Copy this checklist and track your progress:
Audit Progress:
- [ ] 1. Choose the mode
- [ ] 2. Establish the boundary
- [ ] 3. Build the matrix
- [ ] 4. Capture the baseline
- [ ] 5. Triage findings
- [ ] 6. Remediate (remediate mode only)
- [ ] 7. Verify (remediate mode only)
- [ ] 8. Report
1. Choose the mode
Two modes exist. Choose one before any other step.
- Audit mode: inspect and report only. Do not change product source code.
- Remediate mode: inspect, fix, add regression coverage, and re-verify.
Audit mode executes steps 1, 2, 3, 4, 5, and 8.
Remediate mode executes steps 1 through 8.
2. Establish the boundary
Record, in writing, all of the following:
- Mode: audit or remediate.
- Target surfaces: changed feature, selected routes, or representative sample.
- User tasks: the essential actions users must complete.
- Support baseline: browsers, assistive technology, and versions.
- Data constraints: authentication, test accounts, and fixtures.
- Evidence location: where results will be stored.
If the scope is ambiguous, choose a narrower scope.
A narrow scope produces a true claim.
A broad scope produces a false claim.
Done when: mode, scope, support baseline, constraints, and evidence location
are all explicit.
3. Build the matrix
Create one row for each combination of:
- Route or journey.
- UI state: empty, loading, populated, error, authenticated, dialog, menu,
toast, drag.
- Viewport: mobile, desktop, and intermediate widths.
- Input mode: keyboard, pointer, touch, screen reader.
Give every row a stable identifier, for example checkout-empty-mobile-kb.
Done when: every selected row has an identifier.
4. Capture the baseline
4.1 Automated checks
-
Detect the project's package manager, test runner, and browser test setup.
-
Use axe-core. WCAG 2.2 rules are disabled by default in axe-core.
Enable them before the run. See references/axe-setup.md for working
configuration in common test stacks.
-
Select the full WCAG 2.2 A/AA tag set. Each axe rule carries exactly one
WCAG version and level tag, so select every tag up to the target:
runOnly: {
type: "tag",
values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22a", "wcag22aa"]
}
The tag wcag22a currently matches no rules. Include it anyway. The set
stays valid and future-proof.
-
Run automated checks against every rendered state. Axe does not test hidden
content: inactive menus, closed dialogs, and unrendered regions are
skipped. Activate each state, then re-run.
-
Save the raw output per row: violations, incomplete results, tool version,
browser, viewport, and state.
-
Run the manual matrix in references/manual-audit.md for every applicable
category.
Tool order, from best to last resort:
- Existing browser tests with an axe integration.
- Existing browser automation that can expose dynamic states.
- Project-local axe CLI or axe-core in the test stack.
- Lighthouse, for discovery only.
- Static source inspection, only when the app cannot run. If you use it,
report reduced confidence.
Lighthouse scores are not evidence of conformance.
Done when: every row has automated evidence and applicable manual evidence,
or a written reason why it cannot be tested.
4.2 Manual checks
Load references/manual-audit.md. For every matrix row, mark each category
Applicable or N/A. Do not force irrelevant work. Complete every check
in each applicable category, or record why it cannot be tested. Record the
exact browser, operating system, assistive technology, and version for all
screen-reader evidence.
5. Triage findings
Prioritize in this order:
- Blocks an essential task.
- Appears on shared surfaces: layout, navigation, forms.
- Confirmed WCAG A or AA violation.
- User impact.
- Confidence.
- Fix leverage versus regression risk.
For every finding, record:
- Affected matrix rows.
- User consequence.
- Evidence.
- The WCAG criterion.
- Confidence.
- Proposed fix.
- Verification method.
Audit mode: continue to step 8. Do not fix code.
6. Remediate
- Fix root causes in small batches. Verify after each batch.
- Prefer native HTML, visible labels, and established project primitives.
- Treat every ARIA role as a contract for keyboard and focus behavior.
- Keep all rules enabled. If you disable a rule, record the reason and its
impact on the claim.
- Add regression tests in the existing test stack.
Done when: every confirmed in-scope A/AA failure and critical task barrier is
fixed, or explicitly deferred with a reason and evidence.
7. Verify
-
Re-run the identical matrix.
-
Compare before and after evidence with scripts/compare-evidence.mjs:
node scripts/compare-evidence.mjs before.json after.json
The script exits 1 if any finding was added. That is the intended behavior.
-
Inspect every new and every incomplete result.
-
Exercise essential journeys with keyboard and with each declared browser
and assistive-technology combination.
-
Record remaining limitations.
Done when: no unexplained mismatch remains, and manual checks and project
tests pass.
8. Report
Use this exact template:
# Accessibility report: <scope>
## Mode and scope
- Mode: <audit | remediate>
- Surfaces: <target surfaces>
- Matrix: <N rows, identifier range>
## Environment
- Browsers: <names and versions>
- Assistive technology: <names and versions>
- Tools: <axe-core version and other tools>
## Findings
| # | Severity | WCAG SC | Location | User impact | Evidence | Status |
|---|----------|---------|----------|-------------|----------|--------|
| 1 | critical | 2.5.8 | `path:line` | <consequence> | <evidence> | fixed / deferred |
## Evidence
- <per-row before/after summary>
- Raw output:
Rules for claims:
- "Axe zero" is an instrument reading, not conformance.
- "Lighthouse 100" is an instrument reading, not conformance.
- Claim only what you tested: surfaces, states, environments, and methods.