Files
HMDesign/docs/guidelines/guard-accuracy-2026-10-10.md
T

15 KiB
Raw Blame History

HMDesign Guard 정확도 수정 결과 — 2026-10-10

RESULT: PARTIAL

TARGET: D:\디자인시스템\hmdesign

범위: Guard 검증 로직·테스트·설명 문서. Runtime: React/Vite. Production과 기존 Storybook Reference를 독립 검사한다. Component/Pattern/Theme/Token/D-01/D-02/대표 Story와 이전 퍼블리셔 통합 보고서는 수정하지 않았다. Git 명령을 실행하지 않았다.

Guard 문제 분석

항목 원인·판정·수정
Dashboard Sidebar 이전 Guard는 import graph의 모든 JSX를 실제 render처럼 취급했다. export entry의 DashboardScreen mode="compact" → compact=true → sidebar=undefined와, 사용되지 않는 Reference JSX initializer를 구분하지 못해 NAV-001 FAIL 및 NAV-005를 냈다. 직접 component 호출·기본/literal props·immutable local 값·반환 JSX/slot을 분석하여 현재 entry에서 배제되는 분기만 제외했다. 실제 Chrome DOM의 Sidebar는 0개다.
Storybook Scope 기존 Guard는 Production 전용이므로 Story 변경의 SCOPE-001은 검사 범위 불일치였다. 독립 --profile STORYBOOK을 추가했다. 설정의 literal stories glob으로 63개 Story module을 발견하고, 각 Story graph에 공통 preview를 연결한다. 다른 lazy Story의 CSS를 연결 증거로 사용하지 않는다.
CSS Intent 기존 REUSE-003은 위반 확정 FAIL이 아닌 검토용 NOT VERIFIED였다. Primary 80%·Secondary·Legacy·Dashboard Gradient를 바꿀 근거가 없다. 해당 판정을 유지하고, 누락됐던 내부 tabs-* slot도 검토 대상으로 포함했다. package 내부 Theme CSS는 기존 소비자 replica 검사에서 제외한다.
Navigation Policy GNB_ONLY/DASHBOARD_ONLY의 Sidebar 금지와 혼합 Navigation 금지는 유지한다. LNB_ONLY 정상 사용도 유지한다. 실제 선택되는 Reference Sidebar branch는 FAIL, 동적 조건/spread/mutation/opaque callback은 가능한 위반을 NOT VERIFIED로 남긴다. 여러 호출 중 하나라도 확정 위반이면 FAIL이다. 공식 Sidebar를 component prop으로 전달해 렌더하는 경우도 탐지한다.
Production Graph bootstrap import graph와 공개 package API 경계는 보존한다. Story/helper/reference 소비는 계속 FAIL이다. package Component/Pattern/Theme source는 소비 graph로 강제 포함하지 않는다. 직접 선택한 package CSS는 SCOPE-001 NOT VERIFIED이며 패키지 build/typecheck 및 별도 CSS/실제 렌더 확인으로 구분한다.

실제 렌더·조건·Reference 구분

  • 실제 <DashboardSidebar> 또는 금지 sidebar slot을 반환하는 literal 경로: FAIL.
  • 조건이 미확정인 Sidebar: NOT VERIFIED. PASS로 숨기지 않는다.
  • 현재 compact literal props로 배제된 분기·반환되지 않는 Reference JSX 값: 현재 Navigation 위반에서만 제외한다. import/export/CSS 검사는 유지한다.
  • Reference라는 주석·파일명·Sidebar 문자열만으로 Production 사용을 허용하지 않는다. 같은 보존 분기를 선택하면 FAIL이다.
  • Storybook Reference의 Navigation API는 mode 미지정 시 NOT APPLICABLE이다. 명시 mode를 주면 기존 정적 금지 규칙을 검사한다. Story별 대표/verification 분류·모든 상태의 혼합 Navigation 의도를 자동 승인하지 않는다. 신규 업무 화면의 Story 등록 금지는 그대로다.

원인 분류

실제 위반: 이번 제공된 Production entry에서 확정한 신규 디자인 시스템 위반은 없다. 회귀 fixture의 실제 Sidebar·혼합 Navigation·비공개 import·위조 public slot·Production의 Story 의존은 FAIL을 유지한다.

