한국어
24장 디자인 시스템 배포와 채택
디자인 시스템의 CSS와 토큰은 버전이 있는 패키지로 배포하고, Vue wrapper와 패턴은 제품이 복사해 소유합니다.
leysys-design은 대표 소비처까지 검증하고, 나머지 제품은 각자의 일정과 CI로 채택합니다. 이 장은 이 배포 모델과 채택 절차를 설명합니다.
왜 필요한가
처음에는 CSS를 제품 저장소마다 복사하고, 디자인이 바뀌면 같은 작업 안에서 모든 저장소를 똑같이 맞췄습니다. 이 방식을 지키는 수단은 규율뿐이었습니다. 소비 저장소가 여섯 곳 이상으로 늘어난 2026-07-10 KST에는 한 제품 저장소가 자체 규칙과 클래스를 만들어 사본이 정본과 갈라졌습니다.
백지에서 다시 보면 답은 버전 있는 아티팩트였습니다. 무엇을 쓰는지가 lockfile(설치한 정확한 버전의 기록)에 남고, 맞추기는 의존성 해석이 맡습니다. Vue wrapper는 제품이 고쳐 쓰는 코드이므로 shadcn/ui처럼 복사를 유지했습니다.
그 뒤 릴리스마다 모든 소비처를 갱신하자, 컴포넌트 하나만 바뀌어도 여러 저장소의 설치·빌드·PR·CI가 따라왔습니다. 품질이 아니라 독립 제품의 일정을 디자인 작업에 묶은 비용이었습니다. 그래서 2026-08-02 KST에 채택은 각 저장소가 소유하기로 바꿨습니다.
모델: 두 가지 배포 경계
| 바뀐 것 | design의 고정 기준 | 제품의 채택 | 패키지 게시 |
|---|---|---|---|
| CSS·토큰 | 게시된 패키지 버전과 원격 tag | package.json의 정확한 버전(exact version) + lockfile + 제품 CI | 필요 |
| registry wrapper·패턴 | 병합된 design PR의 merge SHA | 필요한 item과 의존 item 전체 복사 + 제품 CI | 불필요 |
| 문서·샘플 | merge SHA | 참조 | 하지 않음 |
패키지
- 디자인 시스템 하나에 패키지 하나입니다.
@leysys/eds,@leysys/mds,@leysys/print-ds,@leysys/markdown-ds. CDS는 CSS도 코드도 없는 참고 문서라 패키지가 없습니다(6장). - 패키지에는 CSS·토큰과 클래스 목록(
classes.json) 같은 manifest만 있고 Vue 코드는 없습니다. 제품 CI는 코드가 쓰는 클래스가 모두classes.json에 있는지 검사해, 없는 클래스를 지어내지 못하게 합니다. - GitHub Packages에 조직 내부용으로 게시합니다. 네 패키지는 한 버전으로 함께 움직이며, 이 판의 기준은 3.1.3입니다.
EDS와 MDS를 다른 패키지로 나눈 데에는 이유가 있습니다. 한 페이지에 두 진영을 섞지 않는다는 규칙을 의존성 단계에서 막기 위해서입니다. console 저장소는 @leysys/eds만 의존하므로 MDS 클래스가 애초에 없습니다. 실제로 EDS와 MDS가 섞인 투표 프로토타입을 두 저장소로 나눌 때, 차트 화면이 MDS의 drawer 부품에 의존한다는 사실이 자동으로 드러났습니다. 그 화면은 EDS 저장소에 들어가지 못하고 MDS portal 저장소로 갔습니다.
제품은 버전을 정확히 고정합니다.
text
.npmrc @leysys:registry=https://npm.pkg.github.com
package.json "@leysys/eds": "3.1.3" (^ · ~ · latest를 쓰지 않고 lockfile을 커밋)릴리스 흐름
패키지 소스를 바꿀 때는 changeset(바뀐 내용과 버전 단계를 적은 파일)을 함께 올립니다. 릴리스는 게시 후보(candidate)를 한 번 만들어 검사하고, 통과한 그 산출물을 그대로 게시합니다.
text
패키지 소스 + changeset 병합 → Version PR 생성
Version PR 병합 → 그 SHA로 candidate 생성
→ 저장소·브라우저·Print(관련 시)·대표 소비처 검사
→ 모두 통과하면 같은 candidate를 게시하고 원격 tag
문서 사이트만 바뀐 push → 패키지 릴리스 없음앞 버전의 tag가 빠져 있으면 다음 버전 게시를 막습니다. Version PR은 사람·App 신원의 토큰으로 만들도록 workflow를 설정했습니다. Actions 기본 토큰이 만든 PR에서는 필수 검사가 실행되지 않기 때문입니다.
registry 복사
wrapper와 패턴은 복사한 뒤 제품이 소유하고, 의도적으로 다르게 고칠 수 있습니다. 파일 하나를 골라 복사하지 않고, canonical item과 그 item이 import하는 item을 재귀로 모은 의존 묶음(dependency closure) 전체를 복사합니다. 명령은 제품 저장소에서 실행하고, design 저장소는 병합된 상태(main)여야 합니다.
bash
node scripts/sync-from-design.mjs --registry=e-tabs,e-table-card \
--receipt=docs/verification/registry-sync-receipt.json- 영수증(receipt)에는 design 기준과 파일마다의 상태·SHA-256이 남고, 제품은 이 값으로 registry 목록을 갱신합니다. 제품이 따로 더한 파일은 지우지 않고
kept로 보고합니다. - 아이콘 provider 같은 add-on은 design의
src/registry/addons/vue/에 있으므로--family=addons/vue를 지정합니다(기본값vue). - 파일 복사 명령이라,
src/registry/**의 AI 직접 편집을 막는 제품 권한 설정과 함께 쓸 수 있습니다.
소비처 소유와 대표 소비처
design 릴리스가 책임지는 범위는 셋입니다. 정본 계약과 릴리스 검사, 같은 candidate로 하는 대표 소비처 검증, 그리고 SemVer 버전·변경 기록·호환이 깨지는지와 이행 안내입니다.
| 디자인 시스템 | 대표 소비처 |
|---|---|
| EDS | leyve-console-proto, leyve-center-proto |
| MDS | leyve-www-proto |
| Print DS | leysys-print |
| Markdown DS | leyve-docs-proto |
이 다섯 곳의 정본은 scripts/lib/ds-consumer-targets.mjs이며, 조직 전체 소비처 목록이 아닙니다. 나머지 제품은 게시된 정확한 버전과 필요한 registry item을 자기 일정·PR·CI로 채택합니다. design 변경이 다른 저장소를 고칠 권한을 자동으로 만들지 않습니다. 정기 점검도 매주 월요일 09:20 KST에 대표 소비처만 봅니다.
제품에서 찾은 결함이 다른 제품에도 생길 수 있는 것이면, 제품에서 override나 !important로 덮지 않고 design에서 먼저 고칩니다.
소비처 안내 문서
호환이 깨지거나 사용법이 바뀌면 leysys-design의 docs/migrations/outbound/에 안내 문서를 둡니다. 3.1 안내는 이름 변환 도구(@leysys/legacy-vocabulary-audit)의 미리보기(--dry-run)와 적용(--fix), 남은 수동 항목과 검증 순서를 담습니다. 안내의 목표 버전은 게시 완료를 뜻하지 않으므로, 소비처는 게시를 확인한 버전을 씁니다.
채택 PR에 남길 것
채택 PR은 무엇을 어디서 가져왔고 무엇을 확인했는지 남깁니다. 해당하지 않는 항목은 N/A와 이유를 적습니다.
markdown
## SSOT provenance
- Design PR:
- Design merge SHA:
- Package exact version / remote tag:
- Copied registry items and dependency closure:
- Migration document:
- Current proof boundary (proven / pending / failed / N/A):
- Intentional consumer divergence:
## Consumer verification
- Actual routes:
- Unit / type / lint / build:
- Keyboard / focus / ARIA:
- Responsive / browser:- 실행하지 않은 검사를 PASS로, pending을 증명된 것으로 적지 않습니다. 패키지 게시, design의 브라우저 검증, 제품 화면 검증은 서로를 대신하지 않습니다.
- 게시·tag나 merge SHA를 확인할 수 없거나 실행으로 재현된 고장이 있으면 채택을 멈춥니다. 정책 편차 경고(alert)나 다른 제품의 미채택만으로는 멈추지 않습니다.
경계와 예외
- 패키지 버전만 올렸다고 복사한 wrapper가 갱신되지는 않습니다.
- 문서·샘플만 바뀐 변경은 패키지를 게시하지 않고 소비처 빌드도 하지 않습니다.
- 정본과 다른 제품 편차는 경고(alert)입니다. 실제 실행·접근성·보안·무결성 고장이 없으면 그것만으로 병합을 막지 않습니다.
정리
- CSS·토큰은 버전 패키지, wrapper·패턴은 복사본입니다.
- 제품은 정확한 버전을 쓰고, registry는 병합 SHA의 item과 의존 묶음 전체를 복사합니다.
- design은 대표 소비처 다섯 곳까지 검증하고, 나머지는 각 제품이 채택합니다.
- 채택 PR에는 출처·버전·복사 항목·이행·증명 범위·의도적 편차를 남깁니다.
정본
leysys-designdocs/decisions/NPM-PACKAGE-DISTRIBUTION-PROPOSAL-2026-07-10.md— 패키지 배포 결정leysys-designdocs/decisions/CONSUMER-UPDATE-OWNERSHIP-2026-08-02.md— 소비처 소유와 대표 gateleysys-designdocs/process/SSOT-CONSUMER-ADOPTION-STANDARD.md— 채택 절차와 PR 기록leysys-designdocs/process/REGISTRY-GUIDE.md§6 — registry 복사와 동기화 명령leysys-designdocs/decisions/RELEASE-PATH-SCOPED-GATES-2026-07-18.md·docs/process/RELEASE-VERSION-PR-CI-TRIGGER.md— 릴리스 흐름leysys-designscripts/lib/ds-consumer-targets.mjs— 대표 소비처 목록leysys-designdocs/migrations/outbound/— 소비처 안내 문서