| name | product-ui-audit |
| description | Audit product / consumer UI code (非 design-system 本身) against DS usage discipline + mindset adherence. Catches element misuse / design principle violations / token leakage / geometry bugs / a11y gaps across 7 dimensions. Invoke via /product-ui-audit when user says「audit 這個 UI」「檢查 X feature 用對 DS 嗎」「這段 code 符合設計原則嗎」,or auto-invoked by /prototype Phase 3.5 gate. |
Product UI Audit Workflow
Purpose: design-system-audit audits the DS itself(spec / cva / SSOT 三方漂移);product-ui-audit audits consumer UI code(不是 DS 本身,是 app / exploration / feature code — 即「consumer 用 DS 的地方」)。防止:
- 元件亂用(wrong variant / missing props / incorrect composition)
- 設計原則亂用(placeholder 文案 / 憑直覺創造 pattern / Mindset 違反)
- Token 逃逸(硬寫 hex / shadcn alias 回流 / shadow-sm 繞過 elevation)
- 幾何 bug(flex gap token 被 overflow 吃、slot box 不一致)
- A11y 缺口
When to run
明確觸發(直接 invoke):
- User 說「audit 這個 UI」「audit X feature」「檢查 /src/app/xxx」
- User 說「這段 code 符合設計原則嗎」「DS 用對了嗎」「有元件亂用嗎」
/prototype Phase 3.5 自動 invoke(audit src/explorations/{topic-slug}/)
- PR review 前自我檢查
不觸發:
- 要 audit DS 本身 → 走
/design-system-audit(不同 scope)
- 要 audit token 定義 → 走
design-system-audit
- 只要求補 stories → 直接補,不需 audit
生態位
/design-system-audit audit DS 本身(設計系統內部)
/product-ui-audit audit consumer UI code(本 skill)
/prototype 呼叫本 skill 作 Phase 3.5 gate
/delivery-handoff 只在產品交付前執行(產 handoff 文件)
Preconditions
- User 指定 audit target(file path / folder / feature area)
- Target 是 consumer 層 UI code(
src/app/** / src/explorations/** / src/pages/** / src/features/** / apps/**(含 DS repo 自家 apps/template + create-app 產物)等 — 不掃 packages/design-system/src/)
- CLAUDE.md 全讀(7 維 audit 都依此為基準)
7-Dimension Audit
每個 dimension 獨立檢查,產出 findings。詳細 grep pattern + rule 見 references/audit-checks.md。
Dim 1 — Token 紀律(token hygiene)
- 硬寫 hex / rgb / rgba / hsl 色值
- shadcn compat alias(bg-popover / text-muted-foreground / bg-accent / bg-destructive / bg-background / bg-card / border-input / text-primary-foreground / text-accent-foreground / text-card-foreground / text-popover-foreground)(完整 deny-list SSOT:
packages/design-system/src/tokens/utility-registry.json;此處 inline 為 grep 便利,新增 alias 改 registry)
- Tailwind default shadow(shadow-sm / md / lg / xl / 2xl / inner)— 應走 elevation token
- Tailwind v4
[--foo] shorthand 靜默失效
- 硬寫 px 值當該用 token(
w-[48px] 應改 token)
此維對齊既有 token 防線(lib/_token_hygiene.sh 5-check:shadcn alias / v4 shorthand / hardcoded shadow / primitive-color-as-utility / native overflow,由 post_edit_dispatcher.sh source;+ check_opacity_token_usage.sh 讀 utility-registry.json)+ 擴充硬色值 / 硬 px 檢查。
Dim 2 — Layout primitive 消費(per CLAUDE.md 清單)
掃是否正確消費既有 layout primitives(非自 roll):
| 視覺 pattern | 應消費 | 違規 signal |
|---|
| icon+title+desc 垂直居中 | <Empty> | 自己寫 flex flex-col items-center 3-layer text |
| row prefix+content+suffix | item-layout | 自己寫 flex items-center gap-2 3-slot |
| overlay Header/Body/Footer | overlay-surface | 自己寫 border-b/border-t padding loose/tight |
| 橫向按鈕列 | action-bar pattern | 自己 flex gap-2 按鈕組 |
| 水平溢出 + fade mask | horizontal-overflow | 自己 overflow-x-auto + mask |
| 跨 OS 一致捲軸 | ScrollArea | native overflow-(auto|scroll) |
| 圖像 / media 容器 | AspectRatio | 硬寫 aspect-video / aspect-square class |
| Field wrapper | Field + fieldWrapperStyles | 自己 border + padding + startIcon + endAction |
Dim 3 — 元件使用正確性
- Button / Input / Select 等 variant / size / props 組合合理
- icon-only 有
aria-label
- Button primary 沒堆疊(一個 row 一個 primary)
- Input 外有 Field wrapper(非 standalone input)
- Composition 正確
- Popover 不放互動破壞(Dialog trigger in Popover content 避免)
- Accordion / Tabs / Carousel 不巢狀
- Radix API 用對
- Dialog 有 DialogTitle / DialogDescription for a11y
- DropdownMenu 不當 Select 用
Dim 4 — Mindset adherence
對齊 CLAUDE.md 5 條 mindset:
- M1 對標世界級:新 pattern 有對標備註? 或找得到對應既有元件?
- M2 不憑直覺發明:新數值(gap / padding / font-size)前有 grep 既有?
- M3 改一處看三處:若改 DS 的 cva defaultVariants,spec / docblock / anatomy 三方同步?
- M4 真實業務場景:stories / examples 用真實場景 (Jira / Stripe / Notion...)?無
Option A/B/C / 按鈕一 / Rule A?
- M5 猶豫就問:code 裡有 TODO-未確認留白?
Dim 5 — 視覺幾何(Mindset #1 視覺擴充 + .claude/references/ui-dev-rules.md「同 flex 列互動 slot 幾何鐵律」)
- 同 flex 行的互動 slot box 尺寸一致(例:FileItem status / delete 都 h-field-sm)
- hover-bg / ring / focus outline 不溢出 box 吃 gap token
- padding 對稱正確
- Typography tier 正確(text-body / text-caption / etc.,不自造
text-[13px])
Dim 6 — A11y
- icon-only 元件有
aria-label
- interactive element
role 正確
- Dialog / Popover / Sheet 有 title + description
- keyboard navigation 可用(Tab / Enter / Esc)
- color contrast(不用純 color 傳 state — 要 icon / label 配合)
詳見 references/audit-checks.md。
Dim 7 — D6 設計原則自檢(consumer 是否牴觸 DS canonical)
chain .claude/skills/design-system-audit/references/principle-audit-protocol.md 做 4 子維 scoped 對 consumer code:
- D6a 合理性:consumer 自己的設計判斷是否有 rationale(為什麼這樣用 DS 元件)
- D6b 一致性:跨 feature 同概念處理一致(同 team 兩頁面 dismiss 不應用不同方式)
- D6c 無矛盾:consumer 實作是否牴觸 DS spec 聲明(例:用 Button 作 dismiss 明顯違 item-anatomy SSOT)
- D6d 完整性:state 覆蓋(error / loading / empty)
判斷 auto vs STOP 依 protocol 公式。修 consumer code 一致化 = AUTO;建議修 DS canonical 本身 = STOP 提議。
Workflow
Phase 0 — Scope
確認 audit target:file / folder / feature area。提問 user 若模糊。禁止掃整個 repo(失焦)。
Phase 1 — Parallel 6-dim audit
7 個維度各自獨立 grep + code review。可 parallelize。
Phase 2 — Report
產出 report 表格:
| Dim | File:Line | Finding | Severity | Fix suggestion |
|-----|-----------|---------|----------|----------------|
| 1 Token | src/app/foo.tsx:42 | 硬寫 `#3b82f6` | P0 | 改 var(--primary) |
| 2 Layout | src/app/bar.tsx:87 | 自己寫 icon+title+desc 垂直堆疊 | P1 | 改用 `<Empty>` |
| 3 Component | src/app/baz.tsx:12 | icon-only Button 無 aria-label | P0 | 加 aria-label |
| ... |
⚠️ Checkpoint 1 — Triage & fix decision
類似 design-system-audit 的 triage checkpoint:
🔍 Audit 結果
P0(必修,無爭議):N 項
P1(批次修 + review):M 項
P2(需討論):K 項
先修 P0?還是全給 user 看?
詳見 references/report-template.md。
Phase 3 — Fix(optional)
若 user 同意 fix,surgical 修復。每批(Dim 1 / Dim 2 / ...)一個 commit。
Phase 4 — Verify
npx tsc --noEmit 通過
- re-run 本 skill(縮窄到原 findings)確認 zero regression
Phase 5 — Visual audit(stakeholder-gate,mandatory on stakeholder-visible work)
對齊 CLAUDE.md 稽核 canonical Tier 1 stakeholder-gate:產品 UI 要給 stakeholder / end-user 看之前,code + visual 雙層都要過。Phase 1-4 是 code 層;本 Phase 補視覺層。
Input:Phase 4 verify 過關的產品 UI(screens / routes / embedded widgets)
Process:
- 確認 user 有提供 URL 清單(產品 app routes)或 Storybook scenario id(若產品 stories 在 Storybook):
- URL mode:
npm run visual-audit -- --urls=<csv>(例:--urls=http://localhost:3000/inbox,http://localhost:3000/settings)
- Storybook mode:
npm run visual-audit -- --scope=component:<topic>
- Layer A mechanical(auto):WCAG 對比度 + DOM 幾何 assertion + retina screenshot →
snapshots/
- Layer B AI judgement(chain
/visual-audit skill):讀 snapshots/*.png,判斷設計合理性(視覺對齊 / 覆蓋限制 / 世界級對照 / typography hierarchy)
- Violation 分級:
- Contrast AA 不過 → P0(a11y 強制)
- Geometry assertion fail → P0(機械規則違反)
- Layer B AI 視覺判斷 finding → 按嚴重度 P0 / P1 / P2
Gate 規則:P0 有 → 停下修,不放給 stakeholder;P1 / P2 走跟 Phase 2 Report 同樣 user-decision 流程。
何時可跳:內部 UI(只給 engineer / admin 看,非 stakeholder / end-user)→ user 明示 skip,但建議跑一次 Layer A 抓 a11y P0。
為什麼 mandatory:code audit 對 + spec 對,視覺仍可能錯(對比不夠、overlay 疊到文字、跨 OS 捲軸跑版)——這類 bug 只有視覺層抓得到。產品給 stakeholder / user 看時 = stakeholder-visible artifact,必過 Tier 1 gate。
呼叫時的回答格式
audit 完畢報告應含:
- Scope:audit 了什麼(path / file 數量)
- Summary:per dimension 的 pass/fail 數
- Findings table:具體 file:line + severity + fix
- Recommendations:P0 優先 / 建議修順序
- Next step:等 user Checkpoint 1 決策
Non-goals
- 不 audit DS 本身(走 /design-system-audit)
- 不改 user 未同意的 P1/P2(僅 P0 可自動修,需 user 決策 P1+)
- 不 audit 業務邏輯正確性(本 skill 管 UI / DS consumption / design principles,不管 data flow 對不對)
- 不 replace code review(本 skill 是 pre-review self-check,不是 final QA)
Common failure modes
- Scope 太廣:掃整個 repo 導致 findings 爆量,triage 崩潰 → 限制 scope 到 feature / folder
- Dim 間互相矛盾:Dim 2 建議用 Empty 但 Dim 3 說 Button 該在某處 — surface 而非自己選
- P0/P1 分類偏誤:把明確 bug 當 P1 / 把 style preference 當 P0 — 嚴格按 audit-checks.md 分類
- AI 自行修 P2:違反 checkpoint 精神,每個 P2 都是設計決策
References