- 핵심 규칙 6: 완료의 정의는 게이트 통과. 사용자를 QA로 쓰지 않는다 - 5단계 기계 검사 4번째: design-gate 실행 의무화 - references/audit-gate.md: 사고-검사 매핑, SEO/meta 체크리스트, OS/브라우저 특성, 하니스 규칙 - tools/design-gate.mjs: 범용 게이트(메타/SEO·대비·수축·리듬·트랙·스케일×폭 + 옵션 L0/L3/L4, checks 깊은 병합) - 리듬·트랙 불변식: 숫자 라벨 등폭·빈 셀 트랙 균일·등간격 — 시간표 자동배치 결함 재현 픽스처 검출, 앱 15뷰 통과(오탐 0) feat(site): 관리 앱 2종 프로덕션 콘솔(v6→v18) - 가온 학적부 9뷰·두레 수강신청 6뷰: shadcn 문법, Pretendard/Noto Serif/IBM Plex 폰트 전략, 볼드 금지(400/500/600), WCAG AA 대비 전면 교정, 한글 keep-all 조판 - LMS 필수 요소(알림 센터·공지·진도·평가 유형·출결 사유·학점 경고), 12명 기준 데이터 정합, SEO 구조(h1 유일·OG/twitter·og.png) - 시간표 자동배치 결함 수리(명시적 격자 좌표) - QA 게이트: L0 stylelint/html-validate · L1 단위 30 · L2 감사 61+불변식 · L3 시각회귀 30화면 · L4 WebKit · L5 키보드 탐색 — npm run verify 실패 시 배포 금지 체인
6.2 KiB
audit-gate — 자율 검증 폐쇄 루프
5단계(감사)를 완료 선언의 게이트로 만드는 문서다. 핵심 원칙은 하나다:
완료의 정의는 게이트 통과다. 사용자를 QA 로 쓰지 않는다.
"고쳤다"는 말의 근거는 검증 리포트의 수치다. 게이트가 실패 항목을 내면 4단계로 돌아가 고치고 다시 전체를 돌린다 — 고친 것만 재검하지 않는다. 이 루프(구현 → 게이트 → 실패 → 수정 → 재게이트)가 designpaca의 기본 동작이며, 게이트 없이 6단계로 넘어가는 것은 경로 무관 금지다.
왜 필요한가 — 실제 사고 목록
이 게이트의 각 검사는 사용자 보고로야 발견됐던 결함에서 왔다. 어느 검사가 어느 사고를 잡는지가 설계 근거다.
| 사고 (실제) | 검사 |
|---|---|
| CSS 닫는 중괄호 누락 — 이후 규칙 절반이 죽은 채 렌더 | stylelint(구문) + 중괄호 균형 |
| 브랜드가 모바일에서 1글자 폭으로 수축, 세로로 쌓임 | 수축 탐지(짧은 라벨 n줄 이상) + 브랜드 1줄 |
| 기기 글꼴 확대(안드로이드 큰 글꼴 1.3×)에서 제목 부서짐 | 스케일×폭 h1 행렬 |
| 본문 보조색이 배경 대비 4.4:1 (AA 미달) | 전 요소 대비 스캔(블렌드 계산) |
| 조사만 하고 안 고친 영역(관심 과목 등) | 전 뷰 순회 — 검사는 '내가 고친 것'이 아니라 전체 표면 |
| 대시보드 26명 ↔ 명단 12명 숫자 모순 | 콘텐츠 정합(요약 = 재계산 비교) |
| aria-label 을 div/ul 에 오용(보조기술 무시) | html-validate + axe |
dl 안 <p>, role="grid" 자식 구문 위반 |
html-validate + axe |
| 계산 로직 오류(행 배열을 값으로 셈 → 0/3) | 단위 테스트(브라우저 밖 경계값) |
| 같은 데이터 속성이 여러 뷰에 존재해 선택자 오작동 | 하니스 규칙: 선택자는 컨테이너 스코프 |
| 혼합 span 그리드의 자동 배치가 시간 라벨을 흩어놓음(같은 열 폭 40/78 혼재, Δ 불규칙) | 리듬·트랙 불변식 — 같은 부모·같은 클래스 형제 중 (a) 숫자/시간 라벨(등폭 의도)과 (b) 빈 격자 셀(트랙 균일 의도)은 폭이 균일해야 하고, 한 축 정렬·크기 균일 형제는 등간격이어야 한다. 한국어 라벨은 글자수가 같아도 내용 폭차가 자연스러우므로 폭 검사 대상에서 뺀다(오탐 방지). 근본 수칙: 혼합 span 그리드는 자동 배치를 믿지 않고 좌표를 명시하라 |
6계층
tools/design-gate.mjs 가 한 파일로 돌리는 것과 프로젝트가 보강하는 것이 있다.
| 계층 | 도구 | 비고 |
|---|---|---|
| L0 정적 | stylelint + html-validate | 문법·구문 위반을 브라우저 켜기 전에 |
| L1 단위 | 순수 계산 로직 추출(calc.js) + 경계값 테스트 | 프로젝트별 작성 — 0명/만석/초과/빈배열 |
| L2 불변식 | design-gate.mjs — 오버플로·h1·수축·대비·SEO/meta |
전 뷰 × 전 폭 |
| L3 시각 회귀 | 기준 화면 pixelmatch diff (≥0.1% 실패) | 갱신은 검증된 배포 후 --update-baseline |
| L4 WebKit | Playwright webkit | 사파리 엔진 렌더 차이 |
| L5 탐색 | 키보드 완전 통과 + 사용자 여정 차터 | 프로젝트별 작성 — 마우스 금지 |
설치 (프로젝트에 게이트 심기)
node <스킬>/tools/design-gate.mjs --init # gate.config.json 초안
# pages[].views 를 실제 뷰 목록으로, viewAttribute 를 data-view 등으로
npm i -D puppeteer-core # CHROME_PATH 또는 자동 탐색
package.json: "verify": "node <스킬>/tools/design-gate.mjs"
배포는 항상: npm run verify && build && deploy # verify 실패(exit 1)면 배포 불가
L1·L5 는 프로젝트 안에 tools/unit/*.test.mjs, tools/exploratory.mjs 로 보강하고 verify 체인에 묶는다. 근거와 완성 예는 designpaca 저장소 apps/site/tools/ 가 정본 샘플이다.
SEO / meta 감사 (design-gate 내장)
조사 기준(2026): title 1065자·유일, description 60165자, viewport, html lang, charset, canonical(프로덕션), og:title/description/image/url, twitter:card, favicon, h1 유일, img alt 전부, JSON-LD 파싱. 데모·로컬 페이지는 canonical/robots 없음을 허용한다 — 검사는 맥락을 존중하되 나열 근거는 리포트에 남긴다.
OS · 브라우저 특성 — 검사에 반영할 것
- Windows: 스크롤바가 오버레이가 아니다 —
overflow-x:auto짝에는overflow-y:hidden+scrollbar-width검토. 스크롤바 자체가 레이아웃을 민다. - iOS/Safari(WebKit):
100vh주소창 문제(100dvh), 텍스트 인플레이션(-webkit-text-size-adjust:100%), WebKit 만의 flex/행높이 차이 → L4 로 재검. - 안드로이드: 시스템 글꼴 확대(1.15~1.3× 흔함) — rem 전면 확대로 제목 칸 수축 → 스케일×폭 행렬으로 재현·검증.
- 폰트 스왑:
font-display: swap의 CLS — 폴백 메트릭 보정(typography.md §4) 없이 검사 통과를 선언하지 않는다.
하니스 규칙 (테스트를 만드는 테스트)
- 선택자는 스코프필수 — 같은 data-* 가 다른 뷰에 있으면 숨은 요소를 잡는다(
#as-table [data-assign]처럼). - page.evaluate 클로저 금지 — Node 스코프 함수를 페이지 안에서 부르지 않는다. 측정 코드는 문자열로 주입.
- 줄 수 측정의 오탐 두 종류 — 폰트 메트릭 top 차이(±5px 허용오차), 인라인 아이콘과 텍스트의 top 차이(텍스트 노드만 분리 측정).
- CSS 수정 직후 검증은 캐시 차단(
setCacheEnabled(false)) + 실제 로드된?v=확인. - 비전(모델) 검수는 '여부'가 아니라 '지점 평가'에만 — 여부는 계측으로.
- 모달 닫힘 직후 포커스 강탈 — 뷰 전환+타깃 포커스는 한 evaluate 로, settle 후 유실 재포커스.
- 게이트를 통과해도 리포트에 수치를 남긴다 — "ALL PASS"가 아니라 "무엇을 몇으로 확인했나".
리포트 양식
게이트: 전 계층 통과 — 배포 가능 · 총 Ns
| 계층 | 결과 | 항목 | 소요 |
실패 상세는 원문 테일 포함. 리포트 파일(gate-report.md / verify-report.md)은 커밋 대상이다.