오탐: Dashboard compact에서 mount되지 않는 legacy Sidebar branch의 NAV-001. 현재 mode로 빈 slot을 증명할 수 있는데 NAV-005를 내던 분석 한계. Story 변경의 SCOPE-001은 기존 전용 범위 불일치이며 독립 Storybook 검사로 해결했다.

검증 불가: CSS override의 승인/복제 의도, native control의 합법적 사용 의도, opaque/dynamic render flow, 독립 package source를 소비 Guard로 검사하는 범위, 전 Story/모든 browser/state의 runtime 회귀.

전체 Storybook의 src/patterns/gnb.stories.tsx:406은 공개 컴포넌트가 없는 내부 lnb-mobile-nav wrapper를 사용한다. 기존 GNB Composition 계약에도 있는 Reference이며 소비자 복제로 확정할 수 없다. Storybook에서만 이 종류를 REUSE-001 NOT VERIFIED로 분류한다. 같은 코드의 Production 사용은 FAIL이며, Storybook에서도 공개 component slot을 기본 HTML로 위조하면 FAIL이다. 파일별 허용 목록·무조건 PASS는 추가하지 않았다.

수정 파일

파일 변경 내용·이유
Guard 독립 Storybook profile/preview 연결·진단 범위, Navigation 분석 연결, 내부 Reference wrapper의 검토 판정, tabs slot intent 인식, 검사 파일 목록. Production 규칙을 삭제하지 않고 근거의 확실성을 구분한다.
Navigation 분석기 (신규) 소비 코드를 실행하지 않는 제한된 render-value 분석. immutable literal props/locals만 absent를 증명한다. 미지원 흐름·callback·spread·mutation·alias·비원시 identity에는 불확실성을 유지한다.
회귀 테스트 기존 14개 본문을 그대로 보존하고 22개 test를 추가한다.
Guard 정책 문서 두 profile과 Component/Pattern 경계, 조건부 Navigation, Reference wrapper, CSS intent/utility 제한, exit 0 ≠ PASS 설명.
이 보고서 (신규) 분석·명령·결과·보존·미검증 근거 기록. 이전 보고서를 덮어쓰지 않는다.

추가 테스트

  • 기존 테스트: 14개, 기존 본문 byte 내용(개행 정규화 대조) 유지, 14/14 PASS.
  • 신규 테스트: 22개. compact/default/literal/alias/barrel props, 실제 Reference 선택, 미확정 조건, 다중 호출, literal ternary/logical, spread·mutation·callback·destructuring·객체 alias, 혼합 Navigation 및 PARTIAL, Storybook discovery·공개 export·CSS entry·lazy CSS 격리, Reference wrapper, 정상 Gradient 파싱, malformed CSS·위조 slot, raw CSS import, package scope, component prop Sidebar 전달을 포함한다.
  • 전체 테스트: 36/36 PASS.
  • 실패 테스트: 0. 개발 중 테스트가 드러낸 누락은 최종 코드에서 수정했다. 성공한 최종 검증은 추가 변경이 없으면 반복하지 않았다.

최종 검증

