Files
HMDesign/docs/guidelines/publisher-validation-2026-10-10.md
T

99 lines
12 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.
# 퍼블리셔 잔여 이슈 수정·회귀 검증 (2026-10-10)
RESULT: PARTIAL — 아래 필수 기능·빌드·테스트 검증은 통과했다. 개발 의존성 High 7건, 과거 실패 당시 브라우저 조건의 미확정, 기존 숨김 비교 Story의 넘침과 실기기/SR 미검증을 보존한다.
TARGET: `D:\디자인시스템\hmdesign` / BOTH / React.
BASE_SHA: `581a130883db921696cadda872ab0887e2b0e797`. 시작 working tree는 clean이며 GitHub main과 같았다. 공식 Gitea는 접근·변경하지 않았다. 이 문서는 이전 보고서를 대체·소급 수정하지 않는다.
## Theme 자동 검사
수정 전 정상 Chromium Context와 기존 Edge에서는 JSON Loader 119개·Designer 96개가 통과했다. 검사 중 CSS animation clock을 멈추는 **통제된 렌더 지연 재현**에서는 Loader가 80개 후 `HTTP JSON reaches rendered Checkbox`, Designer가 53개 후 `Checkbox fill uses Active`에서 실패했다. 이때 `data-state=checked`, `aria-checked=true`, Active Runtime Key `#007f73`는 정상인데 계산된 Checkbox 색상은 이전 Default/보간 색상이고 CSS transition은 paused 상태였다.
이 증거는 고정 250ms 대기가 최종 계산 색상을 보장하지 못하는 검사 문제를 확인한다. 이전 독립 검증 당시 브라우저가 같은 조건이었는지는 확인하지 못했다. 일반 실행에서 그 간헐적 실패가 자연 재발했다고 주장하거나 원래 환경 원인을 완전히 확정하지 않는다.
변경은 verification Story에 한정한다. 최종 CSS target 비교 범위에 transition duration/delay 0을 적용하며 일반 Editor·Component·Production timing은 그대로다. Designer의 시험용 input/click dispatch는 React `flushSync`로 commit 경계를 보장하고, 실제 변수/checked/ARIA/계산 색상 조건을 최대 5초 동안 확인한다. 고정 Sleep을 늘리지 않았고 Checkbox assertion과 119/96개 기존 검사를 보존했다. 조건이 끝내 만족되지 않으면 진단과 함께 실패한다. Controlled/Uncontrolled API, focus/keyboard, session store, Runtime Apply/Reset/Loader는 변경하지 않았다.
최종 정적 빌드에서도 정상·지연 조건 각각 Loader 119개 / Designer 96개가 통과했다. 새 Context·기존 Context/탭·새 탭·반복·역순·Reset 후·다른 Story 방문 후의 7가지 조건을 3라운드 검사했다(반복 조건은 라운드마다 2회): **각 Story 24회 통과, 실패 0**. 별도로 390/768/1280/1440px 각 1회와 독립 Clone 각 1회도 통과했다. 기존 Edge Designer와 새 Edge 탭 Loader에서도 각각 96/119개를 확인했다. 이 유한 반복 결과가 모든 브라우저의 간헐적 실패 부재를 보증하지는 않는다.
실제 Tab/Shift+Tab/Enter로 Runtime 검증을 실행해 **138 checks / 58 rendered parts / KEYBOARD_FOCUS: PASS**를 확인했다. 같은 preview document에서 Designer Active를 변경하고 Color Story로 전환했을 때 `performance.timeOrigin`이 같고 Default `#266651`로 복원되며 inline override가 제거됐다. 편집기로 돌아오면 세션 편집값이 복원되고 Reset으로 비워졌다. [Designer 안내](designer-theme-guide.md)는 이 동작과 일치한다.
## 문서와 Git 공유
- Git Clone에 없는 과거 증거 링크 7개를 당시 `_local/` 경로의 텍스트 보관 기록으로 전환했다. 파일을 새로 만들거나 과거 PASS/PARTIAL 결과를 바꾸지 않았다.
- Runtime portability의 중복 `3.2 Button`을 `3.4 Button`으로 정정했다.
- README·개발 적용·예제·공유 안내에 GitHub Clone, Node 조건 `^20.19.0 || >=22.12.0`, 검증 npm 10.8.2, `npm ci`, workspace build, Storybook 6024와 신규 React 화면 제작 절차를 반영했다. 과거 ZIP 기록은 분리 보존했다.
- Designer의 “다른 Story에도 반영”이라는 오래된 화면 문구를 실제 격리 동작에 맞게 수정했다. 임시 데이터는 sessionStorage에 보관되며 검수 Story에 적용되지 않는다.
- `node scripts/check-doc-links.mjs`는 Git 공유 MD의 경로·heading과 Clone 제외 로컬 증거 링크를 검사한다. 무시되지 않은 신규 MD도 검사한다. 최종 전체 검사에 오류가 없어야 한다.
- 기존 Git 실행 BAT, package.json, lockfile은 변경하지 않았다. ZIP 생성·포터블 패키징·Gitea 접근은 수행하지 않았다. [현재 실행 안내](publisher-distribution-guide.md).
## 검증 결과와 범위
| 항목 | 실제 결과 |
|---|---|
| THEME_DEFAULTS | 71색 / 73 defaults 일치 |
| UI_BUILD / PACKAGE_BUILD | UI·CENTER workspace build 통과 |
| TYPECHECK | root/UI/CENTER 및 예제 통과 |
| PRODUCTION_BUILD | root 앱·Dashboard export·공개 HM 목록 예제 통과 |
| STORYBOOK_BUILD | 통과, 292개 ID 보존·삭제/추가 없음 |
| COMPONENT_TEST | 기존 8/8 통과, 테스트 원본 byte 보존 |
| GUARD_TEST | 기존 40/40 통과, 테스트·Guard 규칙 byte 보존 |
| THEME_STATE_TEST | 신규 3/3 통과: 비동기 실제 상태 대기·미충족 timeout·검증 CSS 범위 |
| GUARD_FULL_SCREEN | 예제 GNB_ONLY / React index.html, FAIL 0 |
| GUARD_PARTIAL | 변경 Theme Story/helper만 Storybook profile로 확인, FAIL 0 |
| GUARD_STORYBOOK | 전체 Storybook profile, FAIL 0 |
| CSS_IMPORTS | CSS import 69개, 누락 0 |
| EXPORTS | 공개 import 736개·export artifact 16개, 누락 0 |
| DOC_LINKS | 전체 MD 경로/heading 및 로컬 증거 링크 검사 오류 0 |
| THEME_JSON_LOADER / DESIGNER | 위 반복·지연·viewport·Clone 검사 통과 |
| PACKAGE_CONSUMER | 최종 UI/CENTER pack 독립 설치, strict:true / skipLibCheck:false 타입 검사 통과 |
| GIT_CLONE_RUNTIME | GitHub Clone의 fresh npm ci·typecheck·UI/CENTER/Storybook build·6024 dev 실행 통과 |
| NEW_REACT_SCREEN | Clone의 `_local/new-screen`에서 공개 HM 실제 React bootstrap·typecheck/build/dev·조회/초기화/모바일 메뉴 통과 |
| RESPONSIVE | 대표 Story 18개 × 4폭, 운영 앱·목록·신규 화면 4폭, Sheet 4방향 × 4폭·Drawer 4폭 확인 |
필수 Guard FAIL은 없지만 정적 Guard의 최종 상태는 `NOT VERIFIED`다. Native 검증 도구 UI/소비 스타일 의도와 React 실제 렌더 판정 한계를 의미한다. 원본 JSON을 PASS로 바꾸지 않았다. UI source·실제 렌더 증거와 구분한다.
패키지 소비 프로젝트는 `@tanstack/react-table`과 직접 `@tanstack/table-core` 9.2.4 경계를 확인했다. API export 수량은 UI 255 / Theme 8 / CENTER 25 / CENTER Reference 10이다.
전체 **292개 Story는 1280px에서 렌더 확인**했다. 전체 Story의 모든 Props/interaction/모바일을 전수 검사했다는 의미는 아니다. 상세 동작은 조회/초기화/Enter, 메뉴/Escape, Sheet 안쪽 모서리·focus 복귀, Drawer 버튼 위치, Dialog Solid 세트·focus 유지, Input readOnly/disabled, Label focus, Tabs ArrowRight·flat panel, Progress radius, Accordion 제목 Hover 5%, Theme Focus/격리로 한정한다.
예상하지 않은 앱 Runtime/Console error는 관찰하지 않았다. Loader의 의도적 missing JSON 404와 Avatar fallback의 의도적 broken image 404는 원본 로그에 보존한다. 전체 렌더 탐색에서 숨김 `components-form-select--list-size-comparison`만 1280px에서 scrollWidth 1352였다. 수정 전 정적 빌드도 동일 1352여서 기존 비교 canvas 제한으로 남기고 공통 Select/대표 Story를 수정하지 않았다. 대표 18개 Story와 앱/목록/신규 화면의 4폭에서는 페이지 가로 넘침이 없었다.
Clone은 기존 node_modules/dist/환경 설정을 복사하지 않고 GitHub에서 받았다. Push 전 후보 source 변경만 적용하여 독립 설치·빌드했으며 최종 commit의 tree와 대조한다. 임시 화면·검사 코드·산출물은 `_local/`에 두고 Git에 포함하지 않는다. 소스의 로컬 절대경로 의존성도 별도 검사한다. npm ci의 선택적 WASM dependency cleanup EPERM 경고는 남았으나 설치 exit 0·실제 타입/빌드/실행은 통과했다.
## 기존 요청 보존
시작 추적 source 517개의 SHA-256을 기록했다. 변경된 기존 파일은 문서 8개와 Theme 검사 Story 2개뿐이다. Component/Pattern 구현·CSS·대표 Story(Theme 내부 설명 제외)·공개 barrel/API·Default JSON/Primitive/Semantic/생성값·기존 Component/Guard 테스트·실행 BAT·package/lockfile은 byte 동일이다.
D-01/D-02, Secondary/Legacy, 목록 Card/Filter/Table, 버튼·Table 강조 20%·Progress·Accordion·Separator·Sheet/Drawer·Navigation 및 C2~R3 구현을 다시 변경하지 않았다. 필요한 대표 실제 동작을 위와 같이 재검증했으며 모든 상태의 역사적 pixel diff를 수행했다는 뜻은 아니다.
## 개발 의존성 보안
현재 `npm audit --json`은 High 7 / Critical 0, `npm audit --omit=dev --json`은 0이다. 7개는 개별 독립 취약점 7개가 아니라 다음 직접 개발 도구와 간접 전파 그래프다.
| 패키지 | 설치 버전 | 경계 |
|---|---|---|
| shadcn | 4.21.1 | UI workspace 직접 devDependency |
| @shadcn/registry | 0.1.0 | 간접 개발 도구 |
| ts-morph | 26.0.0 | 간접 코드 생성/분석 도구 |
| @ts-morph/common | 0.27.0 | 간접 개발 도구 |
| fast-glob | 3.3.3 | 간접 glob 탐색 |
| micromatch | 4.0.8 | 간접 glob matching |
| braces | 3.0.3 | 깊게 중첩된 pattern의 stack exhaustion 원인 |
실행 경로는 shadcn CLI의 registry/파일 glob 처리다. 현재 app/package/Storybook build scripts는 shadcn CLI를 실행하지 않는다. 운영 dependency 감사는 0이며 소비 앱에 shadcn devDependency를 배포하지 않는다. 외부의 비신뢰 glob/registry 입력으로 해당 CLI를 호출할 때 위험은 남는다.
[GitHub 공식 권고 GHSA-vfj7-8cjw-p6xm](https://github.com/advisories/GHSA-vfj7-8cjw-p6xm)는 braces <=3.0.3에 패치 버전이 없음을 명시한다. npm 레지스트리 최신 braces는 3.0.3, shadcn은 4.21.4이지만 audit의 영향을 받는 상위 범위에 속해 이 patch만으로 해소되지 않는다. audit가 제안하는 shadcn 1.0.0은 현재 4.x의 major 역행이므로 보류했다. 강제 fix/override/major 교체나 lockfile 변경을 하지 않았다. Storybook 10.6.1 / Vite 8.3.0 / React 19.3.0의 현재 호환 구성을 유지했다.
500kB chunk·Storybook bundler 성능 안내는 번들 크기/성능 경고이며 이 braces 입력 처리 취약점과 다른 원인이다. 불필요한 대규모 upgrade로 해결했다고 표시하지 않는다.
## 잔여 제한과 판단
- 이전 간헐적 실패 당시의 정확한 브라우저 lifecycle/visibility 조건은 미확정이다. 확인한 검사 clock 의존성은 수정했고 반복 실행에서 재발하지 않았다.
- 개발 도구 High 7건과 숨김 Select 비교 canvas의 기존 넘침은 남는다.
- 실제 SR 발화·실기기 touch/drag·Node 미설치 PC·지원되는 모든 Node/npm/브라우저 조합은 미검증이다.
- 미확정 컬러 의미·최종 Sheet radius·설정/도움말 숨김은 확정하지 않았다.
- 필수 빌드·테스트·독립 설치/실행·대표 UI 검증을 통과하고 Critical/High 기능 회귀가 없어 GitHub main 일반 Push 대상이다. 위 제한을 포함하는 PARTIAL 테스트 공유이며 공식 Gitea 이전·운영 승인 완료를 뜻하지 않는다.
증거: `_local/publisher-validation-20261010/`의 baseline·transition-before/final·checks·browser matrix/responsive/all-stories·interactions·focus-isolation·clone·consumer·audit·preservation 로그/JSON/캡처와 최종 보고. 이 경로는 로컬 보관 자료이며 Git Clone에 포함되지 않는다. 과거 `_local/publisher-*` 검증 결과는 덮어쓰지 않았다.