4장 검증 원칙
「됐다」는 실행해서 확인한 뒤에만 말합니다. 변경은 21개 검증 원칙으로 판단하고, 검사는 변경의 영향만큼 한 번씩만 실행합니다.
왜 필요한가
검증이 없으면 「아마 될 것」이 사실처럼 퍼집니다. 그렇다고 검사를 많이 돌리는 것이 품질의 근거는 아닙니다. 2026-07-28 KST에 48px 탭 띠 하나를 고친 컴포넌트 수정이 기능 PR 병합에서 제품 PR 병합까지 약 20분 걸렸습니다. 모든 DS stylesheet를 전역 변경으로 분류했고, shard 네 개가 각자 브라우저를 설치해 전체 E2E를 돌렸고, 버전 번호만 바뀐 PR도 화면 변경으로 보았기 때문입니다. 이 사례의 교훈은 검증을 약하게 하자는 것이 아니라 위험과 무관한 반복을 없애자는 것입니다.
원칙
21개 검증 원칙
코드나 아키텍처 변경을 제안할 때는 검증 원칙(P-*) 21개로 스스로 점검합니다. 원칙은 네 층(Tier)으로 나뉩니다.
| Tier | 묻는 것 | 원칙 |
|---|---|---|
| 1 사고 | 원인을 고쳤는가, 논리에 반례가 없는가 | P-ROOT-CAUSE · P-LOGIC · P-CONSISTENCY · P-GENERALITY |
| 2 구조 | 계층과 의존이 바른가 | P-CLEAN-ARCH · P-DAG · P-OCP · P-PRIMITIVE |
| 3 구현 | 코드가 경계를 지키는가 | P-CLEAN-CODE · P-DRY · P-NO-SHOTGUN-STATIC · P-NO-ADHOC · P-CONVENTION |
| 4 검증·운영 | 실행해서 확인했는가 | P-TESTABLE · P-VISUAL · P-A11Y · P-PERF · P-COMPAT · P-NO-SHOTGUN-DYNAMIC · P-MAINT · P-SECURITY |
원칙마다 분류가 있습니다. B(Blocking)는 어기면 진행을 멈추는 원칙으로 10개, M(Measurable)은 수치로 재는 원칙으로 4개, Q(Qualitative)는 정성 판단으로 7개입니다. 판정 기준은 가능한 한 수치나 명령으로 적습니다.
- P-DAG: 순환 의존 검사(
madge --circular)에서 새로 생기거나 늘어난 순환이 0건입니다. - P-OCP: 새 기능은 기존 코드를 지우지 않고 더하기만 합니다(+N/−0).
- P-DRY: 의미 단위 중복은 2회까지입니다.
- P-PERF: LCP 2.5초 미만, INP 200ms 미만, CLS 0.1 미만입니다.
- P-CONVENTION: 맥락이 같은 외부 디자인 시스템 다수와 맞추고(웹은 14개 중 7개 이상), 미달하면 근거를 기록합니다.
- P-SECURITY: OWASP Top 10:2025를 점검하고,
npm audit의 high 등급이 새로 생기거나 늘지 않아야 합니다.
판정과 처리
판정은 ✅ 통과, ❌ 위반, ⚠️ 부분(조건부이거나 변경 전부터 있던 위반), N-A(해당 없음) 넷입니다. ❌와 ⚠️에는 원칙이 깨지는 최소 사례인 반례(counterexample)를 반드시 붙입니다.
- 변경 때문에 새로 생기거나 나빠진 B 위반은 한 건이라도 재설계합니다.
- 변경 전부터 있던 위반(baseline)은 ⚠️로 보고하고, 변경이 악화시키지 않으면 진행합니다.
- M 위반은 수치를 보완한 뒤 다시 평가하고, Q 위반은 사유를 밝히면 진행할 수 있습니다.
- 원칙이 부딪히면 B > M > Q 순서이고, 같은 분류면 Tier 번호가 낮은 쪽을 따릅니다.
출력은 ❌·⚠️만 표(ID·판정·반례·근거·개선안)로 쓰고, ✅와 N-A는 ID를 한 줄로 요약합니다. N-A에는 사유를 한 문장 붙이며, 사유가 없으면 ❌로 봅니다. 예를 들어 Combobox 목록 폭을 입력란에 맞춘 결정은 벤치마크가 갈려(shadcn/ui는 맞추지 않고 Nuxt UI는 맞춤) P-CONVENTION을 ⚠️로 남기고, Reka UI를 쓰므로 Nuxt UI를 따른다는 근거를 적었습니다.
원칙 사이의 관계도 있습니다. 순환 의존이 없는 것(P-DAG)은 계층 분리(P-CLEAN-ARCH)의 필요조건입니다. 코드가 달라도 뜻이 같으면 P-DRY는 통과해도, 한 의도를 바꾸려고 여러 곳을 고쳐야 하는 구조(P-NO-SHOTGUN-STATIC)로는 위반일 수 있습니다.
검사는 한 번씩, 영향만큼
gate는 정해진 시점에 실행하는 검사 묶음입니다.
| Gate | 시점 | 기본 범위 |
|---|---|---|
Iteration — npm run verify:changed | 수정 중 | 변경 관련 테스트와 정적 계약 |
Push — npm run verify:push | commit·push 직전 | Iteration과 영향 저장소 build 1회 |
| CI·Release | PR·main·버전 commit | 변경 경로를 분류한 뒤 중앙 gate |
| Live smoke | 배포 후 | 변경 수준에 맞는 실제 화면 |
같은 파일 내용에서 이미 통과한 명령과 상위 gate가 포함한 하위 명령은 다시 실행하지 않습니다. 실패하면 실패한 단계와 그 영향을 받는 단계만 다시 실행합니다. 전체 검증 npm run verify는 공개 패키지 버전 commit이나 게시 후보, 공용 API·schema·event·router·build 도구·lockfile 변경, 변경 범위를 분류할 수 없을 때, 부분 검사가 공통 기반의 결함을 드러냈을 때, 사람이 명시적으로 요청했을 때만 실행합니다.
작업 모드도 나눕니다. 구조와 화면을 확정하는 Review와 공개 패키지를 실제로 게시하는 Release를 분리해, 작은 수정마다 관성적으로 게시하지 않습니다. 게시까지 승인된 작업은 Release의 종료 조건까지 끝냅니다.
반응형 화면 검증
화면 검증 범위는 파일 수가 아니라 화면 영향 수준 L0–L5로 정하고, 영향받은 실제 화면에서 합니다.
| 수준 | 대상 | viewport |
|---|---|---|
| L0 | 문서·테스트·화면에 보이지 않는 로직 | 브라우저 검증 생략 |
| L1 | 문구·아이콘 | 대표 3종 412×915 · 768×1024 · 1440×900 |
| L2·L3 | 모바일 전용, 태블릿 전용 | 해당 구간의 viewport |
| L4 | 컴포넌트·레이아웃 | 대표 3종과 1023×900 · 1024×768, 영향에 따라 추가 |
| L5 | 전역 셸·디자인 시스템 | 전체 9종 |
1023×900은 데스크톱 대표가 아니라 전환 경계입니다. 좌측 메뉴는 1024px부터 보이므로, 그 바로 아래 폭과 1024×768을 함께 보면 전환의 양쪽을 확인할 수 있습니다. 스크린샷만으로 끝내지 않고 수치를 함께 기록합니다. 페이지 가로 넘침(문서의 scrollWidth <= clientWidth), 텍스트 넘침 수, 예상하지 않은 내부 scroll, fixed·sticky 요소의 겹침을 한 번의 브라우저 측정으로 모읍니다. 결과에는 「PASS」 한 단어 대신 실행한 viewport와 수치를 쓰고, 실행하지 않은 항목은 N-A와 사유를 적습니다.
실제 예 — 실패하면 게시하지 않습니다
3.0.0의 release 검증에서 브라우저 shard 하나의 typography 계약 한 단계가 실패했습니다. 원인은 패키지가 아니라 검사 스크립트였습니다. 테스트 마크업이 3.0에서 제거한 2.x 별칭 클래스를 써서 버튼이 스타일을 받지 못했고, 글자 크기가 기대값 14px이 아닌 브라우저 기본값 13.3333px로 측정되었습니다. 나머지 검사는 모두 통과했지만, 실패를 통과가 아니라 차단으로 처리하는(fail-closed) 원칙에 따라 게시는 0건이었습니다. 3.0.0은 게시하지 않고 내용을 3.0.1로 게시했으며, 미게시 버전은 결정 기록과 release 도구의 목록에 올렸습니다.
경계와 예외
- P-* 평가는 코드·아키텍처 변경을 제안할 때 하는 자기 점검입니다. 일반 질의·설계 토론·문서 작성은 대상이 아닙니다. 자동 gate가 commit·PR을 막는 권한은 실제 고장에만 있습니다(1장).
- 저장소 자동화가 이 정책보다 엄격하면 우회하지 않고, 통과한 뒤 지나친 부분을 정책 어긋남(policy drift)으로 보고합니다.
- 검사가 재지 않는 결함은 통과 결과 뒤에 숨습니다. 2장의 Hero 사례가 그랬습니다. 그래서 새 계약 테스트는 수정 전 CSS에서 4건 모두 실패하고 수정 후 모두 통과하는 것까지 확인했습니다.
정리
- 「됐다」는 실행해서 확인한 뒤에만 말하고, 실행하지 않은 검사는 N-A와 사유로 적습니다.
- 변경 제안은 4 Tier 21개 원칙으로 점검하고, 새로 생긴 B 위반은 재설계합니다.
- 검사는 Iteration → Push → CI·Release → Live smoke 순서로 각각 한 번, 영향만큼 실행합니다.
- 화면은 L0–L5 수준에 맞는 viewport에서 실제 route로 보고, 넘침·scroll·겹침을 수치로 남깁니다. 실패하면 게시하지 않습니다.
정본
leysys-designAGENTS.md「검증 원칙」 — 21개 원칙 표, 판정 기호, 처리 규칙, 출력 형식leysys-designdocs/specs/VERIFICATION-PRINCIPLES.md— 외부 디자인 시스템 16종과 헤드리스 프리미티브 부록leysys-designdocs/process/CHANGE-VALIDATION-AND-DEPLOYMENT.md— 실행 gate와 전체 검증 승격 조건leysys-designdocs/process/AGENT-WORK-EFFICIENCY-STANDARD.md— 작업 모드와 같은 검사 한 번 실행 규칙leysys-designdocs/process/RESPONSIVE-VIEWPORT-VALIDATION-STANDARD.md— viewport·L0–L5·수치 기록 형식leysys-designdocs/decisions/RELEASE-300-UNPUBLISHED-2026-09-30.md— 3.0.0 미게시 결정