a11y-audit
Skill7 starsChanged 28 days agoMITView on GitHub
Dedicated WCAG 2.2 AA/AAA accessibility audit across 10 dimensions (A1-A10) covering semantic HTML, keyboard navigation, ARIA patterns, color contrast, forms, images/media, responsive/zoom, motion/animation, reading/content, and legal compliance. Goes far beyond surface-level design-review checks with deep compliance-focused analysis, WCAG criterion mapping, and legal risk assessment (ADA Title II, EAA, Section 508). Critical gates on keyboard (A2) and contrast (A4). Flags: [path] | full | --live-url <url> | --quick | --fix | --standard AA|AAA | --legal ada|eaa|508.
34 other projects use a version of this.
Adopted by
Most recently taken up by
- arcasilesgroup/ai-engineeringtheir own version, first seen Nov 8, 2026
- darkweb19/skillstheir own version, first seen Nov 8, 2026
- Aboudjem/ui-ux-suitetheir own version, first seen Nov 8, 2026
- kgelster/ecom-a11y-audittheir own version, first seen Nov 1, 2026
- jbouder/skillstheir own version, first seen Nov 1, 2026
- MKS-01/appscreenmaptheir own version, first seen Oct 17, 2026
Used with
Projects with it also use perf-audit, design-tokens and 3 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
WhatIfWeDigDeeperSkillperf-audit
Profile and optimize React application performance
Also in 4 projects that use this
ilikescienceSkilldesign-tokens
Expert in design tokens using the DTCG specification. Use this skill when users ask about design tokens, DTCG format, token validation, formatting, transformation, color spaces (sRGB, Display P3, OKLCH), references and aliasing, resolvers, theming with modifiers/contexts, multi-platform design systems, accessibility, or working with tools like jq, jsonata, and terrazzo. Helps with token file creation, resolver configuration, structure, naming conventions, and best practices.
Also in 4 projects that use this
lbednerSkilli18n
Use when a code or template change introduces a new translation message key, in either the framework CLI (aegis/i18n/locales/) or a generated project's CLI (the app/i18n/locales/ template tree). Covers adding the real English string, stubbing the same key into every other locale for parity, and the separate translation PR that later replaces placeholders with reviewed native text.
Also in 3 projects that use this
AnthropicSkilldesign-system
Audit, document, or extend your design system. Use when checking for naming inconsistencies or hardcoded values across components, writing documentation for a component's variants, states, and accessibility notes, or designing a new pattern that fits the existing system.
Also in 3 projects that use this
HashiCorpSkillchangelog
Add a `.changelog/<PR_NUMBER>.txt` entry for a GitHub Pull Request, commit, and push.
Also in 3 projects that use this
Other versions34 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 34
- gitkraken/vscode-gitlens★ 10ksame name
- plugin87/ux-ui-agent-skills★ 3.1ksame name
- SwitchbackTech/compass★ 227same name
- arcasilesgroup/ai-engineering★ 65same name
- helderberto/agent-skills★ 19same name
- Hassaan146/claude-skills★ 18same name
- renfei-design/Figma-AI-Bridge★ 16same name
- kgelster/ecom-a11y-audit★ 12same name
- Mozurok/fhorja.dev★ 10same name
- Aboudjem/ui-ux-suite★ 8same name
24 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository58 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- agent-benchmarkSkill
- api-auditSkill
- architectureSkill
- backlogSkill
- benchmarkSkill
- brainstormSkill
- buildSkill
- canarySkill
- ci-auditSkill
- code-auditSkill
- container-auditSkill
- content-auditSkill
- content-expandSkill
- content-fixSkill
- content-migrationSkill
- context-auditSkill
- db-auditSkill
- debugSkill
- dependency-auditSkill
- deploySkill
- design-reviewSkill
- designSkill
- docsSkill
- env-auditSkill
- executeSkill
- fix-testsSkill
- geo-auditSkill
- geo-fixSkill
- incidentSkill
- infra-auditSkill
- leadsSkill
- mutation-testSkill
- pentestSkill
- performance-auditSkill
- planSkill
- presentationSkill
- profile-sessionSkill
- receive-reviewSkill
- refactor-radarSkill
- refactorSkill
- release-docsSkill
- retroSkill
- reviewSkill
- security-auditSkill
- seo-auditSkill
- seo-fixSkill
- shipSkill
- skill-evalSkill
- structure-auditSkill
- test-auditSkill
- tests-performanceSkill
- ui-design-teamSkill
- using-zuvoSkill
- worktreeSkill
- write-articleSkill
- write-e2eSkill
- write-testsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
22 rules. 0 are common, 9 are distinctive, and 13 are very specific to this project.
0
Common
Most of the 27 edited versions we read keep these.
9
Distinctive
This author's own choices. Worth a look.
13
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 55
When to use: Before public launches, when targeting WCAG compliance, after ADA/EAA legal requirements surface, periodic accessibility …
- Distinctive: line 83
Read these files before any work begins.
- Very specific: line 105
Read ../../shared/includes/env-compat.md for agent dispatch patterns, path resolution, and progress tracking across all supported platforms.
- Very specific: line 128
Use the deterministic preload helper FIRST: Run ~/.zuvo/compute-preload a11y-audit "$PWD".
- Very specific: line 134
Read ../../shared/includes/codesift-setup.md for the full initialization sequence.
- Very specific: line 272
Check package.json dependencies, config files (next.config.*, astro.config.*, svelte.config.*, angular.json)
- Distinctive: line 307
Run grep/CodeSift scans across the codebase for:
- Very specific: line 330
If eslint-plugin-jsx-a11y is detected:
- Distinctive: line 336
If not available: skip, rely on manual scan.
- Very specific: line 373
If mcp-accessibility-scanner is available:
- Very specific: line 378
If chrome-devtools MCP is available but not accessibility-scanner:
- Very specific: line 380
Run evaluate_script with axe-core injection
- Very specific: line 451
If --dry-run flag is set: report all fixes without applying.
- Very specific: line 453
If --fix flag is set:
- Distinctive: line 456
Run verification: check that fixes don't break existing tests
- Distinctive: line 457
If tests fail after a fix: revert that specific fix, keep the tag for manual rollback
- Distinctive: line 602
Before printing the final output block, verify every item.
- Distinctive: line 616
After completing the audit, print:
- Very specific: line 650
If gate_status = FAIL → VERDICT = INCOMPLETE.
- Very specific: line 659
Follow the retrospective protocol from retrospective.md.
- Distinctive: line 661
If gate check skips: print "RETRO: skipped (trivial session)" and proceed.
- Very specific: line 663
After printing this block, append the Run: line value (without the Run: prefix) to the log file path resolved per run-logger.md.
“Common” is measured: kept by at least 6 in 10 of the 27 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
zuvo:a11y-audit — WCAG 2.2 Accessibility Audit
Deep, compliance-focused accessibility audit across 10 weighted dimensions with WCAG 2.2 criterion mapping, legal risk assessment, and actionable fix generation. Every finding maps to a specific WCAG success criterion and severity level.
When to use: Before public launches, when targeting WCAG compliance, after ADA/EAA legal requirements surface, periodic accessibility health checks, when onboarding a codebase that must meet compliance standards, after adding interactive components or forms.
Out of scope: Surface-level design consistency (zuvo:design-review), visual design quality (zuvo:ui-design-team), code quality (zuvo:code-audit), penetration testing (zuvo:pentest).
Argument Parsing
Parse $ARGUMENTS for these flags:
| Argument | Effect |
[path] | Audit a specific directory or component |
full | Audit the entire project |
--live-url <url> | Enable browser-based testing (axe-core via MCP) |
--quick | Critical gates only (A2 Keyboard, A4 Contrast) |
--fix | Generate fix code for all findings |
--standard AA|AAA | Compliance level (default: AA) |
--legal ada|eaa|508 | Focus on a specific legal standard |
--max-files [N] | Cap audit to N files (default: 40) |
--persist-backlog | Record CRITICAL/HIGH findings via backlog-add (also done whenever a CRITICAL finding exists) |
| Mode | Scope | Phases | Browser |
[path] | Directory/component | 0-5 | No |
full | Entire project | 0-5 | No |
--live-url | Project + URL | 0-5 incl. Phase 2 browser | Yes |
--quick | Project | 0, 1 (A2+A4 only), 5 | No |
Mandatory File Loading
Read these files before any work begins. Print the checklist with status.
Stage 1 -- Before Phase 0 (STOP if any missing):
CORE FILES LOADED:
1. ../../shared/includes/codesift-setup.md -- [READ | MISSING -> STOP]
2. ../../shared/includes/env-compat.md -- [READ | MISSING -> STOP]Stage 2 -- Before Phase 5 (report writing):
3. ../../shared/includes/run-logger.md -- [READ | MISSING -> STOP]
4. ../../shared/includes/retrospective.md -- [READ | MISSING -> STOP]
5. ../../shared/includes/backlog-protocol.md -- [READ | MISSING -> degraded]Stage 2 deferred to save upfront context.
Environment Compatibility
Read ../../shared/includes/env-compat.md for agent dispatch patterns, path resolution, and progress tracking across all supported platforms.
MANDATORY TOOL CALLS — A11y Audit Validity Gate
INVALID if any tool below is skipped. "DEFERRED", "N/A" NOT valid reasons.
| Tool | Trigger | Skip allowed? |
get_file_tree | Always | NO |
search_text | Always | NO — aria-*, role=, alt=, tabindex, lang attrs |
search_symbols | Always | NO — interactive component discovery |
search_patterns | Always | NO — WCAG anti-patterns (missing alt, nested interactive) |
audit_scan | Always | NO — compound check |
| React tools (analyze_hooks, trace_component_tree) | React detected | NO when React |
Forbidden: same as above (skipped/N/A/codesift unavailable when deferred — REJECTED).
POSTAMBLE: report on disk → retro appended → ~/.zuvo/append-runlog exit 0. Every A-dim finding needs path/to/file.ext:LINE (verify-audit gate).
Mandatory-tools-acknowledgment: I will run get_file_tree + search_text + search_symbols + search_patterns + audit_scan + React tools (when React) for this a11y audit. Every A-dim finding will cite a `path/to/file.ext:LINE` resolving in the current tree.Use the deterministic preload helper FIRST. Run ~/.zuvo/compute-preload a11y-audit "$PWD". Math gate enforced.
CodeSift Integration
Read ../../shared/includes/codesift-setup.md for the full initialization sequence.
a11y-audit CodeSift usage:
search_text(repo, "aria-|role=", regex=true, file_pattern="*.tsx")-- ARIA attribute scansearch_text(repo, "<h[1-6]", regex=true, file_pattern="*.tsx")-- heading inventorysearch_text(repo, "tabindex\|tabIndex", regex=true)-- tabindex usagesearch_text(repo, ":focus-visible\|:focus", regex=true, file_pattern="*.css")-- focus style scansearch_text(repo, "prefers-reduced-motion", file_pattern="*.css")-- motion media querysearch_text(repo, "alt=", file_pattern="*.tsx")-- alt text coveragesearch_symbols(repo, "useReducedMotion|usePrefersReducedMotion", include_source=true)-- motion hook usage
Degraded Mode (CodeSift unavailable)
| CodeSift tool | Fallback | Lost capability |
search_text (ARIA) | Grep for ARIA attributes | Same coverage, more tokens |
search_symbols (hooks) | Grep for hook names | Less precise matches |
get_file_tree | find command | Slower, no symbol counts |
get_file_outline | Read each file | More tokens consumed |
Dimensions (A1-A10)
A1: Semantic HTML (weight 10)
| Check | WCAG | Detection |
| Heading hierarchy (h1-h6 in order, no skips) | 1.3.1 | Scan for <h1>-<h6> ordering per page/component |
| Landmark regions (nav, main, aside, footer, header) | 1.3.1 | Grep for landmark elements or ARIA landmark roles |
| Lists used for list content (not divs) | 1.3.1 | Pattern: repeated sibling divs that should be <ul>/<li> |
| Tables with proper thead/th/scope | 1.3.1 | Grep for <table> without <th> or missing scope |
| Buttons vs links (button for actions, a for navigation) | 4.1.2 | <a> with onClick and no href, <div> with click handlers |
A2: Keyboard Navigation (weight 12, CRITICAL GATE)
| Check | WCAG | Detection |
| All interactive elements focusable | 2.1.1 | <div onClick> without tabIndex or role="button" |
| Tab order matches visual order (no positive tabindex) | 2.4.3 | tabindex values > 0 |
| Focus visible on all interactive elements | 2.4.7 | :focus-visible or :focus styles present for interactive elements |
| No keyboard traps | 2.1.2 | Modal/dialog without escape handler, custom widgets without blur path |
| Skip navigation link present | 2.4.1 | First focusable element links to #main or #content |
| Custom component keyboard handlers | 2.1.1 | Custom interactive elements missing onKeyDown/onKeyUp for Enter, Space, Escape, Arrow keys |
| Modal/dialog focus management | 2.4.3 | Focus trapped inside modal, focus returns to trigger on close |
A3: ARIA Patterns (weight 10)
| Check | WCAG | Detection |
| ARIA roles match component behavior | 4.1.2 | Role attribute vs actual element behavior |
| aria-label/aria-labelledby on elements without visible text | 4.1.2 | Icon buttons, image-only links without label |
| aria-expanded on toggleable elements | 4.1.2 | Dropdowns, accordions missing aria-expanded |
| aria-live regions for dynamic content | 4.1.3 | Toast, notification, status updates without aria-live |
| aria-hidden on decorative elements | 4.1.2 | Decorative icons/images without aria-hidden="true" |
| No redundant ARIA | 4.1.2 | role="button" on <button>, role="link" on <a> |
| aria-describedby for form field help text | 1.3.1 | Help text near inputs without association |
A4: Color & Contrast (weight 10, CRITICAL GATE)
| Check | WCAG | Detection |
| Text contrast >= 4.5:1 (normal), >= 3:1 (large) | 1.4.3 | Extract color values from CSS/tokens, compute ratios |
| UI component contrast >= 3:1 | 1.4.11 | Border, icon, form control colors vs background |
| Information not conveyed by color alone | 1.4.1 | Status indicators, error states using only color |
| Focus indicator contrast >= 3:1 | 1.4.11 | Focus ring color vs surrounding background |
| Light and dark theme coverage | 1.4.3 | Both themes checked if prefers-color-scheme or theme toggle exists |
A5: Forms & Inputs (weight 10)
| Check | WCAG | Detection |
| Every input has associated label | 1.3.1, 3.3.2 | <input> without <label>, aria-label, or aria-labelledby |
| Error messages linked to fields | 3.3.1 | Error elements without aria-describedby or aria-errormessage |
| Required fields marked | 3.3.2 | Missing aria-required="true" and no visual indicator |
| Autocomplete attributes on common fields | 1.3.5 | Name, email, phone, address inputs without autocomplete |
| Form validation errors announced | 4.1.3 | Error summary not in aria-live region |
| Related fields grouped | 1.3.1 | Radio groups, address fields without <fieldset>/<legend> |
A6: Images & Media (weight 8)
| Check | WCAG | Detection |
| Informative images have alt text | 1.1.1 | <img> without alt, or alt="image" / alt="photo" |
| Decorative images have alt="" or aria-hidden | 1.1.1 | Decorative images with meaningful alt |
| Complex images have long description | 1.1.1 | Charts, diagrams without aria-describedby or <figcaption> |
| Video has captions/subtitles | 1.2.2 | <video> without <track kind="captions"> |
| Audio has transcript | 1.2.1 | <audio> without transcript link |
| SVG has title or aria-label | 1.1.1, 4.1.2 | <svg> without <title> or aria-label |
| No auto-playing media | 1.4.2 | autoplay attribute without pause control |
A7: Responsive & Zoom (weight 6)
| Check | WCAG | Detection |
| Content reflows at 320px width | 1.4.10 | Horizontal scroll triggers, fixed-width containers |
| Text resizable to 200% | 1.4.4 | Font sizes in px instead of rem/em |
| Touch targets minimum 44x44px | 2.5.8 | Small click/tap targets (links, buttons, icons) |
| No content hidden at zoom | 1.4.10 | overflow: hidden on containers with text |
| Viewport no disable scaling | 1.4.4 | maximum-scale=1 or user-scalable=no in viewport meta |
A8: Motion & Animation (weight 5)
| Check | WCAG | Detection |
| prefers-reduced-motion respected | 2.3.3 | CSS @media (prefers-reduced-motion) present |
| No content flashes > 3 times/sec | 2.3.1 | Animation durations < 333ms with repeating patterns |
| Animations can be paused/stopped | 2.2.2 | Auto-playing animations without pause control |
| Carousels have pause control | 2.2.2 | Auto-advancing carousels without pause button |
| Page transitions respect reduced motion | 2.3.3 | Route transitions without motion preference check |
A9: Reading & Content (weight 5)
| Check | WCAG | Detection |
| html lang attribute set | 3.1.1 | <html> without lang attribute |
| Language changes marked | 3.1.2 | Foreign-language content without lang attribute |
| Link text is descriptive | 2.4.4 | "click here", "read more", "learn more" without context |
| Consistent navigation | 3.2.3 | Nav component differs across pages |
| Page titles descriptive and unique | 2.4.2 | Missing <title>, duplicate titles, generic titles |
A10: Legal Compliance Status (NOT scored — separate legal risk section)
A10 is a qualitative legal risk assessment, not a scored dimension. It does NOT contribute to the numerical score (to avoid double-counting A1-A9 results). It appears as a standalone section in the report.
| Check | Standard | Detection |
| ADA Title II compliance (deadline: 2026-04-24) | ADA | Map A1-A9 failures to ADA requirements. If audit date < deadline: flag as APPROACHING. If audit date >= deadline: flag as POST-DEADLINE (compliance now mandatory). |
| European Accessibility Act compliance | EAA | Map failures to EAA requirements (if EU-facing) |
| Section 508 compliance | 508 | Map failures to Section 508 (if government) |
| VPAT readiness | VPAT | Assess documentation completeness for VPAT generation |
| Accessibility statement present | All | Check for /accessibility page or statement in footer |
Phase 0: Detection
- Detect framework: React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Astro, Angular, plain HTML
- Check
package.jsondependencies, config files (next.config.*,astro.config.*,svelte.config.*,angular.json)
- Check
- Detect component library: MUI, Chakra, Radix, Headless UI, shadcn, Mantine, Ant Design, none
- Check
package.jsondependencies
- Check
- Detect existing a11y tooling:
eslint-plugin-jsx-a11yin devDependenciesaxe-coreor@axe-core/*in devDependenciespa11yin devDependencies or globaljest-axeorvitest-axein devDependencies- Storybook a11y addon (
@storybook/addon-a11y)
- Detect existing a11y config:
.axercoraxe.config.js.pa11yor.pa11ycieslintrcwith jsx-a11y rules
- Estimate scope: Count pages/components for workload sizing
Output:
A11Y DETECTION
Framework: [name]
Components: [library or "custom"]
A11y tools: [list or "none detected"]
A11y config: [list or "none"]
Scope: [N pages, N components]
Standard: WCAG 2.2 [AA|AAA]
Legal focus: [ADA Title II | EAA | Section 508 | N/A]Phase 1: Static Code Analysis (A1-A9)
Scan templates, JSX/TSX, CSS, and config files against all dimension checks.
1.1 Batch Scans
Run grep/CodeSift scans across the codebase for:
| Scan | Target | Dimension |
| Heading inventory | <h1>-<h6> elements per file | A1 |
| Landmark elements | <nav>, <main>, <aside>, <header>, <footer> | A1 |
| ARIA attributes | aria-* attribute usage and coverage | A3 |
| Focus styles | :focus-visible, :focus, outline: in CSS | A2 |
| Tabindex usage | tabindex/tabIndex values | A2 |
| Skip nav link | First focusable element pattern | A2 |
| Keyboard handlers | onKeyDown, onKeyUp, onKeyPress on custom elements | A2 |
| Color values | Hardcoded hex/rgb in CSS, contrast-relevant variables | A4 |
| Alt text | alt= attribute presence and quality | A6 |
| Form labels | <label>, aria-label, aria-labelledby on inputs | A5 |
| Autocomplete | autocomplete on common input types | A5 |
| Viewport meta | viewport meta tag content | A7 |
| Reduced motion | prefers-reduced-motion media query | A8 |
| Lang attribute | <html lang= in root templates | A9 |
| Link text | "click here", "read more", "learn more" patterns | A9 |
| SVG accessibility | <title> or aria-label on SVGs | A6 |
1.2 eslint-plugin-jsx-a11y Integration
If eslint-plugin-jsx-a11y is detected:
- Grep the ESLint config for disabled
jsx-a11y/*rules — note each as an intentional exception - Run with project config:
npx eslint --ext .jsx,.tsx [scope]— captures what the project considers violations - Run baseline scan:
npx eslint --no-eslintrc --plugin jsx-a11y --rule '{...}' [scope]— captures ALL violations including intentionally suppressed ones - Diff the two runs — suppressions found in config but not in baseline are intentional exceptions. Report them as
[SUPPRESSED]findings (user decided to allow this) vs[ACTIVE]findings (violations the project config also flags)
If not available: skip, rely on manual scan.
1.3 Per-Component Scoring
For each page/component in scope, evaluate A1-A9 checks:
### [file path]
Component type: [PAGE | FEATURE | SHARED]
| Dim | Score | Max | Evidence |
|-----|-------|-----|----------|
| A1 | [N] | 10 | [summary] |
| A2 | [N] | 12 | [summary] |
| A3 | [N] | 10 | [summary] |
| A4 | [N] | 10 | [summary] |
| A5 | [N] | 10 | [summary] |
| A6 | [N] | 8 | [summary] |
| A7 | [N] | 6 | [summary] |
| A8 | [N] | 5 | [summary] |
| A9 | [N] | 5 | [summary] |
Critical gates: A2=[N]/12 A4=[N]/10 -- [PASS/FAIL]Scoring per dimension: Each check within a dimension scores proportionally. Example: A1 has 5 checks, each worth 2 points (total 10). A check scores 0 (fail), 1 (partial), or full points (pass).
Dispatch follows ../../shared/includes/execution-policy.md through env-compat. Reuse existing
authorization within that policy; session restrictions take precedence. Run each required gate
and report its actual independence or an unmet requirement.
If >10 components: Split into batches of 5. Dispatch background agents where env-compat supports parallel dispatch.
Phase 2: Automated Testing
2.1 Browser-Based (if --live-url and browser MCP available)
If mcp-accessibility-scanner is available:
scan_page(url)per route for axe-core violationsscan_page_matrix(url, variants=["mobile", "forced-colors", "reduced-motion", "zoom-200%"])for variant testingaudit_keyboard(url)for tab order, focus visibility, keyboard traps
If chrome-devtools MCP is available but not accessibility-scanner:
- Navigate to pages via
navigate_page - Run
evaluate_scriptwith axe-core injection - Take screenshots at multiple viewport sizes
axe-core results override static scan findings: Where automated tools provide definitive results, they take precedence over grep-based analysis.
2.2 pa11y Integration (if available)
If pa11y is available:
npx pa11y [url] --reporter json --standard WCAG2AAParse JSON output, map violations to A1-A10 dimensions.
2.3 Automated Coverage Note
Automated tools catch approximately 30-57% of WCAG issues. The following CANNOT be caught by automated tools and require manual verification:
- Meaningful alt text quality (automated can detect presence, not quality)
- Keyboard trap detection in complex widgets
- Logical reading order
- Content comprehension at different zoom levels
- Whether color alone conveys information (context-dependent)
- Focus management correctness in SPAs
- Screen reader announcement quality
Phase 3: Manual Checklist Verification
For each dimension, verify against WCAG 2.2 success criteria:
- Map every finding to a specific WCAG criterion (e.g., "1.1.1 Non-text Content", "2.1.1 Keyboard")
- Classify each check as:
- PASS -- criterion satisfied with evidence
- FAIL -- criterion violated with evidence
- CANNOT DETERMINE -- requires manual verification (e.g., screen reader testing, cognitive assessment)
- For CANNOT DETERMINE items, describe what manual test is needed
WCAG Level mapping:
- Level A (minimum): 1.1.1, 1.2.1, 1.3.1, 1.4.1, 2.1.1, 2.1.2, 2.2.2, 2.3.1, 2.4.1, 2.4.2, 2.4.3, 2.4.4, 3.1.1, 3.2.1, 3.3.1, 3.3.2, 4.1.2
- Level AA (standard target): Level A + 1.3.5, 1.4.3, 1.4.4, 1.4.10, 1.4.11, 2.4.7, 3.1.2, 3.2.3, 3.3.3, 4.1.3
- Level AAA (if
--standard AAA): Level AA + 1.4.6 (7:1 contrast), 2.3.3, 2.4.9, 2.5.8, 3.1.5, 3.1.6
Phase 4: Fix Generation (if --fix or findings exist)
For each finding, generate a specific code fix:
### A11Y-[NNN]: [Title]
Dimension: A[N]
WCAG: [criterion number] [criterion name]
Severity: CRITICAL | HIGH | MEDIUM
Level: A | AA | AAA
File: [path:line]
Impact: [who is affected and how]
Before:
[code snippet showing the violation]
After:
[code snippet with the fix applied]
Notes: [implementation considerations]Prioritization order:
- Legal risk (CRITICAL findings in dimensions relevant to
--legalstandard) - User impact (keyboard/screen reader blockers > visual issues > enhancements)
- Effort (quick wins first within same priority tier)
If --dry-run flag is set: report all fixes without applying. Show before/after code for each fix.
If --fix flag is set:
- Create rollback tag:
git tag a11y-fix-YYYY-MM-DDbefore applying any changes - Apply all CRITICAL and HIGH fixes automatically. MEDIUM fixes are reported but not auto-applied.
- Run verification: check that fixes don't break existing tests
- If tests fail after a fix: revert that specific fix, keep the tag for manual rollback
Scope guard: Fixes touch only accessibility attributes, ARIA properties, semantic elements, CSS focus/contrast styles, and meta tags. Fixes do NOT modify business logic, data fetching, or application state.
Phase 5: Report & Backlog
5.1 Read Stage 2 Files
Read deferred files:
3. ../../shared/includes/run-logger.md -- [READ | MISSING -> STOP]
4. ../../shared/includes/retrospective.md -- [READ | MISSING -> STOP]
5. ../../shared/includes/backlog-protocol.md -- [READ | MISSING -> degraded]5.2 Scoring
Per-dimension scoring: Each dimension has a max weight. Score = sum of check scores within dimension.
Overall score: (total earned / total possible) * 100 — A10 excluded from score (legal risk section only, max = 76 from A1-A9).
Critical gates (explicit pass thresholds):
- A2 (Keyboard Navigation) < 6/12 --> automatic FAIL regardless of overall score
- A4 (Color & Contrast) < 5/10 --> automatic FAIL regardless of overall score
Grade thresholds:
| Grade | Score | Condition |
| A | >= 85% | All critical gates pass |
| B | >= 70% and < 85% | All critical gates pass |
| FAIL | < 70% | OR any critical gate fails |
VERDICT mapping for run log — A → PASS, B → WARN, FAIL → FAIL; a failing critical gate forces FAIL at any score.
Two things this table used to get wrong. The bands were written 70-84 / >= 85, so a real 84.4%
matched neither. And the verdict line said "PASS (A or B), WARN (B with critical gate borderline)",
which both contradicted the field-resolution section below (there, 70-84% maps to WARN, not PASS)
and invented a state the table forbids — B already requires every critical gate to pass, so
"B with a borderline gate" cannot occur, and "borderline" is defined nowhere. A critical gate is
PASS or FAIL; there is no third position.
5.3 Report Output
REQUIRED: emit the Tool Availability Block (template in ../../shared/includes/codesift-setup.md) at the top of the report, after the title and before findings. Auditing degraded runs depends on this — do NOT skip it.
ACCESSIBILITY AUDIT REPORT
===============================================
Project: [name]
Date: [ISO-8601 date]
Framework: [detected]
Component Library: [detected or "custom"]
Standard: WCAG 2.2 [AA|AAA]
Legal: [ADA Title II | EAA | Section 508 | N/A]
A11y Tooling: [detected tools or "none"]
SCORE: [N]% -- Grade [A/B/C/FAIL]
===============================================
## Critical Gate Status
A2 (Keyboard Navigation): [PASS/FAIL] ([N]/12)
A4 (Color & Contrast): [PASS/FAIL] ([N]/10)
## Dimension Scores
| # | Dimension | Score | Max | Key WCAG Criteria |
|---|-----------|-------|-----|-------------------|
| A1 | Semantic HTML | [N] | 10 | 1.3.1, 4.1.2 |
| A2 | Keyboard Navigation | [N] | 12 | 2.1.1, 2.1.2, 2.4.7 |
| A3 | ARIA Patterns | [N] | 10 | 4.1.2, 4.1.3 |
| A4 | Color & Contrast | [N] | 10 | 1.4.1, 1.4.3, 1.4.11 |
| A5 | Forms & Inputs | [N] | 10 | 1.3.1, 3.3.1, 3.3.2 |
| A6 | Images & Media | [N] | 8 | 1.1.1, 1.2.1, 1.2.2 |
| A7 | Responsive & Zoom | [N] | 6 | 1.4.4, 1.4.10 |
| A8 | Motion & Animation | [N] | 5 | 2.2.2, 2.3.1, 2.3.3 |
| A9 | Reading & Content | [N] | 5 | 2.4.2, 3.1.1, 3.2.3 |
| A10 | Legal Compliance | [N] | 4 | (aggregate) |
| | **Total** | **[N]** | **80** | |
## Findings (sorted by legal risk, then user impact)
### A11Y-001: [Title]
Dimension: A[N]
WCAG: [criterion number and name]
Severity: CRITICAL | HIGH | MEDIUM
File: [path:line]
Impact: [who is affected and how]
Fix: [specific code change or reference to Phase 4 fix]
### A11Y-002: [Title]
...
## Legal Compliance Summary
| Standard | Status | Key Gaps |
|----------|--------|----------|
| WCAG 2.2 AA | [PASS / PARTIAL / FAIL] | [summary] |
| ADA Title II | [COMPLIANT / AT RISK / NON-COMPLIANT / N/A] | [summary] |
| EAA | [COMPLIANT / AT RISK / NON-COMPLIANT / N/A] | [summary] |
| Section 508 | [COMPLIANT / AT RISK / NON-COMPLIANT / N/A] | [summary] |
## Automated vs Manual Coverage
Automated checks (axe-core/pa11y): [N issues found | "not run"]
Static code analysis: [N issues found]
Manual verification needed: [N items flagged as CANNOT DETERMINE]
## Per-Component Breakdown
| File | A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | Total | Grade |
|------|----|----|----|----|----|----|----|----|----|----- -|-------|
| [path] | [N] | [N] | [N] | [N] | [N] | [N] | [N] | [N] | [N] | [N]% | [A-FAIL] |5.4 Backlog Persistence
One rule: when --persist-backlog is set, or the run has at least one CRITICAL finding, every CRITICAL or HIGH finding of the run goes through backlog-add (the HIGH ones too, not only the CRITICAL that triggered it), one call per finding (../../shared/includes/backlog-protocol.md "Filing from a skill"; the bars and the dedupe are the protocol's, so compute no fingerprint and no seen count). With neither the flag nor a CRITICAL finding, nothing is recorded. <level> is critical or high.
A Generic write per finding. In the repository, an A2 keyboard trap or an A5 form finding that names the input and the wrong result is a BUG file record, and takes --anchor "$A", copied from the line that shows the defect or, for something absent (a control with no label, no key handler), from the line of the code that lacks it ("The location rule"): ~/.zuvo/backlog-add --repo "$R" --class BUG --conf <N> --source a11y-audit --file "$F" --line <n> --anchor "$A" --severity <level> --title "$T". Every other finding is a CQ, with no anchor: ~/.zuvo/backlog-add --repo "$R" --class CQ --conf <N> --source a11y-audit --file "$F" --line <n> --severity <level> --title "$T"; a finding that covers the whole component is a whole-file finding (--line 1, a "Whole file: ..." title).
A Phase 2 finding on the live page with no repository file causing it is a target record, which takes no anchor at all (--target "$U" --evidence "$E" in place of --file, --line and --anchor), with U the page URL and its own class by the same test: a BUG for an A2 or A5 finding that names the input and the wrong result, ~/.zuvo/backlog-add --repo "$R" --class BUG --conf <N> --source a11y-audit --target "$U" --evidence "$E" --severity <level> --title "$T"; otherwise a CQ, ~/.zuvo/backlog-add --repo "$R" --class CQ --conf <N> --source a11y-audit --target "$U" --evidence "$E" --severity <level> --title "$T". E holds the axe-core rule, the selector and the element's tag and attributes without any value= attribute or field content, and U has no query string; a secret or user data is never copied into a record (backlog-protocol.md "Filing from a skill", "The location rule", the secrets sentence).
Assign "$R" and "$T" before each call, "$F" and "$A" only for a file finding ("$A" only for a BUG), "$U" and "$E" only for a live-page finding, as "Free text goes through a variable" in that section says; an empty value you pass is a bug, and backlog-add refuses a missing required field (REFUSED missing-field:<f>). Report the B- or F-id each call prints and Recorded: N (backlog: a, ledger: b) ("The report line" in backlog-protocol.md), plus each NOT PERSISTED (<reason>) by name; on a non-zero exit act on the protocol's exit table, and never append by hand.
This audit does not commit: it stages nothing. It lists the wrote= paths backlog-add printed as Backlog writes: <path>, ... (Backlog writes: none when there are none), in its report for the user when it runs standalone, and in its report for the calling skill's closing commit to carry when another skill runs it (backlog-protocol.md "Filing from a skill", Committing what backlog-add wrote).
5.5 Save Report
Save to: zuvo/audits/a11y-audit-YYYY-MM-DD.md — at the project root (zuvo/ resolves via git rev-parse --show-toplevel; override $ZUVO_OUTPUT_DIR. See ../../shared/includes/report-output-location.md).
5.6 Propose Next Actions
| Finding | Action | Command |
| Critical gate A2 failure | Fix keyboard navigation | zuvo:build fix keyboard traps in [component] |
| Critical gate A4 failure | Fix contrast | zuvo:build update color tokens for WCAG contrast |
| Multiple A3 ARIA issues | Fix ARIA patterns | zuvo:build add ARIA attributes to [component] |
| A5 form issues | Fix form accessibility | zuvo:build add form labels and error association |
| No a11y tooling | Add eslint-plugin-jsx-a11y | zuvo:build add eslint-plugin-jsx-a11y |
| Broad failures (Grade C/FAIL) | Full multi-agent UI review | zuvo:ui-design-team [path] |
| DX12-DX17 also failing | Run design-review | zuvo:design-review [path] |
Completion Gate Check
Before printing the final output block, verify every item. Unfinished items = pipeline incomplete.
COMPLETION GATE CHECK
[ ] A11y tooling detection printed
[ ] Critical gates printed: A2 (Keyboard) and A4 (Contrast)
[ ] Per-component score table present with all A1-A9 dimensions
[ ] Findings sorted by legal risk first
[ ] Report saved to zuvo/audits/
[ ] Run: line printed and appended to logCompletion
After completing the audit, print:
A11Y-AUDIT COMPLETE
-----
Components audited: [N]
Standard: WCAG 2.2 [AA|AAA]
Score: [N]% -- Grade [A/B/C/FAIL]
Critical gates: A2=[PASS/FAIL] A4=[PASS/FAIL]
Findings: [N] CRITICAL, [N] HIGH, [N] MEDIUM
Fixes generated: [N] (if --fix)
Legal: [status summary]
Run: <ISO-8601-Z> a11y-audit <project> <score>% - <VERDICT> - <N>-dimensions <NOTES> <BRANCH> <SHA7> <INCLUDES> <TIER>
-----Validity Gate (REQUIRED — print BEFORE Run line, AFTER retro append + append-runlog)
VALIDITY GATE
required_tool_calls:
get_file_tree: [<N> | NOT_CALLED]
search_text: [<N> | NOT_CALLED]
search_symbols: [<N> | NOT_CALLED]
search_patterns: [<N> | NOT_CALLED]
audit_scan: [<N> | NOT_CALLED]
react_tools: [<result> | not_required | NOT_CALLED]
postamble:
retros_log_appended: [yes(bytes_added=N) | NOT_APPENDED]
retros_md_appended: [yes(entry_count=N) | NOT_APPENDED]
verify_audit_pass: [yes(<verified>/<total>) | NOT_RUN | REJECTED]
gate_status: [PASS | FAIL]If gate_status = FAIL → VERDICT = INCOMPLETE. Append the Run line via the retro-gated wrapper (NOT direct >> runs.log):
printf '%b\n' "$RUN_LINE" | ~/.zuvo/append-runlogRetrospective (REQUIRED)
Follow the retrospective protocol from retrospective.md.
Gate check → structured questions → TSV emit → markdown append.
If gate check skips: print "RETRO: skipped (trivial session)" and proceed.
After printing this block, append the Run: line value (without the Run: prefix) to the log file path resolved per run-logger.md.
Field resolution:
CQ_SCORE:<score>%(overall percentage)Q_SCORE:-(not applicable)VERDICT:PASS(>= 85%),WARN(>= 70% and < 85%),FAIL(< 70%, or any critical gate fails)TASKS:-DURATION:<N>-dimensions(number of dimensions scored, typically 10)NOTES:WCAG2.2-[AA|AAA] [N]-findings [legal-status](max 80 chars)
Next-Action Routing
| Finding | Action | Command |
| Keyboard traps, missing focus | Fix keyboard navigation | zuvo:build [description] |
| Contrast failures | Fix color tokens | zuvo:build [description] |
| Missing ARIA on components | Fix ARIA patterns | zuvo:build [description] |
| Form a11y gaps | Fix form accessibility | zuvo:build [description] |
| Broad design issues | Multi-agent UI review | zuvo:ui-design-team [path] |
| Surface-level DX checks | Design consistency audit | zuvo:design-review [path] |
| Security concerns surfaced | Security audit | zuvo:security-audit [path] |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

