WCAG Auditor Skill
Two-Phase Audit Protocol
Phase 1 — Deterministic (tools first)
Run real tools. They catch 30–40% of issues with zero false negatives on what they cover.
# 1a. Check if eslint-plugin-jsx-a11y is available
npx eslint --no-eslintrc -c '{"plugins":["jsx-a11y"],"extends":["plugin:jsx-a11y/recommended"],"parser":"@babel/eslint-parser","parserOptions":{"requireConfigFile":false,"babelOptions":{"presets":["@babel/preset-react"]}}}' \
--ext .jsx,.tsx src/ 2>/dev/null | head -60
# 1b. If axe-cli available — run against local dev server
npx axe http://localhost:3000 --reporter json 2>/dev/null | head -80
# 1c. Quick deterministic grep (high signal-to-noise patterns only)
echo "=== Images without alt ===" && grep -rn '<img[^>]*>' src/ --include='*.tsx' --include='*.jsx' | grep -v 'alt=' | grep -v '//'
echo "=== Interactive divs/spans ===" && grep -rn '<\(div\|span\)[^>]*onClick' src/ --include='*.tsx' --include='*.jsx' | grep -v 'role=\|//.*onClick'
echo "=== Inputs without label association ===" && grep -rn '<input' src/ --include='*.tsx' --include='*.jsx' | grep -v 'type="hidden"\|aria-label\|aria-labelledby\|id='
echo "=== outline:none without replacement ===" && grep -rn 'outline.*:.*none\|outline.*:.*0' src/ --include='*.css' --include='*.scss' --include='*.tsx'
echo "=== Missing lang on html ===" && grep -rn '<html' public/ --include='*.html' | grep -v 'lang='
Interpret tool output before proceeding to Phase 2. If eslint/axe output is available — list all reported issues first, mapped to WCAG criteria.
Phase 2 — LLM Analysis (what tools miss)
Tools cannot check: logical focus order, meaningful alt text quality, context-appropriate ARIA labels, color contrast in CSS-in-JS/Tailwind, screen reader announcement flow, keyboard UX patterns.
Decision tree for Phase 2:
- ARIA correctness? → read
references/aria-roles.md - Color contrast values? → read
references/color-contrast.md - Screen reader flow / live regions / focus management? → read
references/screen-reader.md - Specific fix needed? → read
references/fix-suggestions.md - Full criterion reference? → read
references/wcag-checks.md
Phase 3 — Structured Report
Format every finding as:
[SEVERITY] WCAG X.X.X — Issue description
File: path/to/file.tsx:42
Source: eslint-jsx-a11y / axe-core / manual
Before: <problematic code>
After: <fixed code>
Severity levels:
- Critical (WCAG A) — blocks screen reader users entirely
- High (WCAG AA) — fails legal compliance threshold
- Medium (WCAG AA) — degraded experience
- Low (WCAG AAA) — best practice
End every report with:
Tool coverage: ~35% of issues (eslint-jsx-a11y + axe-core)
Manual review: ~65% of issues (this analysis)
Recommendation: run axe DevTools in browser for final verification
Scope shortcuts
| User says | Do this |
|---|---|
| "audit my repo" | Run Phase 1 scan across all src/, report Phase 2 summary |
| "check this component" | Skip Phase 1, go straight to Phase 2 with provided code |
| "fix this error" | Read fix-suggestions.md, provide before/after |
| "contrast for #hex" | Read color-contrast.md, calculate ratio inline |
| "check my buttons/forms/nav" | Phase 1 grep for that element type, then Phase 2 |