항목 결과·실제 실행 근거
GUARD_TEST PASS — node --test scripts/ai-generation-guard.test.mjs, 36/36.
GUARD_FULL_SCREEN NOT VERIFIED — 운영 GNB_ONLY, Dashboard/Recruit DASHBOARD_ONLY 모두 FAIL 0. 각 Navigation·Production 격리·CSS entry·공개 import 그룹은 PASS. 각 11건의 잔여는 REUSE-003 10건 + RENDER-002 1건이다.
GUARD_PARTIAL NOT VERIFIED — 운영 CSS와 Dashboard composition 각각 RENDER-002 1건. Publisher 두 Story는 독립 profile에서 PASS. package Tabs CSS는 SCOPE-001 1건으로 독립 소비 검사가 아님을 명시한다.
GUARD_STORYBOOK NOT VERIFIED — 전체 63개 Story module의 graph 검사, FAIL 0. 공개 import·격리 profile·CSS entry 그룹 PASS, Navigation NOT APPLICABLE. 내부 Reference wrapper 1건, CSS intent 16건, native control 19건을 유지한다. Publisher 두 Story PARTIAL은 PASS.
TYPECHECK PASS — npm run typecheck, 사전 Theme/package 검사 및 루트·workspace TypeScript 검사 exit 0.
UI_BUILD PASS — 위 pretypecheck의 npm run build:packages가 UI/Center Graphic build를 수행했다. 동일 package build를 다시 실행하지 않았다.
PRODUCTION_BUILD PASS — npm run build --ignore-scripts; Dashboard 기존 Vite config build + node scripts/finalize-dashboard-export.mjs; Recruit 기존 Vite config build. 모두 exit 0. 이미 끝난 사전 package/Theme 검사는 중복하지 않았다.
STORYBOOK_BUILD PASS — npm run build-storybook --ignore-scripts, exit 0, 291개 Story ID 산출물.
TEST NOT VERIFIED — 일반 test script/Component unit runner가 없다. 지원되는 Guard suite는 GUARD_TEST에 별도로 기록한다.
CSS_IMPORTS PASS — source CSS 78개·import 63건, 미해결 0. index.css → tailwind.css, 공개 UI Tailwind/Theme/status entry, compiled UI @source "./index.js" 존재, flex/grid/min-w-0/px-0/py-6 생성 및 관련 React 계산값 확인.
EXPORTS PASS — runtime 공개 import 688건, 누락 0; 공개 export 산출물 16개 모두 존재. source barrel/API는 미변경.

지원되지 않는 전용 Component/Pattern Guard profile, 전체 Story별 runtime/state/포인터 검사와 과거 pixel diff는 NOT VERIFIED다. 존재하지 않는 명령을 통과로 기록하지 않는다. 기존 Tailwind bg-[var(...)] 최적화 경고와 production 500kB 초과 chunk 경고는 그대로이며 build 실패가 아니다.

실제 Guard 명령

node scripts/ai-generation-guard.mjs --target . --scope FULL_SCREEN --mode GNB_ONLY --result index.html --json
node scripts/ai-generation-guard.mjs --target . --scope FULL_SCREEN --mode DASHBOARD_ONLY --result src/exports/dashboard/index.html --json
node scripts/ai-generation-guard.mjs --target . --scope FULL_SCREEN --mode DASHBOARD_ONLY --result src/exports/recruit/index.html --json
node scripts/ai-generation-guard.mjs --target . --scope PARTIAL --mode GNB_ONLY --files src/index.css,tailwind.css --result index.html --json
node scripts/ai-generation-guard.mjs --target . --scope PARTIAL --mode DASHBOARD_ONLY --files src/patterns/dashboard-composition.tsx --result src/exports/dashboard/index.html --json
node scripts/ai-generation-guard.mjs --target . --profile STORYBOOK --scope FULL_SCREEN --json
node scripts/ai-generation-guard.mjs --target . --profile STORYBOOK --scope PARTIAL --files src/components/tabs.stories.tsx,src/patterns/page-header.stories.tsx --json
node scripts/ai-generation-guard.mjs --target . --scope PARTIAL --files packages/ui/src/theme/tabs.css --json

실제 React 확인

로컬 Chrome에서 실제 build 산출물을 확인했다. Dashboard/Tabs/PageHeader의 대표 확인 범위이며 전체 291개 Story를 다시 렌더했다는 주장이 아니다.

  • Dashboard: Sidebar 0개, Header 48px, layout min-width 960px, body flex. Token 기반 20/50/80% gradient 유지. 완료 필터 클릭으로 완료 업무 12건과 선택 상태·Table 갱신 확인. 390px에서 document 390px, frame client 390/scroll 960, overflow-x auto. Console error/warn 0.
  • Tabs 1280/390px: Primary color(srgb 1 1 1 / 0.8) → rgb(245,240,229), opacity 1. Secondary White→White. Fill active panel 7개 모두 24px 0 / transparent / border 0 / radius 0. Card 탭 전환 후 입력 초안 보존. document width 1265/375px(세로 scrollbar 제외), 가로 넘침 없음. Console error/warn 0.
  • Legacy Compatibility: 기존 non-fill 2개가 gradient none / White / panel border 1px / padding 16px. surface-only Secondary Fill은 평면 패널 유지.
  • PageHeader 1280/390px: 설명 margin-top 8px, Header margin-bottom 20px, panel 24px 0, Primary alpha .8. 완료 업무 클릭 시 완료 Table로 전환, 문서 폭 1280/390px.
  • 브라우저 임시 viewport를 복원하고 검증 탭과 loopback 서버를 종료했다. source 화면/API를 바꾸지 않았다.

