# VD-08: 개발용 Storybook과 로컬 시각 회귀 증적 - 상태: Accepted - 결정일: 2026-07-26 - 적용 브랜치: `feature-frontend-test-registry-evidence-hardening` - 재검토: 제품이 cloud visual review, 다중 OS baseline 또는 별도 디자인 시스템 배포를 요구할 때 ## 배경 `/examples/ui`와 `/examples/states`는 실제 application composition 안에서 공통 UI와 상태 표면을 보여 주지만, primitive를 격리해 interaction과 접근성을 검증하는 workshop은 아니었다. 실패 시 screenshot도 디버깅 증거일 뿐 의도된 UI 기준선과 현재 렌더의 차이를 차단하지 못했다. 외부 visual review 서비스, 별도 Storybook 배포와 브랜드별 baseline은 아직 선정되지 않았다. 이 결정을 기다리며 UI 회귀 검증을 비워 두거나 production application bundle에 workshop runtime을 포함하는 것 모두 적절하지 않다. ## 결정 1. Storybook은 development dependency와 별도 static artifact로만 사용한다. production entry와 application `dist`에는 Storybook runtime, story 또는 테스트 selector를 포함하지 않는다. 2. story는 public design-system entry를 소비하고 실제 locale, theme, session, router와 query provider 계약으로 렌더한다. production component를 복제한 story 전용 구현을 만들지 않는다. 3. interaction과 story-level axe는 Playwright가 정적 Storybook을 대상으로 실행한다. unexpected console, page error와 request failure는 테스트 실패다. 4. 시각 회귀는 production `build` 후 `preview`를 대상으로 pinned Chromium, locale, color scheme과 viewport에서 `toHaveScreenshot()`으로 실행한다. 5. 최초 기준선은 wide shell, compact pseudo-locale drawer, dark design-system gallery, loading/empty/error/access 상태 표면을 포함한다. 6. animation과 caret만 결정적으로 비활성화한다. `html`, `body`, `main` 또는 application 전체를 mask해 false PASS를 만드는 설정은 gate가 거절한다. 7. snapshot 갱신은 `test:visual:update`라는 명시적 명령으로 분리하고 PNG diff를 review한다. 일반 `test:visual`은 승인 기준선을 변경하지 않는다. 8. local visual threshold는 작은 rasterization 차이만 허용하며 실제 layout, copy, theme 또는 상태 변화가 숨겨지도록 확대하지 않는다. 9. `/examples/*`는 production composition smoke로 유지하고 Storybook story의 대체물로 취급하지 않는다. 반대로 Storybook만 통과해 application shell integration을 완료 처리하지 않는다. 10. cloud service가 선정되지 않아도 repository-local workshop, interaction, a11y와 visual baseline gate는 완전하게 실행 가능해야 한다. ## 실행과 증적 - workshop config: `.storybook/main.ts`, `.storybook/preview.tsx` - story: `src/presentation/design-system/design-system.stories.tsx` - interaction/a11y: `tests/storybook/workshop.spec.ts` - visual: `tests/visual/platform.visual.spec.ts` - baseline: `tests/visual/__snapshots__/` - production E2E: `playwright.config.ts` - local dev E2E: `playwright.dev.config.ts` - evidence policy: `scripts/check-test-evidence.ts` CI는 JUnit, HTML report, failure trace/screenshot, visual baseline 존재 여부와 금지된 full-screen mask/무소유 skip fixture를 함께 검사한다. ## 한계와 재검토 조건 로컬 기준선은 실제 iOS/Android 기기, 여러 운영체제의 font rasterization, 디자인 승인 workflow와 다중 브랜드를 증명하지 않는다. 이를 요구하면 동일 public component와 story를 입력으로 사용하는 외부 review adapter를 추가하되, provider 결과가 없을 때 임의 PASS로 대체하지 않는다. ## Rollback Storybook dependency/config, workshop test와 visual config/baseline은 production runtime 변경 없이 독립적으로 제거할 수 있다. rollback 후에도 `/examples/*`, component behavior, automated accessibility와 built-dist E2E는 유지한다.