From QA Automation
Review implementation fidelity between a live app and Figma design. Use for design QA, screen-to-frame mapping, Playwright snapshots, and read-only drift findings.
How this skill is triggered — by the user, by Claude, or both
Slash command
/qa-automation:design-qaThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You run an implementation-fidelity review: **is the rendered app faithful to the Figma design?**
You run an implementation-fidelity review: is the rendered app faithful to the Figma design? You are READ-ONLY — you produce findings and fix candidates; you never edit code or Figma.
This is a general method bound to a specific project by a manifest. The skill holds no project
facts. Each run resolves design-qa/<slug>/ (the manifest: project.json, screen-map.json,
conventions.md — see references/manifest-schema.md) and operates over it. The binding to a
project lives in that manifest, never hardcoded here; the method below is the same for every
project. The only deterministic code is scripts/design_snapshot.py (structured browser facts +
Layer-1 invariants). Mapping, correspondence, judgment, and localization are disciplined reasoning
over the three legs — disciplined by the layers and rules below, not improvised.
Empirical basis for the 3-layer method: references/spike-findings.md. The design-qa-reviewer
agent internalizes the full evidence-collection + decision-tree; this skill does not re-derive it.
<design-qa-skill-dir>/scripts/design_snapshot.py,
where <design-qa-skill-dir> is the installed skill directory shown in Codex's available-skills
list. The script imports its sibling dom_snapshot.py; both ship with this skill). Requires Playwright in the
active Python env: pip install playwright && playwright install chromium (optional python-dotenv
for env-based login). A remote browser extension may control a Chrome on a
different host that cannot reach the local dev server — confirm the snapshot's title/url match
the app under review.project.json.alignment.locale). After alignment,
residual sample-data text differences are still variations — establish correspondence by
structure (name+position), not raw string match.reach.viewport); layout still goes to
Layer 3..tmp/design-qa/. The
manifest under design-qa/<slug>/ IS tracked (team knowledge) and must never contain a snapshot.ls design-qa/ for an existing project; match it to the codebase/Figma
file the user named.project.json + screen-map.json + conventions.md. Skip to the
phase the user wants (a full sweep, or one screen). Re-runs merge, never overwrite.fileKey + seed page node-id (scope to ONE page for a large Figma file); how to run the
app + port; how locale/role are selected. Write project.json, then proceed to Phase 1 to
build screen-map.json + conventions.md.Exit criteria: a project.json exists for the slug and is loaded.
conventions.md as you find them.
Fan out: spawn parallel worker subagents (a fast, cheap tier) — one per router file / page
directory — each covering: route-level screens AND all overlays reachable from that route (modals,
drawers, dialogs, bottom sheets — find the trigger: button onClick, state flag, route param) AND
role-gated variants of each screen. Then synthesize the full list and resolve conflicts.get_metadata(fileKey, nodeId). The same screen often has a
distinct frame per role (a role-section variant) — match role too.get_design_context
text + screen purpose. Confident → record automatically; ambiguous or unmatched → ask the
user before recording.screen-map.json: each screen's { route, figmaNode, figmaFrameName, reach, match },
plus gaps.figmaOnly (designed, not built) and gaps.appOnly (built, not designed) — the
gaps are themselves review insight. Seed only validated entries; leave unknowns out.STATIC. Never silently skip a screen.Exit criteria: every reachable screen is in screen-map.json with a reach recipe and a
confidence; ambiguous matches were confirmed by the user; gaps recorded.
For each mapped screen (screens proceed in parallel — screen B captures while screen A is reviewed):
python "<design-qa-skill-dir>/scripts/design_snapshot.py" --manifest design-qa/<slug> --screen <screen> --out .tmp/design-qa/<screen>.snap.json --screenshot .tmp/design-qa/<screen>.png
Reach (locale/role/auth/viewport) is applied from the manifest automatically.
(Ad-hoc flags --viewport/--locale/--set-storage still work for one-off captures.)snap.json["invariants"] + snap.json["nodes"] — no Figma
reads, no judgment. The worker outputs preAnalysis:
layer1Flag: "clean" | list of fired signals ("truncated[N]", "offscreen[N]", "zeroSize[N]")candidateElements: filtered nodes keyed by guessed semantic kind
(status-badge, column-header, nav-item, form-field, action-button, image)regionSummary: { hasTable, hasBadges, hasNav, hasForm, badgeCount, tableRowCount }
This pre-classification is cheap here and makes the reviewer's key-map step a confirmation pass,
not an exploratory one.design_qa_reviewer (less advanced model / Sonnet tier) with coordinates + paths — not pre-fetched blobs:
figmaCoords: { fileKey, nodeId, channel? } — reviewer reads Figma directly through figma-mcp-express, scoped to its tasksnapshotPath: .tmp/design-qa/<screen>.snap.jsonscreenshotPath: .tmp/design-qa/<screen>.pngconventionsPath: design-qa/<slug>/conventions.mdpreAnalysis from step 2 — reviewer uses candidateElements as key-map scaffold
The reviewer is the only PASS authority; do not self-approve.Exit criteria: each screen has a reviewer verdict with a non-trivial key map; no Layer-1 harm signal is left unexplained.
UNCERTAIN
finding — each running a targeted grep for the i18n key / route / conditional render cited in
the finding's coverageNote. Each worker resolves to VARIATION (exists, conditionally rendered) or
escalates to VIOLATION (key/route absent). Collect results and update findings before reporting.file:line, theme variable family, component
import gap). Skip if ≤2 FAIL..tmp/design-qa/<screen>.review.json, then generate the
screen-keyed report:
python "<design-qa-skill-dir>/scripts/generate_report.py" --screen-map design-qa/<slug>/screen-map.json --out reports/design_qa_<date>.json .tmp/design-qa/*.review.json.
The report contains a coverage matrix (mapped screens + figma-only/app-only/STATIC gaps),
per-screen PASS/FAIL, and each drift as {layer, severity, where, figmaValue, renderedValue, why, file, fix}. Do not route design-qa findings through behavioral-QA tooling that expects tc_id.conventions.md. Never
clobber the file.Exit criteria: report produced; manifest merged forward (not overwritten).
Auto-fixing code / opening PRs (review is READ-ONLY — findings + fix candidates only). Behavioral QA. Naive pixel screenshot diff / whole-tree node diff.
Guides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
npx claudepluginhub wondermove-inc/awsome-figima-skills --plugin qa-automation