보존 확인

항목 결과
D-01/D-02 PASS — Tabs CSS/Story·PageHeader Story source hash 동일. 공식 Tabs source/dist CSS 동일. 실제 위 패널·Gradient·Legacy 렌더 보존.
Component/API PASS — 기존 Component/Pattern TSX·공개 barrel·package.json·lockfile hash 동일.
Theme/Token PASS — Theme JSON/계약/CSS source hash 동일, 기존 check:theme-defaults의 71색/73 defaults 일치.
Storybook ID PASS — Story source/export 미변경, 291개 현재 ID 산출물 및 기존 inventory 288개 ID 모두 보존.
참고 원본 PASS — 3개 파일 SHA-256 동일, 읽기 전용 유지.
기존 파일 PASS — 시작 source 504개 중 Guard·테스트·Guard 문서 3개만 변경, 나머지 501개 동일. 분석기·이 보고서는 신규다. 이전 통합 보고서/기존 작업을 보존했다.

파일 목록·SHA-256·수정 전 사본은 _local/guard-accuracy-2026-10-10/: _local/guard-accuracy-2026-10-10/ (당시 로컬 보관 증거, Git Clone 미포함)에 보존했다. node_modules·빌드 산출물·tsbuildinfo·기존 _local·Git metadata는 source baseline에서 제외했다. 빌드 산출물은 지원되는 기존 명령으로 재생성했고 source 보존과 구분한다. 해당 경로의 baseline.json, reference-baseline.json, before/, tests-final.log, guard-summary.json, guard-*.json, 각 build log, static-audit.json, browser-evidence.json, preservation-final.json이 이번 증거다. 이전 _local/publisher-* 로그/사본은 덮어쓰지 않았다.

남은 문제

  • REUSE-003/004와 내부 Reference wrapper는 의도를 정적 코드만으로 확정할 수 없다. 실제 fixture·문서·사용 화면별 검토가 필요하다. 전체 Guard PASS로 표기하지 않았다.
  • RENDER-002는 tool의 브라우저 확인 요구를 나타낸다. 이번 대표 실제 렌더 증거와 원본 JSON 상태를 따로 기록한다. 브라우저 증거를 근거로 JSON을 임의 PASS로 덮어쓰지 않는다.
  • package source의 독립 Guard 범위는 지원하지 않는다. 패키지 typecheck/build/CSS declaration/hash/관련 렌더 검증은 별도 수행했다.
  • 일반 Component unit runner, 전 Story/Props/브라우저/state 회귀, 외부 소비 앱·배포·역사적 pixel diff는 NOT VERIFIED.
  • .git이 없는 폴더다. Git status/diff/HEAD 및 미커밋 구분은 NOT VERIFIED이며 파일 baseline으로 기존 작업을 보존했다.

Git

Git Init: NOT EXECUTED
Git Clone: NOT EXECUTED
Local Commit: NOT EXECUTED
Remote Push: NOT EXECUTED
Git commands / remote changes: NOT EXECUTED

최종 판단

  • 기존 Dashboard Guard FAIL은 해결했다. 금지 Sidebar를 실제 선택하는 fixture는 계속 FAIL이다.
  • 실제 위반 탐지 능력은 기존 14개+신규 22개로 검증했다. 미확정 경로를 PASS로 숨기지 않는다.
  • 정상 D-01/D-02·Component/Pattern/Theme/Storybook source를 수정하지 않았고 지원되는 build/typecheck 및 대표 실제 렌더에서 회귀를 발견하지 않았다. 전수 runtime 회귀는 NOT VERIFIED다.
  • 로컬 Git 커밋은 보류한다. Git metadata 부재와 잔여 NOT VERIFIED 검토를 다음 단계에서 별도로 판단해야 한다. 이번에는 Git 작업을 수행하지 않았다.

작업 시간 (Asia/Seoul)

  • Started At: 2026-10-10 00:14:14 KST
  • Completed At: 2026-10-10 00:48:42 KST
  • Actual Duration: 34분 28초
  • Estimated Duration: 45–65분
  • Variance: 예상보다 10분 32초–30분 32초 단축