paqad-ai
Version:
Spec-driven development framework — AI agents that think before they type
56 lines (40 loc) • 3.4 kB
Markdown
---
name: accessibility-review
description: 'Audits the running UI against WCAG 2.2 A/AA (contrast, focus visibility, keyboard order, ARIA, target size, prefers-reduced-motion), with findings tagged WCAG-2.2.x. Use when any design-test run reaches the accessibility pass.'
metadata:
model_tier: reasoning
cacheable: 'false'
output_format: markdown
paqad-meta: skill.meta.yaml
---
## What It Does
Audits the UI against WCAG 2.2 A/AA. Combines (1) static scan for missing ARIA, missing alt text, and obvious focus issues with (2) axe-core results from the Playwright walk (Step 3 of the workflow). Every finding cites a WCAG 2.2 success criterion id: the design-test analog of WSTG ids in pentest.
## Use This When
For every design-test run. Driven by the live phase's axe-core output when available; static-only when the live phase is blocked.
## Inputs
- Read `docs/instructions/design-system/accessibility.md` for declared a11y rules.
- Read `references/wcag-mapping.md` to map findings to WCAG ids.
- Read the axe-core results JSON from `runtime-checks.ts` if the live phase ran.
## Procedure
Detection and mapping are deterministic: the LLM picks severity and writes
findings; the scripts do the spotting.
1. Static scan: run `scripts/static-a11y-scan.sh [search-root]` → TSV of `<category>\t<file>:<line>\t<excerpt>`. Categories: `img-no-alt | button-no-name | anchor-no-name | input-no-label | outline-zero | positive-tabindex | missing-lang`.
2. Live axe results: when the Step 3 runtime walk produced an axe JSON, run `scripts/parse-axe-violations.sh <axe-results.json>` → TSV of `<route>\t<rule-id>\t<impact>\t<target>\t<help>`. Accepts a full runtime-checks payload or a bare violations array.
3. For each axe rule emitted, run `scripts/map-axe-to-wcag.sh <rule-id>` to get its primary WCAG 2.2 success criterion id. Unmapped rules return `WCAG-UNKNOWN`; map those manually using the published axe docs.
4. Verify each rule declared in `accessibility.md`: contrast ratio met, focus ring visible, target size ≥ declared minimum, reduced-motion respected, keyboard order matches reading order.
5. Cross-reference with `tokens.md`: contrast violations point at the token pair that's failing (e.g. `color.text.muted` on `color.surface.base` = 3.8:1, below 4.5:1).
## Output Contract
- Match `assets/output.template.md`. `contract_ref` is a WCAG id like `WCAG-2.2-1.4.3` (contrast) or the relevant `accessibility.md` clause.
- Default severity: WCAG Level A violations → **blocker**, Level AA → **high**, design-system-specific rules → **medium**.
- Output must pass `scripts/lint-findings.sh` (exit 0).
## Escalate / Stop Conditions
- Ask when no axe-core results are available AND the static scan found nothing: coverage may be inadequate. Emit a `blocked_checks` entry noting the live phase didn't run.
- Warn when `accessibility.md` is missing: defer to `design-system-coverage` (tier likely `bare`); run as exploratory.
## Resources
- `references/wcag-mapping.md`
- `scripts/static-a11y-scan.sh`: static-only a11y violation candidates (img/button/anchor/input/tabindex/outline/lang).
- `scripts/parse-axe-violations.sh`: flatten axe-core JSON into `(route, rule, impact, target)` rows.
- `scripts/map-axe-to-wcag.sh`: table lookup from axe rule id to WCAG 2.2 success criterion.
- `scripts/lint-findings.sh`
- `assets/output.template.md`
- `agents/openai.yaml`