designpaca/packages/skill/references/critique.md
Yun Chan 6805fb2be7 feat(skill): absorb external design skills, restore interview gate, add review route
- Restore the step-0 interview as a mechanical gate the skill explicitly
  depends on; add harness.md (per-harness question tools, limits,
  fallbacks) and brief-interview.md (slots, question cards, rounds).
- Add 10 reference docs absorbed from external design skills
  (accessibility, interaction-feel, elevation, color, icons, product-copy,
  component-systems, critique, change-review, print-email) and extend
  existing references.
- Add a review-only route and two hard-gate clauses (truncated content
  reachability, three-flashes limit).
- design-gate: split tap targets into WCAG 2.5.8 and 44px contract layers,
  run axe-core when available, and fix false positives found on a real
  site (decorative alt="", stacked wordmark line count, url-only pages).
- lint-skill: fail if the interview gate section or its links disappear.
- Ship agents/openai.yaml and THIRD_PARTY_NOTICES.md.
2026-09-24 13:26:03 +09:00

251 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# critique — 리뷰 경로와 발견 보고 형식
**리뷰 경로**(SKILL.md 0단계 경로 표의 0 → **5′** 감사 → 보고)와 **5단계 프리플라이트**의 최종 보고에서 읽는다. 이 문서는 두 경로가 공유하는 하나의 규약이다 — "무엇을 검사하는가"는 [preflight.md](preflight.md)·[audit-gate.md](audit-gate.md)가 정하고, 이 문서는 "발견한 것을 어떤 형식·어떤 심각도·어떤 톤으로 사용자에게 보여주는가"만 정한다. 자동 게이트의 범주별 집계 양식([audit-gate.md](audit-gate.md) 리포트 양식)과는 별개로, **개별 발견 하나하나**를 사람이 읽을 보고서로 옮길 때 이 문서를 따른다.
diff·PR·커밋 범위처럼 **변경분**을 지목받았다면 스코프 계산과 Introduced/Regression 구분은 [change-review.md](change-review.md)가 맡고, 그 산출물도 이 문서의 finding 형식·심각도·톤으로 보고한다.
## 이 문서를 읽는 법
| 상황 | 읽을 곳 |
|---|---|
| 스크린샷·코드·URL 중 무엇을 받았는지에 따라 어떻게 시작할지 | §1 |
| 히어로·폼처럼 표면 종류에 따라 얼마나 깊이 볼지 | §2 |
| finding 하나를 어떻게 적을지 | §3 |
| 심각도를 어떻게 매길지, 무엇이 자동으로 심각도를 끌어올리는지 | §4 |
| 수정안을 어떤 순서로 고를지 | §5 |
| 같은 문제가 여러 곳에서 나왔을 때, 또는 문제가 하나도 없을 때 | §6 |
| 요청 범위가 너무 넓을 때 | §7 |
| 확인을 못 한 항목을 어떻게 표시할지 | §8 |
| 시각 증거와 코드 증거를 섞어 단정하지 않는 법 | §9 |
| 보고서를 강점으로 마무리하는 법 | §10 |
| 톤 | §11 |
| 리뷰 중 자동으로 고쳐도 되는 항목 | §12 |
| 그대로 쓸 한국어 보고 템플릿 | §13 |
---
## 0. 언제, 이 문서가 다루는 범위
리뷰 경로는 **재구현이 목적이 아니다.** 사용자가 "이 화면 어때?", "이 코드 리뷰해줘", "여기 스크린샷 봐줘"처럼 평가만 요청했을 때 0단계에서 범위·입력을 확인한 뒤 곧장 5′(감사)로 가고, 4단계(구현)를 거치지 않는다. 고쳐 달라는 요청으로 바뀌면 그때 국소·연장 경로로 올린다.
5단계 프리플라이트에서도 이 문서를 쓴다. [preflight.md](preflight.md) §0~§4-3의 체크가 끝난 뒤, 실패·관찰 항목을 사용자에게 보고할 때 §3의 finding 형식과 §4의 심각도를 쓴다. 두 경로의 차이는 **깊이와 입구**뿐이다. 리뷰 경로는 구현이 없으니 입력(스크린샷·코드·URL)에서 바로 시작하고(§1), 프리플라이트는 자기 구현물을 대상으로 이미 렌더된 상태에서 시작한다.
이 문서는 designpaca가 내리는 판정의 근거인 **판정 위계**(하드 게이트 / 프로젝트 계약 / 스타일 휴리스틱, [SKILL.md](../SKILL.md))를 그대로 쓴다. 새 심각도 체계를 만들지 않는다 — §4가 하는 일은 그 3층을 리뷰 보고서의 언어로 옮기는 것뿐이다 [SKILL-DESIGN-REVIEW].
---
## 1. 입력별 진입
받은 입력의 종류로 시작 방법이 갈린다. 종류를 섞어 짐작하지 않는다.
| 입력 | 진입 방법 |
|---|---|
| **스크린샷·이미지** | 바로 시각 판단으로 들어간다. 렌더가 이미 있으므로 추가 확보가 필요 없다 |
| **코드 파일**(컴포넌트·스타일시트) | 파일을 읽되 그 파일만 보지 않는다. 관련 CSS·토큰([tokens.md](tokens.md) 역할 이름)까지 함께 열어 finding의 위치를 `path/to/file:line`으로 인용할 수 있게 한다 |
| **URL만** | 텍스트 페처(WebFetch류)는 마크업·CSS는 가져와도 **렌더링은 보지 못한다.** 브라우저 도구가 있으면 390·1440 두 폭에서 직접 캡처한다(도구 목록은 [harness.md](harness.md) §6). 브라우저 도구가 없으면 데스크톱·모바일 스크린샷을 사용자에게 요청한다 |
| **diff·PR·커밋 범위** | [change-review.md](change-review.md)로 넘긴다. 스코프 해석과 Introduced/Regression 구분은 거기서 하고, finding 자체는 이 문서 §3~§4를 그대로 쓴다 |
시각 판단이 걸린 리뷰인데 스크린샷도 렌더도 브라우저 도구도 없으면 **추측하지 않는다.** 코드만 읽고 "아마 이렇게 보일 것"이라고 단정하는 것은 §9의 증거 방향성 위반이다. 질문 수단은 [SKILL.md 인터뷰 게이트](../SKILL.md)의 규칙 3(기계적 판정)을 그대로 따른다 — 구조화 질문 도구가 있으면 그것으로, 없으면 평문으로 스크린샷을 요청하고 턴을 끝낸다.
---
## 2. 표면별 깊이
모든 표면을 같은 깊이로 훑지 않는다. 표면 종류를 먼저 식별하고, 그 종류가 가장 잘 무너지는 축을 더 깊이 본다.
| 표면 | 더 깊이 볼 것 |
|---|---|
| 마케팅 히어로 | 모션([motion.md](motion.md))·타이포([typography.md](typography.md))·구도, 반사실 제네릭 검증 |
| 폼 | 상태 완결성(입력 검증·오류·disabled)·접근성([accessibility.md](accessibility.md)) |
| 대시보드·관리 화면 | 밀도·데이터 정합·표(숫자 정렬, 관계 보존) |
| 내비게이션 | 도달성(키보드·터치)·현재 위치 신호·좁은 화면 축약 |
이것은 **다른 축을 생략해도 된다는 뜻이 아니다.** 하드 게이트는 표면 종류와 무관하게 전부 돈다([SKILL.md](../SKILL.md) 규범·기능 하드 게이트 표). 깊이 배분은 스타일 휴리스틱·프로젝트 계약 층의 시간 배분 문제다.
---
## 3. finding 형식 — What·Why·Fix
발견 하나마다 세 요소를 강제한다. 셋 중 하나라도 없으면 finding이 아니라 인상이다.
- **무엇(What)**: 요소를 인용하거나 `path/to/file:line`을 인용한다. 스크린샷만 있으면 화면 영역과 컴포넌트 이름으로 특정한다.
- **왜(Why)**: 한 줄로 위계 3층 중 어디에 해당하는지 밝히고, 규범·근거가 있으면 출처 ID를 붙인다. "이상해 보여서"는 이유가 아니다.
- **고침(Fix)**: 정확한 값이나 선택자를 준다. "늘려라", "더 낫게" 같은 방향만 있는 지시는 finding이 아니다 [SKILL-DESIGN-REVIEW].
표로 묶어 보고한다. 컬럼은 심각도·위치·무엇·왜·고침이다.
```markdown
| 심각도 | 위치 | 무엇 | 왜 | 고침 |
|---|---|---|---|---|
| Blocking | `Button.tsx:42` | 아이콘 전용 버튼에 접근성 이름 없음 | 하드 게이트 — 스크린리더가 컨트롤 목적을 못 읽음 [WCAG-NRV] | `aria-label="검색"` 추가 |
| Important | `Card.module.css:18` | radius가 4px·8px·12px 세 종류 혼재 | 프로젝트 계약 — `design.md`가 `--radius-md`(8px) 단일 체계로 확정 | `--radius-md`로 통일 |
| Polish | 히어로 이미지 좌측 | 섹션 간 여백이 위 40px(`--space-5`)·아래 64px(`--space-6`)로 비대칭 | 스타일 휴리스틱 — 리듬 관찰 후보, 브리프 근거가 없으면 대칭이 시작값 [SKILL-BETTER-LAYOUT] | 상하 모두 `--space-6`(64px)으로 통일 검토 |
```
**UI 코드 자체의 수정 전/후를 비교하는 리뷰**(모션 커브 교체, 트랜지션 재조준 등)에는 위 표 대신 `Before | After | Why` 3열 표를 쓴다. 목록형으로 "Before:"와 "After:"를 줄바꿈해 나열하지 않는다 — 나란히 비교해야 차이가 보인다 [SKILL-EMIL-DESIGN-ENG].
```markdown
| Before | After | Why |
|---|---|---|
| `transition: transform 300ms ease-in` | `transition: transform 300ms var(--ease-out)` | 진입 모션에 `ease-in`을 쓰면 시작이 굼떠 보인다. `--ease-in`은 퇴장 전용이다 |
```
두 표는 병행 가능하다 — 구조 finding은 첫 표, 코드 수정 대안은 두 번째 표로 보조한다.
---
## 4. 심각도
판정 위계를 그대로 3단계 언어로 옮긴다. 새 규칙을 만드는 게 아니라 이미 있는 위계에 이름을 붙이는 것이다.
| 심각도 | 판정 위계 | 기준 |
|---|---|---|
| **Blocking** | 하드 게이트 위반 | WCAG·키보드·포커스·대비·감소 모션·진실성처럼 규범·기능에 근거한 항목의 실패. 출시를 막는다 |
| **Important** | 프로젝트 계약 위반 또는 과업 방해 | 브리프·`design.md`·토큰·성능 예산과 어긋나거나, 계약 위반이 아니어도 사용자가 과업을 완수하지 못하게 막음 |
| **Polish** | 스타일 휴리스틱 관찰(관찰 후보) | 색·radius·정렬·리듬 같은 취향 후보의 다듬기. 통과·보류·채택은 맥락과 렌더로 판단한다 |
**전부 나열하지 않는다.** 중요한 순으로 소수만 앞세운다. 몇 개까지인지 숫자로 정하지 않는다 — §7의 스코프 규율을 따른다.
### 에스컬레이션 트리거 — 확인되면 표면이 사소해도 낮추지 않는다
아래 항목은 확인되는 즉시 표에 적힌 위계로 매긴다(대부분 Blocking). "화면 전체는 괜찮으니 평균 내면 Important"처럼 다른 항목과 평균을 내어 낮추지 않는다 — 트리거는 심각도만 정할 뿐 새 하드 게이트를 만들지는 않는다. 실제 하드 게이트 정의는 [SKILL.md](../SKILL.md)·[accessibility.md](accessibility.md)가 갖고 있고, 이 표는 그 정의를 리뷰 시점에 놓치지 않기 위한 점검표다 [SKILL-BETTER-INTERFACE].
| 트리거 | 위계 근거 | 이미 있는 designpaca 규칙 |
|---|---|---|
| 인터랙티브 컨트롤에 접근성 이름이 없음 | 하드 게이트 — 스크린리더가 목적을 읽지 못함 [WCAG-NRV] | [accessibility.md](accessibility.md)의 접근 가능한 이름 규칙 |
| 키보드로 도달은 되지만 포커스가 다른 요소에 완전히 가려짐 | 하드 게이트 — 포커스가 있어도 안 보이면 무의미 [WCAG-FOCUS-OBSCURED] | [preflight.md](preflight.md) §1 포커스 표시 항목의 보강 사례 |
| 포커스 인디케이터가 인접 색과 구별되지 않음(대비 3:1 미만 등) | 하드 게이트 — 상태를 식별하는 시각 정보라 비텍스트 대비 기준을 받는다 [WCAG-NONTEXT]. 인디케이터의 면적(2px 둘레 기준)까지 요구하는 것은 AAA 이므로 프로젝트가 표방할 때만 계약으로 본다 [WCAG-FOCUS-APPEAR] | [preflight.md](preflight.md) §1 포커스 표시 |
| 포인터로만 조작되는 컨트롤(키보드 경로 없음) | 하드 게이트 | [SKILL.md](../SKILL.md) 규범·기능 하드 게이트 1번 |
| `prefers-reduced-motion`을 무시하고 위치 이동·시차가 그대로 재생 | 하드 게이트 | [motion.md](motion.md), [SKILL.md](../SKILL.md) 하드 게이트 3번 |
| 320px 폭 또는 200% 확대에서 콘텐츠·컨트롤이 잘리거나 도달 불가 | 하드 게이트 | [preflight.md](preflight.md) §3 반응형 |
| 텍스트·UI 대비가 적용 WCAG 기준 미달 | 하드 게이트 | [preflight.md](preflight.md) §1 대비 |
| 색만으로 상태·의미를 전달하고 다른 단서(아이콘·라벨·패턴)가 없음 | 하드 게이트 — 색맹·흑백 인쇄·저채도 화면에서 정보 유실 | [color.md](color.md) |
| 파괴적 행동에 확인·실행취소·구분된 처리가 없음 | 하드 게이트 | [preflight.md](preflight.md) §4-1 |
| 잘린(ellipsis 처리된) 콘텐츠에 전체 값으로 가는 경로가 없음 | 하드 게이트 — 정보 접근 수단 자체가 없음 | [SKILL.md](../SKILL.md) 규범·기능 하드 게이트 4번, [typography.md](typography.md) |
| 스크롤 경계나 접힘 뒤에 시각적 단서 없이만 도달하는 컨트롤 | 관찰 후보(다듬기) — 다만 그 컨트롤이 필수 과업의 유일한 경로면 과업 방해로 중요(Important) | [layout.md](layout.md) 점진적 공개 절과 같은 층 |
| 입력 오류에서 고칠 방법이 알려져 있는데 제시하지 않음 | 하드 게이트(WCAG 3.3.3) | [WCAG-22] |
| 그 밖의 오류 문구에 다음 행동이 없음 | 프로젝트 계약 | [product-copy.md](product-copy.md) §6 |
| 시맨틱 색 토큰을 의미와 반대로 사용(예: 위험색을 기본 CTA에) | 프로젝트 계약 위반 — 토큰의 의미 계약을 깼다. 동시에 그 오용이 사용자에게 잘못된 위험 신호로 읽히면 하드 게이트로 올린다 | [color.md](color.md), [tokens.md](tokens.md) |
| 상태 변화가 모션으로만 전달되고, 모션이 꺼지거나 생략돼도 남는 색·아이콘·라벨이 없음 | 하드 게이트 — 감소 모션 환경에서 상태 자체가 사라짐 | [motion.md](motion.md) |
이 표에 없는 항목이라도 같은 논리(정보·조작 수단 자체의 유무)가 성립하면 같은 방식으로 Blocking을 매기고 근거를 적는다. 표는 닫힌 목록이 아니다.
---
## 5. 저비용 수정 사다리
Fix를 쓸 때 다섯 단계를 순서대로 검토한다. 더 비싼 단계로 고쳤는데 더 싼 단계가 가능했다면, **그 수정 자체가 별개의 finding이다** [SKILL-BETTER-INTERFACE].
1. **삭제** — 불필요한 구분선, 과도한 인터랙션 위 애니메이션, 아무도 쓰지 않는 토큰·ARIA 속성은 지우는 것이 가장 싼 수정이다
2. **플랫폼 활용** — 커스텀 컴포넌트 대신 네이티브 엘리먼트·포커스 링·컨트롤로 대체할 수 있는가
3. **재사용** — 새 값을 만들기 전에 기존 토큰·간격·모션 커브가 이미 있는가
4. **값 교정** — 소유 문서(색은 [color.md](color.md), 그림자는 [elevation.md](elevation.md) 등)가 주는 정확한 값으로 바꾼다
5. **추가** — 위 넷으로 안 될 때만 새 토큰·wrapper·미디어쿼리·ARIA 속성을 만든다
---
## 6. 병합과 패딩 금지
같은 근본 원인에서 나온 반복 위반은 **하나의 finding**으로 묶고, 확인된 모든 위치를 그 행에 나열한다. 발생마다 행을 나누지 않는다 [SKILL-BETTER-INTERFACE].
항목 수를 채우려고 같은 문제를 쪼개 보고하지 않는다. 리뷰가 짧아도 되고, **"발견 없음"도 유효한 결과다.** 억지로 Polish를 만들어내는 것은 신뢰를 깎는다.
---
## 7. 스코프 규율
요청 범위가 신뢰성 있게 점검하기에 너무 넓으면, 요청이 중심으로 삼는 **한 흐름**(사용자가 실제로 거치는 진입 경로 하나)으로 좁히고 그 경계를 보고 서두에 명시한다. 어디까지 봤고 무엇을 뺐는지 말하지 않고 넘어가지 않는다.
**점검하지 않은 표면을 점검한 것처럼 암시하지 않는다.** "전체적으로 괜찮다"는 문장은 실제로 전체를 본 뒤에만 쓴다. 숫자 상한(finding 몇 개까지, 화면 몇 개까지)은 두지 않는다 — 상한은 근거 없는 수치이고, 스코프를 좁히는 판단이 상한보다 먼저다.
---
## 8. 미검증·미점검
실행할 수 없는 체크는 **finding이 아니다.** 두 상태를 구분해 따로 나열한다.
- **미검증**: 시도했지만 도구·권한·환경 제약으로 확인하지 못했다(예: 실기기가 없어 제스처 QA 불가). 통과로 추정하지 않는다.
- **미점검**: §7에서 스코프를 좁히며 의도적으로 뺀 표면이다. "확인 안 함"이라고 명시한다.
둘 다 finding 개수·심각도 집계에 넣지 않는다. 통과한 체크와 나란히, 별도 목록으로 둔다.
---
## 9. 증거 방향성
런타임 동작이 결과를 좌우할 때는 방향을 섞지 않는다.
- **시각(스크린샷)만으로 코드-레벨 finding을 단정하지 않는다.** "이 여백은 padding이 아니라 margin일 것"처럼 소스를 안 보고 구현 방식을 추측하지 않는다.
- **소스코드만으로 시각적 finding을 단정하지 않는다.** CSS가 의도한 값이어도 폰트 로딩·동적 콘텐츠·다른 규칙과의 캐스케이드로 실제 렌더가 다를 수 있다.
한쪽 증거만 있으면 그 증거가 답할 수 있는 범위까지만 쓰고, 나머지는 §8의 미검증으로 남긴다.
---
## 10. 마무리 — 강점과 최고 레버리지 변경
지적으로만 끝내지 않는다. 보고서 끝에 **Strengths 2~4개**를 적는다 — 잘 되고 있는 부분 위에 비판이 쌓이게 하는 문화적 장치다 [SKILL-DESIGN-REVIEW]. 지어낸 칭찬이 아니라 실제로 확인한 것만 적는다.
유용하면 **가장 큰 효과를 낼 변경 하나**를 선택으로 덧붙인다. 여러 Important 중 하나를 고치면 나머지가 함께 해결되거나, 사용자 인지에 가장 크게 걸리는 항목이 후보다.
---
## 11. 톤
모호한 지적을 하지 않는다. "더 나아 보이게", "좀 깔끔하게" 같은 방향만 있는 문장은 쓰지 않는다. 항상 §3의 정확한 Fix와 짝짓는다.
동료의 작업을 리뷰하듯 직접적이고 정중하게 쓴다. 문제는 정확하고 모호하지 않게 말하되, 사람이 아니라 결과물을 평가한다.
---
## 12. 리뷰 중 자동 적용 범위
사용자가 리뷰와 함께 수정 적용을 요청했을 때(`--apply`류 의도), 안전하게 자동 적용 가능한 범주와 확인이 필요한 범주를 구분한다.
| 자동 적용 가능 | 확인 필요 |
|---|---|
| 대비 토큰 교체(이미 있는 역할 토큰으로) | 주관적 판단이 들어가는 변경(색감, 레이아웃 재배치) |
| 간격 토큰 교체 | 구조 변경(컴포넌트 분리·합치기, 정보 구조 재배열) |
| 포커스 스타일 보강 | 카피 톤·메시지 변경 |
| `prefers-reduced-motion` 대응 추가 | 새 컴포넌트·새 패턴 도입 |
| 시맨틱 태그로 교체(`div` → `button` 등) | — |
| `alt` 텍스트 추가 | — |
자동 적용 가능 범주도 **수정 후 대비·값을 재검증**한다. 고쳤다고 선언만 하고 재측정을 생략하지 않는다 [SKILL-DESIGN-REVIEW].
---
## 13. 한국어 보고 템플릿
```markdown
## 리뷰 범위
- 대상: <URL/파일/스크린샷>
- 본 흐름: <한 흐름으로 좁혔다면 그 경로>
- 뺀 것: <미점검으로 둔 표면과 이유>
- 증거: <스크린샷/실제 렌더/소스코드, 뷰포트·엔진명>
## 발견
| 심각도 | 위치 | 무엇 | 왜 | 고침 |
|---|---|---|---|---|
| ... | ... | ... | ... | ... |
발견 없음이면: "이 흐름에서 Blocking·Important 발견 없음. Polish 관찰 후보는 <있으면 나열, 없으면 없음>."
## 미검증 · 미점검
- 미검증: <시도했으나 확인 못 한 항목과 이유>
- 미점검: <스코프에서 뺀 표면>
## 잘된 점
- <강점 1>
- <강점 2>
## 가장 큰 효과를 낼 변경 (선택)
<하나, 이유 한 줄>
```
이 템플릿은 뼈대다. 리뷰 규모가 작으면 섹션을 생략할 수 있지만(예: 발견이 없으면 "미검증" 섹션도 빈 채로 명시), 거짓으로 채우지는 않는다.