# Doctor URL: /ai-integration/skill/doctor Source: https://github.com/daangn/seed-design/blob/dev/docs/content/ai-integration/skill/doctor.mdx 저장소 맥락에 맞춰 SEED 설정, 호환성, 셋업, Foundations, 컴포넌트, 라이브러리 계약을 읽기 전용으로 진단합니다. Doctor는 SEED를 쓰는 워크스페이스를 찾아 **그 맥락에 적용되는 건강검진을 선택 실행**합니다. 컴포넌트 린터가 아니라 설정·패키지·앱 셋업·토큰 공개 계약·컴포넌트 가이드라인·라이브러리 배포 계약을 공식 문서와 실제 코드 증거로 연결하는 가이드입니다. 진단은 읽기 전용입니다. 코드를 고치거나 패키지를 설치하지 않고, schema v2 YAML과 사람이 읽는 HTML 리포트를 임시 디렉토리에 함께 기록합니다. 실제 수정은 사용자가 별도로 지시할 때만 합니다. ## 문서와 스킬의 관계 지원 범위와 문서 목록은 스킬에 복사하지 않습니다. Doctor는 실행할 때마다 다음 인덱스를 읽습니다. - [SEED 전체 문서 인덱스](https://seed-design.io/llms.txt) - [React 문서 인덱스](https://seed-design.io/react/llms.txt) - [Lynx 문서 인덱스](https://seed-design.io/lynx/llms.txt) 전체 인덱스에서 공통 Components·Foundations 문서를 찾고, 선택된 플랫폼 인덱스에서 설치·업그레이드·컴포넌트·저자 문서처럼 이번 진단에 필요한 현재 leaf 문서를 찾습니다. 인덱스를 정상적으로 읽었는데 계약 문서가 없으면 `not-applicable`, 인덱스나 연결 문서를 읽지 못하면 `not-verified`입니다. 다른 플랫폼 문서로 빈칸을 채우지 않습니다. Doctor 요청 하나는 URL 기준 문서 풀 하나를 사용합니다. 전체·플랫폼 인덱스와 leaf 문서는 URL마다 한 번만 읽고 같은 실행의 workspace와 rule이 재사용합니다. 결과의 `references`에 같은 URL이 반복되어도 출처를 표시하는 것이며 문서를 다시 요청한다는 뜻은 아닙니다. ## 사용법 스킬을 로드한 상태에서 자연어로 요청하면 됩니다. ```text SEED 잘 쓰고 있나 봐줘 셋업만 진단해줘 공유 React 패키지의 Library Authors 계약을 검사해줘 이 모노레포의 SEED 워크스페이스를 전부 진단해줘 ``` Quick/Deep 모드는 없습니다. 일반 진단은 적용 가능한 룰 전체를, 범주가 지정된 요청은 해당 범주만 실행합니다. ## 결과물 워크스페이스마다 `doctor-report.yaml`과 `doctor-report.html`을 함께 만듭니다. YAML은 판정과 근거의 단일 원천이고, HTML은 검증을 통과한 YAML을 `report-template.html`에 렌더링한 읽기용 결과입니다. 두 파일 모두 대상 프로젝트가 아닌 같은 임시 디렉토리에 저장합니다. 사용자가 명시적으로 "YAML만"을 요청한 경우에만 HTML을 생략합니다. ## 탐색 순서 1. 사용자가 지정한 경로 2. `node_modules`, `.git`, `.claude/worktrees`를 제외한 `seed-design.json` 3. 설정 발견 여부와 관계없이 workspace별 직접 `@seed-design/*` 의존성 4. 두 후보를 package 경계로 중복 제거 5. 사용자 명시 → `framework` → 직접 의존성 순의 플랫폼 확정 6. 앱 entry와 공개 진입점·library build 증거로 `app`·`library` 역할을 비배타적으로 판정 여러 워크스페이스가 발견되면 대상을 확인합니다. "전체" 요청은 워크스페이스별 리포트를 따로 만들며 서로 다른 `meta`를 하나로 합치지 않습니다. `seed-design.json`이 없더라도 직접 패키지 사용은 계속 진단하고, 설정이 필요한 스니펫 룰만 적용 제외합니다. ## Rules | 룰 | 범주 | 판단하는 것 | | ------------------------- | ------------- | ------------------------------------------------- | | `project-config` | config | 현재 CLI 설정 계약, framework 충돌, snippet path·alias 연결 | | `package-compatibility` | compatibility | 설치본 peer 또는 현재 공식 호환 문서와 패키지 조합 대조 | | `project-setup` | setup | 현재 플랫폼 설치·스타일 문서와 앱 연결 대조 | | `snippet-compatibility` | compatibility | 현재 공식 CLI 호환 검사 결과 | | `foundation-contract` | foundations | 토큰 존재·공개성·제거·내부 스타일 API 의존 | | `library-authors` | library | 현재 공식 저자 문서가 있는 플랫폼의 배포 계약 | | `outdated-version` | compatibility | 설치 패키지의 최신 세대 격차만 | | `snippet-generation` | compatibility | 설치 스니펫과 최신 registry의 세대 차이만 | | `no-deprecated-component` | components | 플랫폼에 유효한 출처가 있는 deprecated 사용 | | `component-guidelines` | components | 현재 공통 가이드라인과 플랫폼 인덱스로 연결한 구현의 대조 | 실제 호환 오류·필수 셋업 누락은 `error`, deprecated·내부 API·배포 위험은 `warn`, 최신 세대 격차는 `info`입니다. Foundations에서는 하드코딩이나 semantic token 선택의 적절성을 추론하지 않고 계약 위반만 판정합니다. `component-guidelines`의 기준은 룰 파일에 고정돼 있지 않습니다. 각 [컴포넌트 가이드라인](/components)에서 실행 시점에 도출하므로 문서의 Do/Don't가 바뀌면 판정 기준도 함께 바뀝니다. ### project-config.md ```md # Project Config 현재 공식 CLI 설정 계약과 실제 프로젝트 경로 연결을 판정합니다. category: `config`. ## 적용 조건 선택된 워크스페이스마다 실행합니다. 설정 파일이 없어도 직접 `@seed-design/*` 의존성이 있으면 Doctor는 계속하며, 이 룰이 설정 부재의 영향을 판정합니다. ## 판정 방법 1. 전체·플랫폼 인덱스에서 현재 `Configuration` 또는 같은 역할의 CLI 문서를 찾습니다. 설치한 CLI 소스의 설정 schema를 읽을 수 있으면 함께 대조합니다. 필드 목록과 기본값을 이 룰에 복사하지 않습니다. 2. 현재 schema가 허용한 키·타입·필수값으로 `seed-design.json`을 검사합니다. CLI 실행을 막는 schema 오류는 `error`입니다. 3. 사용자 명시 → 설정의 framework → 직접 의존성 순으로 정한 플랫폼과 설정·직접 의존성을 대조합니다. 충돌하면 높은 순위 단서를 유지하고 충돌한 파일·패키지를 근거로 `error`를 냅니다. 4. 설정의 snippet path를 설정 파일 위치 기준으로 해석하고 실제 사용처와 연결합니다. 디렉토리가 없더라도 snippet import·`@file` 헤더·alias처럼 그 경로를 사용한다는 증거가 없다면 finding을 만들지 않고 evidence에만 기록합니다. 사용 증거가 있는데 디렉토리가 없으면 `error`입니다. 5. TypeScript paths와 번들러/runtime alias가 snippet path와 같은 디렉토리를 가리키는지 확인합니다. alias 자체가 필요한지는 [project-setup](./project-setup.md)이 현재 설치 문서에서 판단하고, 이 룰은 존재하는 연결끼리의 불일치만 판정합니다. 설정이 없을 때는 다음처럼 나눕니다. - 스니펫 import 또는 `@file` 헤더가 있으면 CLI가 위치를 확정할 수 없으므로 `warn`. - 직접 패키지만 사용하고 스니펫 증거가 없으면 finding을 만들지 않습니다. 설정이 전제인 스니펫 check에는 `not-applicable` 이유를 남깁니다. ## 중복 경계 - 설치 절차가 완성됐는지는 `project-setup`이 판단합니다. - 설치 패키지끼리 맞는지는 `package-compatibility`, 스니펫과 패키지가 맞는지는 `snippet-compatibility`가 판단합니다. - 설정이 유효하면 최신 버전이 아니더라도 이 룰은 통과입니다. ## 문서 풀에서 사용할 근거 - 전체·플랫폼 인덱스가 현재 연결한 CLI 설정 문서 ``` ### package-compatibility.md ```md # Package Compatibility 선택된 플랫폼의 구현·스타일 패키지 **설치본 조합**이 현재 공식 계약과 맞는지 판정합니다. category: `compatibility`. 확인된 비호환은 `error`입니다. ## 적용 조건 현재 플랫폼 인덱스의 설치 문서 또는 설치본 metadata에서 구현↔스타일 패키지 계약을 확인할 수 있고, 그 구현 패키지를 사용한 워크스페이스에 적용합니다. 스타일·토큰 패키지만 단독으로 쓰거나 패키지 간 계약 자체가 없으면 `not-applicable`입니다. ## 판정 방법 1. 플랫폼 인덱스가 연결한 설치·업그레이드·호환 문서에서 현재 패키지 역할을 찾습니다. 2. 선언 범위가 아니라 hoist를 고려한 실제 설치본 `package.json`의 버전과 peerDependencies를 읽습니다. 3. 설치본이 명시한 peer 범위가 있으면 스타일 설치본이 그 범위에 드는지 확인합니다. 4. 현재 버전 구간에 peer metadata 대신 별도 호환표를 사용하라고 공식 문서가 명시하면 인덱스에서 연결된 그 표를 실제로 읽고 대조합니다. 역사적 버전 경계와 예외를 이 룰에 요약해 두지 않습니다. 5. 필요한 스타일 패키지가 없거나 공식 범위를 벗어나면 `fail`, 계약 문서·설치본을 읽지 못하면 `not-verified`입니다. 다른 플랫폼의 표로 빈칸을 채우지 않습니다. ## 중복 경계 - npm 최신과의 격차는 [outdated-version](./outdated-version.md)만 판단합니다. - 설치 스니펫의 요구 범위는 [snippet-compatibility](./snippet-compatibility.md)만 판단합니다. ## 문서 풀에서 사용할 근거 - 선택된 플랫폼 인덱스가 현재 연결한 설치·업그레이드·호환 문서 - 대상의 실제 설치본 package metadata ``` ### project-setup.md ```md # Project Setup 앱이 선택된 플랫폼의 현재 공식 설치·스타일 계약을 실제로 연결했는지 판정합니다. category: `setup`. 확인된 필수 연결 누락은 `error`입니다. ## 적용 조건 `meta.projectKinds`에 `app`이 있을 때 적용합니다. 플랫폼 인덱스를 정상적으로 읽었는데 앱 설치 계약 문서가 없으면 `not-applicable`, 인덱스나 연결 문서를 읽지 못하면 `not-verified`입니다. ## 판정 방법 1. 플랫폼 인덱스에서 installation·styling·theming·feature flags처럼 현재 프로젝트 방식과 관련된 문서를 찾습니다. 제목을 고정 목록으로 매칭하지 말고 설명과 문서 내용을 함께 봅니다. 2. package.json, 앱 entry, 전역 스타일, TypeScript 설정, 번들러 설정에서 실제로 채택한 설치 방식을 확정합니다. 3. 선택한 방식에 해당하는 문서의 필수 단계를 실행 시점에 추출해 하나씩 대조합니다. 플러그인 이름·CSS import·테마 속성·feature flag 값을 이 룰에 복사하지 않습니다. 4. 여러 공식 설치 방식 중 하나가 완성돼 있으면 통과입니다. 한 방식을 택한 프로젝트에 다른 방식의 요구사항을 합쳐 적용하지 않습니다. 5. 앱 entry나 실제 빌드 경로를 확정할 수 없으면 실패로 바꾸지 않고 `not-verified`로 남깁니다. ## 중복 경계 설정 파일 자체의 schema와 경로 충돌은 `project-config`, 패키지 버전 조합은 `package-compatibility`가 판단합니다. ## 문서 풀에서 사용할 근거 - 선택된 플랫폼 인덱스가 현재 연결한 설치·스타일 문서 ``` ### snippet-compatibility.md ```md # Snippet Compatibility 설치된 스니펫의 요구 범위와 현재 패키지 버전이 맞는지 현재 공식 CLI의 호환 검사 결과로 판정합니다. category: `compatibility`. 확인된 비호환은 `error`입니다. ## 적용 조건 유효한 snippet path 아래에 `@file` 헤더가 있는 설치 스니펫이 있을 때 적용합니다. 설정·스니펫이 없으면 `not-applicable`, 헤더가 없어 설치 항목을 식별할 수 없으면 `not-verified`입니다. ## 판정 방법 1. 전체·플랫폼 인덱스에서 현재 CLI 또는 Commands 문서를 찾아 호환 검사 명령과 옵션을 읽습니다. 명령 형식과 framework flag를 이 룰에 고정하지 않습니다. 2. 대상 lockfile로 패키지 매니저를 판별하고 그 프로젝트의 실행기를 사용합니다. 3. 문서가 현재 선택된 플랫폼을 지원한다고 명시한 방식으로 읽기 전용 호환 검사를 실행합니다. 4. 명령이 검사한 항목·출력·종료 코드를 evidence로 보존해 pass/fail을 정합니다. 네트워크·실행기·registry 접근 문제는 `not-verified`입니다. 호환 검사는 읽기 전용으로만 실행합니다. 패키지 설치, snippet add·upgrade 같은 변경 명령은 실행하지 않습니다. ## 중복 경계 - 최신 registry와 설치 세대의 차이는 [snippet-generation](./snippet-generation.md)만 판단합니다. - 구현·스타일 패키지끼리의 호환은 [package-compatibility](./package-compatibility.md)만 판단합니다. ## 문서 풀에서 사용할 근거 - 전체·플랫폼 인덱스가 연결하거나 현재 플랫폼 지원을 명시한 CLI 문서 ``` ### foundation-contract.md ```md # Foundation Contract 선택된 플랫폼의 토큰·스타일 API가 현재 공개 계약 안에서 사용되는지 판정합니다. category: `foundations`. ## 적용 조건 SEED 토큰 import, vars 접근, SEED CSS 변수 또는 스타일 패키지 import가 코드에 있을 때 적용합니다. 대상이 없으면 `not-applicable`입니다. ## 판정 방법 1. 전체 인덱스의 Foundations 진입점과 선택된 플랫폼 인덱스에서 관련 문서를 찾습니다. 2. 선택된 플랫폼의 설치본 package exports, 타입 선언, 생성된 공개 변수 목록을 읽습니다. 3. 코드의 import path·vars 접근·CSS 변수 이름이 현재 설치본에 존재하고 공식 문서 또는 package exports에서 공개됐는지 확인합니다. 해석되지 않는 사용은 `error`입니다. 4. 존재하더라도 문서·exports가 공개하지 않은 component 전용 변수나 내부 경로 의존은 `warn`입니다. 특정 예외 경로나 변수 이름을 이 룰에 유지하지 않고 현재 exports와 문서로 판단합니다. 5. deprecated·제거 예정 토큰은 현재 공식 deprecation 출처가 있을 때 [no-deprecated-component](./no-deprecated-component.md)가 소유합니다. 다른 플랫폼의 토큰 표기나 exports를 이식하지 않습니다. `--seed-` 같은 접두사만으로 공개·내부를 추측하지 않습니다. ## 하지 않는 판단 - 하드코딩 값이 나쁜지 - semantic token 선택이 디자인 맥락에 적절한지 - 토큰 값 자체가 화면 의도에 맞는지 Doctor는 존재·공개성·제거·내부 API 의존 같은 계약 위반만 판정합니다. ## 문서 풀에서 사용할 근거 - 전체 인덱스가 연결한 Foundations 인덱스 - 선택된 플랫폼 인덱스가 연결한 스타일·토큰 문서 - 대상의 실제 설치본 package exports ``` ### library-authors.md ```md # Library Authors 소비 가능한 패키지가 선택된 플랫폼의 현재 공식 라이브러리 저자 계약에 맞게 배포되는지 판정합니다. category: `library`. 확인된 배포 위험은 `warn`입니다. ## 적용 조건 `meta.projectKinds`에 `library`가 있을 때 플랫폼 인덱스에서 Library Authors 또는 같은 역할의 공식 배포 계약 문서를 찾습니다. 인덱스를 정상적으로 읽었는데 해당 계약이 없으면 `not-applicable`, 인덱스나 연결 문서를 읽지 못하면 `not-verified`입니다. 다른 플랫폼의 저자 정책을 이식하지 않습니다. 소비 가능 여부는 `private`나 npm 공개 여부만으로 판단하지 않습니다. package entry와 library build·publish artifact 증거를 함께 봅니다. ## 판정 방법 1. 발견한 저자 문서에서 peerDependencies, 지원 범위, bundler external, CSS 소유권, 소비자 설치·배포 문서에 관한 현재 요구사항을 추출합니다. 2. package.json의 runtime·peer·dev 의존성 역할과 문서가 요구한 범위를 대조합니다. 3. 실제 library 빌드 설정과 기존 dist에서 external이 유지되고 구현·스타일 코드가 중복 번들되지 않는지 확인합니다. Doctor가 새 빌드를 만들지는 않습니다. 4. 소스의 전역 CSS import와 README·배포 문서를 현재 저자 문서의 소비자 책임 계약에 맞춰 검사합니다. 5. 공식 문서가 요구하지 않은 범위 표기나 전환 전략을 기억으로 추가하지 않습니다. 여러 세대를 지원한다고 선언한 경우 실제 검증 증거가 있는지만 확인합니다. 6. 내부 스타일 API 의존은 [foundation-contract](./foundation-contract.md)가 소유합니다. ## 수정 방법 발견한 공식 저자 문서가 요구하는 순서와 용어로 수정안을 안내합니다. peer 이동처럼 소비자 설치 동작을 바꾸는 조치는 자동 수정하지 않습니다. ## 문서 풀에서 사용할 근거 - 선택된 플랫폼 인덱스가 현재 연결한 라이브러리 저자·배포 문서 ``` ### outdated-version.md ```md # Outdated Version 직접 설치한 `@seed-design/*` 패키지와 registry 최신 버전의 격차를 판정합니다. category: `compatibility`. 이 룰은 최신성만 보고 실제 패키지 조합의 호환 여부는 판단하지 않습니다. ## 적용 조건 워크스페이스가 `@seed-design/*` 패키지를 직접 선언하고, 선택된 플랫폼 인덱스가 현재 업그레이드·changelog 경로를 제공할 때 적용합니다. 인덱스에 공식 업그레이드 경로가 없으면 `not-applicable`, 인덱스나 registry를 읽지 못하면 `not-verified`입니다. ## 판정 방법 1. 워크스페이스가 직접 선언한 플랫폼 관련 패키지만 수집합니다. 전이 의존성은 제외합니다. 2. 선언 범위가 아니라 hoist를 고려한 실제 설치본 `package.json`의 버전을 읽습니다. 3. 대상 패키지 매니저의 registry 조회 또는 npm registry API로 각 패키지의 최신 버전을 읽습니다. 패키지 경로나 최신 버전을 다른 패키지에서 유추하지 않습니다. 4. 버전 격차는 `info`로 기록합니다. 실제 호환 오류는 [package-compatibility](./package-compatibility.md)가 별도로 판정합니다. 5. 업그레이드 영향은 플랫폼 인덱스가 현재 연결한 upgrade·changelog 문서를 읽어 안내합니다. SemVer 경계나 마이그레이션 순서를 이 룰에 복사하지 않습니다. 패키지가 여러 개면 같은 원인과 조치로 사라지는 최신성 격차를 한 finding과 `files[]`로 묶을 수 있습니다. ## 문서 풀에서 사용할 근거 - 선택된 플랫폼 인덱스가 현재 연결한 upgrade·changelog 문서 - 대상 package registry metadata ``` ### snippet-generation.md ```md # Snippet Generation 설치된 스니펫이 현재 canonical registry와 같은 세대의 요구 범위를 갖는지 판정합니다. category: `compatibility`. 세대 격차는 `info`입니다. ## 적용 조건 유효한 snippet path 아래에 설치 스니펫이 있고, 현재 CLI·registry 문서가 설치 세대와 canonical registry를 대조할 근거를 제공할 때 적용합니다. 설정·스니펫·세대 근거 중 하나가 없으면 `not-applicable`, 필요한 문서나 registry를 읽지 못하면 `not-verified`입니다. ## 판정 방법 1. snippet root에서 파일 헤더의 `@file`과 `@requires`를 수집합니다. 2. 선택된 플랫폼의 현재 registry 전체 인덱스에서 같은 `(registryId, itemId, snippetPath)`의 canonical dependencies를 찾습니다. 3. 현재 공식 CLI·registry 문서가 설치 세대 registry를 제공하면 같은 키로 요구 범위를 비교합니다. 세대 URL이나 지원 버전 목록을 이 룰에 복사하지 않습니다. 4. `@file` 헤더가 없거나 세대 원본을 식별할 수 없으면 경로로 추측하지 않고 `not-verified`로 남깁니다. 5. 로컬 코드 해시 차이는 변환·커스터마이징과 구별할 수 없으므로 이 룰에서 판정하지 않습니다. 현재 설치 패키지와 스니펫의 실제 호환은 [snippet-compatibility](./snippet-compatibility.md)가 소유합니다. 스니펫 전건이 같은 이유로 뒤졌다면 한 finding과 `files[]`로 묶습니다. ## 수정 방법 전체·플랫폼 인덱스에서 현재 CLI 문서를 찾아 그 문서가 안내하는 backup·diff 보존 방식으로 재설치를 제안합니다. 명령과 옵션을 이 룰에 고정하지 않습니다. ## 문서 풀에서 사용할 근거 - 전체·플랫폼 인덱스가 현재 연결한 CLI·registry·upgrade 문서 ``` ### no-deprecated-component.md ```md # No Deprecated Component 공식 문서·registry가 현재 deprecated로 표시한 컴포넌트·스니펫·토큰·옵션 사용을 판정합니다. category: `components`. severity: `warn`. ## 적용 조건 전체·플랫폼 인덱스 또는 선택된 플랫폼 registry에서 현재 유효한 deprecation 출처와 대상 버전을 확인할 수 있을 때 적용합니다. 인덱스를 정상적으로 읽었는데 출처가 없으면 `not-applicable`, 인덱스·연결 문서·registry를 읽지 못하면 `not-verified`입니다. 다른 플랫폼의 목록을 이식하지 않습니다. ## 판정 방법 1. 전체 인덱스가 연결한 Design Guidelines·migration 문서와 플랫폼 인덱스에서 현재 deprecation 문서를 찾습니다. 2. 컴포넌트 자체는 선택된 플랫폼 registry의 `deprecated` metadata를 함께 확인합니다. 대체안은 인덱스가 연결한 문서에 명시된 경우에만 사용합니다. 3. 토큰·스타일 API는 스타일 패키지 설치본, 컴포넌트·옵션은 구현 패키지 설치본과 문서가 말하는 적용 버전을 각각 대조합니다. 4. 패키지 import, 설치 스니펫, 대상 워크스페이스 코드의 토큰·옵션 사용을 검사합니다. 스니펫 내부가 패키지를 감싸는 정상 사용은 중복 finding으로 만들지 않습니다. 5. 문서가 제거 완료 이력을 제공하면 대상 설치본이 그 경계를 아직 지나지 않았을 때만 업그레이드 위험으로 판정합니다. 현재 항목·버전·대체안 목록을 이 룰에 복사하지 않습니다. 토큰은 문서 표기, 코드 API 표기, CSS 변수 표기가 다를 수 있으므로 현재 Foundations 문서와 설치본 선언에서 변환 관계를 확인합니다. 존재하지 않는 토큰과 내부 스타일 API는 [foundation-contract](./foundation-contract.md)가 소유합니다. ## 수정 방법 이번 실행에서 읽은 공식 문서의 대체안과 제거 시점을 그대로 안내합니다. 대체안이 없으면 임의의 컴포넌트나 토큰을 만들지 않고 추적해야 할 문서와 버전 경계만 남깁니다. 재설치 명령이 필요하면 현재 CLI 문서에서 찾아 제시합니다. ## 문서 풀에서 사용할 근거 - 전체·플랫폼 인덱스가 현재 연결한 deprecation·upgrade 문서 - 선택된 플랫폼의 현재 registry metadata ``` ### component-guidelines.md ```md # Component Guidelines 컴포넌트 사용이 현재 공통 디자인 가이드라인에 맞는지 판정합니다. category: `components`. 기본 severity는 `warn`, 실제 동작이 깨지는 위반은 `error`, 교체 기회는 `info`입니다. 판정 기준과 플랫폼 지원 목록은 이 파일에 두지 않습니다. 실행할 때 전체 문서 인덱스가 연결한 Components 인덱스와 개별 문서에서 도출합니다. ## 적용 조건 현재 Components 인덱스에 가이드라인 문서가 있고, 코드에서 그 컴포넌트를 사용하거나 같은 역할을 직접 구현한 증거가 있을 때 컴포넌트별로 적용합니다. 공통 문서와 선택된 플랫폼 구현을 연결할 수 없으면 다른 플랫폼 자료로 대체하지 않고 `not-applicable`로 남깁니다. ## 문서·구현 연결 1. 문서 풀의 전체 인덱스에서 현재 Components 진입점을 찾습니다. 2. Components 인덱스에서 컴포넌트 문서를 찾고, 인덱스가 제공한 raw URL을 읽습니다. 3. 공통 문서의 Platform 표 → 문서 풀의 플랫폼 인덱스 → 플랫폼 registry 전체 인덱스 → 재export를 따라간 설치본 package exports 순으로 실제 구현·registry id를 찾습니다. 4. id 매핑과 지원 컴포넌트 목록을 룰이나 프로필에 유지하지 않습니다. 빈 문서·낡은 링크·문서 충돌은 `doc-conflict` 근거로 남깁니다. ## 대상 선정 - 패키지·스니펫 import와 컴포넌트 식별자를 후보로 모읍니다. 여러 이름이 겹치면 가장 구체적인 식별자를 우선하고 하위 파츠는 소유 컴포넌트로 판정합니다. - 파일명만 믿지 않고 스니펫의 `@file` metadata, 공통 Platform 표, 플랫폼 인덱스를 함께 사용합니다. - SEED와 같은 역할을 직접 구현한 코드도 포함합니다. 이름이 아니라 렌더되는 UI 역할로 확인하며, 전수 확인하지 못했다면 실제로 본 범위를 보고합니다. - 재구현을 지적하기 전에 대상 설치본 package exports와 해당 세대 registry를 확인합니다. 현재 공식 문서가 세대 registry를 제공하지 않으면 최신 registry로 과거 설치본을 추측하지 않고 확인 한계를 evidence에 남깁니다. - 연결 실패와 아이템 부재를 구분합니다. registry에 없다는 이유만으로 package export도 없다고 판단하지 않습니다. 설치본과 최신 제공 여부에 따른 판정은 다음 원칙만 유지합니다. - 설치본과 현재 공식 제공처 모두 없음: finding 없음 - 설치본에는 없고 현재 공식 제공처에는 있음: 교체 기회 `info` - 설치본에 이미 같은 역할의 구현이 있음: 재구현 `warn` 역할이 다르거나 증거가 부족한 후보는 `rejected`에 이유를 남깁니다. ## 판정 기준 도출 가이드라인 문서를 raw로 읽고 기계 수집과 판단 보충을 분리합니다. ### 1단계: 기계 수집 1. 문서 전체의 Do/Don't `body="…"` 속성을 수집하되 주석 처리된 블록은 제외합니다. 2. Guidelines 또는 Usage 절의 볼드 문장 중 문장형 규칙을 수집합니다. 3. 문서 등장 순서대로 `{docId}.dont-N`, `{docId}.do-N`, `{docId}.rule-N` id를 붙입니다. 4. 수집한 항목 전부를 `verdicts`에 남기고 개수를 `coverage.expected`로 기록합니다. 0건도 정상입니다. 기계 수집 항목이 허용문·라벨·예시 해설이면 `pass`와 그 이유를 기록하고, 임계값이 없으면 `unknown: no-threshold`로 남깁니다. 후보를 임의로 버려 coverage를 줄이지 않습니다. ### 2단계: 판단 보충 문서의 Guidelines·Usage·Properties에서 위반이 성립하는 명시적 규범을 추가로 도출합니다. 허용문과 Figma 전용 팁은 제외하고, 도출 개수를 `coverage.derived`로 기록합니다. ## verdict 규칙 - 코드와 문서로 충족을 확인하면 `pass`, 위반을 확인하면 `fail`입니다. - 문서에 임계값이 없으면 `unknown: no-threshold`입니다. - 런타임 데이터에 따라 달라지면 `unknown: runtime-dependent`, 코드 밖 정보면 `unknown: not-in-code`입니다. - 공식 문서끼리 충돌하거나 두 가지로 읽히면 `unknown: doc-conflict`입니다. - 문서·도구 접근 실패는 `not-verified`입니다. - 조건이 성립하지 않음을 코드로 확인하면 `pass`지만, 조건이 성립할 때 구조적으로 지킬 방법이 없으면 `fail`입니다. `coverage.expected != coverage.judged`면 실행 결함입니다. 같은 기준의 공유 원인과 조치가 하나면 finding 하나와 `files[]`로 묶습니다. ## 중복 경계 deprecated 대상은 [no-deprecated-component](./no-deprecated-component.md), 패키지 호환은 [package-compatibility](./package-compatibility.md), 토큰 공개성은 [foundation-contract](./foundation-contract.md)가 소유합니다. ## 문서 풀에서 사용할 근거 - 전체 인덱스가 현재 연결한 Components 인덱스와 개별 가이드라인 - 선택된 플랫폼 인덱스가 현재 연결한 구현 문서 - 선택된 플랫폼의 registry와 대상 설치본 package exports ``` ## 결과 형식 YAML은 진단 결과의 단일 원천입니다. 채팅 요약과 기본으로 함께 만드는 HTML 리포트는 이 파일에서 파생됩니다. 예시의 `{...LeafUrlResolvedFromIndex}`는 실행 시 선택한 플랫폼 인덱스에서 찾은 실제 leaf URL로 바꿉니다. ```yaml schemaVersion: 2 meta: target: /path/to/project workspace: packages/ui framework: react projectKinds: [app, library] date: "2026-08-16" seed: installed: { "@seed-design/react": 2.3.0, "@seed-design/css": 2.5.0 } summary: { error: 0, warn: 1, info: 0 } checks: - rule: seed/project-config category: config status: pass evidence: framework·path와 TypeScript alias가 일치함 references: - https://seed-design.io/react/llms.txt - "{configurationLeafUrlResolvedFromIndex}" - rule: seed/library-authors category: library status: fail evidence: 소비 진입점이 있지만 @seed-design/react가 dependencies에 있음 references: - https://seed-design.io/react/llms.txt - "{libraryAuthorsLeafUrlResolvedFromIndex}" - rule: seed/snippet-generation category: compatibility status: not-applicable reason: 설치 스니펫이 없음 references: - https://seed-design.io/react/llms.txt findings: - rule: seed/library-authors severity: warn message: 소비 가능한 패키지가 @seed-design/react를 dependencies에 선언합니다. file: packages/ui/package.json references: - https://seed-design.io/react/llms.txt - "{libraryAuthorsLeafUrlResolvedFromIndex}" remediation: |- 다음 SEED Doctor finding을 수정해 주세요. 대상 프로젝트: /path/to/project 대상 파일: packages/ui/package.json 문제: 소비 가능한 패키지가 @seed-design/react를 dependencies에 선언합니다. 요구사항: - 공식 Library Authors 문서에서 현재 설치본과 호환되는 peer 범위를 확인해 @seed-design/react 선언을 옮겨 주세요. - 번들러 external 설정과 소비자의 CSS import 계약도 같은 문서 기준으로 맞춰 주세요. - 공개 API와 관련 없는 파일은 변경하지 마세요. 근거: - https://seed-design.io/react/llms.txt - {libraryAuthorsLeafUrlResolvedFromIndex} 먼저 저장소의 AGENTS.md와 package scripts를 확인하세요. 수정 후 package scripts에서 변경 범위에 맞는 검증을 선택해 실행하고 결과를 알려 주세요. verdicts: [] coverage: [] rejected: [] ``` ### 필드 | 키 | 무엇 | 왜 | | ------------------- | ---------------------- | ---------------------------------------------- | | `meta.projectKinds` | `app`·`library` 역할 배열 | 역할이 비배타적이며, 역할 증거가 없으면 빈 배열일 수 있습니다 | | `checks` | 요청 범위의 모든 룰 상태 | pass/fail뿐 아니라 적용 제외·미검증 이유까지 실제 검사 범위를 보여 줍니다 | | `summary` | findings의 severity별 개수 | 점수나 등급을 만들지 않습니다 | | `findings` | 고칠 것만 | 공식 근거와 복사 가능한 수정 프롬프트를 함께 둡니다 | | `verdicts` | 컴포넌트 기준별 판정 전체 | 통과와 `unknown`·`not-verified`를 숨기지 않습니다 | | `coverage` | 기계 수집 기준과 실제 판정 수 | component-guidelines의 기준 건너뛰기를 드러냅니다 | | `rejected` | 검토했지만 기각한 후보 | 보지 않은 것과 보고 뺀 것을 구분합니다 | check status는 `pass | fail | not-applicable | not-verified`, category는 `config | compatibility | setup | foundations | components | library`입니다. `pass`·`fail`에는 `evidence`, 적용 제외·미검증에는 `reason`, 모든 check에는 공식 `references`가 필요합니다. 각 `check.rule`은 리포트 안에서 유일하고, finding은 같은 rule의 `fail` check에서만 나와야 합니다. JSON Schema 구조 검증과 별개로, 저장 전에 모든 finding에 실패 check가 있는지·모든 실패 check에 finding이 있는지·`summary`와 `coverage`가 일치하는지를 의미 검증합니다. `verdicts.unknownReason`은 문서 임계값 부재(`no-threshold`), 런타임 의존(`runtime-dependent`), 코드 밖 정보(`not-in-code`), 공식 문서 충돌(`doc-conflict`)을 구분합니다. `rejected`에는 실제로 검토했지만 공식 기준이 허용하거나 증거가 부족해 뺀 후보만 적습니다. `findings[].remediation`은 설명문이 아니라 해당 finding만 별도 수정 요청으로 전달할 수 있는 완결된 프롬프트입니다. 대상 프로젝트와 파일, 확인된 문제, 구체적인 요구사항, 변경 제약, 공식 근거 전체, 저장소 지침과 package scripts를 확인한 뒤 적절한 검증을 실행하라는 요청을 포함합니다. Doctor는 프롬프트를 생성만 하며 사용자가 실제 수정을 요청하기 전에는 실행하지 않습니다. ### 스키마 ```json { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://seed-design.io/schemas/doctor-report.json", "title": "SEED Doctor Report", "description": "SEED 사용 상태 진단의 결과. 채팅 요약과 HTML 리포트는 이 파일에서 파생되므로, 이것이 단일 소스다. JSON Schema가 표현할 수 없는 배열 간 rule 관계는 생성 단계에서 의미 검증한다.", "type": "object", "required": ["schemaVersion", "meta", "summary", "checks", "findings", "verdicts", "rejected"], "additionalProperties": true, "properties": { "schemaVersion": { "description": "필드가 깨지는 변경에만 올린다.", "const": 2 }, "meta": { "type": "object", "required": ["target", "framework", "projectKinds", "date"], "additionalProperties": true, "properties": { "target": { "type": "string", "description": "진단 대상 프로젝트 경로" }, "workspace": { "type": "string", "description": "모노레포일 때 SEED를 쓰는 워크스페이스. 단일 패키지면 생략." }, "framework": { "enum": ["react", "lynx"] }, "projectKinds": { "type": "array", "description": "프로젝트 역할. 앱이면서 소비 가능한 라이브러리일 수 있으므로 비배타적이다.", "uniqueItems": true, "items": { "enum": ["app", "library"] } }, "date": { "type": "string", "description": "YYYY-MM-DD" }, "seed": { "type": "object", "description": "사실 수집 결과. 판정의 근거이자 재현에 필요한 상태.", "additionalProperties": true, "properties": { "installed": { "type": "object", "description": "선언 범위가 아니라 실제 설치본", "additionalProperties": { "type": "string" } }, "latest": { "type": "object", "additionalProperties": { "type": "string" } }, "snippetRoot": { "type": "string" } } } } }, "summary": { "type": "object", "description": "findings의 severity별 개수. 손으로 세지 말고 findings에서 계산한다. 점수나 등급은 두지 않는다.", "required": ["error", "warn", "info"], "additionalProperties": false, "properties": { "error": { "type": "integer", "minimum": 0 }, "warn": { "type": "integer", "minimum": 0 }, "info": { "type": "integer", "minimum": 0 } } }, "checks": { "type": "array", "minItems": 1, "description": "이번 실행에서 요청 범위에 들어온 룰 전체. 적용되지 않거나 검증하지 못한 룰도 이유와 함께 남겨 실제 검사 범위를 드러낸다. rule은 리포트 안에서 유일해야 하며 fail check만 같은 rule의 findings를 가진다.", "items": { "type": "object", "required": ["rule", "category", "status", "references"], "additionalProperties": true, "properties": { "rule": { "type": "string", "description": "네임스페이스를 포함한 룰 id. 예: seed/project-config" }, "category": { "enum": ["config", "compatibility", "setup", "foundations", "components", "library"] }, "status": { "enum": ["pass", "fail", "not-applicable", "not-verified"] }, "evidence": { "type": "string", "minLength": 1, "description": "pass/fail 판정의 대상과 근거. 파일:줄, 설치본 버전, 실행 결과 등을 적는다." }, "reason": { "type": "string", "minLength": 1, "description": "not-applicable/not-verified인 이유. 적용 조건 불충족과 검증 실패를 구분한다." }, "references": { "type": "array", "description": "판정 또는 적용 제외의 근거가 된 공식 문서 URL.", "minItems": 1, "items": { "type": "string" } } }, "allOf": [ { "if": { "properties": { "status": { "enum": ["pass", "fail"] } }, "required": ["status"] }, "then": { "required": ["evidence"] } }, { "if": { "properties": { "status": { "enum": ["not-applicable", "not-verified"] } }, "required": ["status"] }, "then": { "required": ["reason"] } } ] } }, "findings": { "type": "array", "description": "고칠 것. 생성 단계에서 같은 rule의 checks.status가 fail임을 의미 검증한 항목만 들어온다. 모든 fail check는 적어도 하나의 finding을 갖고, 다른 상태의 check는 finding을 갖지 않는다.", "items": { "type": "object", "required": ["rule", "severity", "message", "file", "references", "remediation"], "additionalProperties": true, "properties": { "rule": { "type": "string", "description": "네임스페이스 포함 룰 id. 예: seed/component-guidelines/bottom-sheet" }, "severity": { "enum": ["error", "warn", "info"] }, "message": { "type": "string", "description": "위반 내용 한 문장" }, "file": { "type": "string", "description": "target 기준 상대 경로. 대상 파일이 아니라 실제로 고쳐야 할 위치. 원인이 하나여서 여러 파일을 한 건으로 묶었으면 대표 파일이나 그 파일들을 담은 디렉토리를 적고, 전체 목록은 files에 둔다." }, "files": { "type": "array", "description": "한 건으로 묶인 파일 전체. 원인이 하나이고 조치도 한 번일 때만 쓴다(패키지가 뒤져 스니펫이 전건 구세대인 경우 등).", "items": { "type": "string" } }, "line": { "type": "integer", "minimum": 1 }, "criterion": { "type": "string", "description": "2단계(판단 보충) 기준 번호. verdicts의 같은 값과 이어진다. 여러 기준을 묶었으면 콤마로 나열한다. 예: \"1,4,8\"" }, "criterionIds": { "type": "array", "description": "1단계(기계 수집) 기준에서 나온 finding이면 그 id들. verdicts의 criterionId와 이어진다. criterion에 id 문자열을 섞어 넣지 않는다 — 그쪽은 번호용이다.", "items": { "type": "string" } }, "references": { "type": "array", "description": "판정 근거가 된 문서 URL. 필수다 — 무엇을 읽어야 하는지가 빠지면 사용자는 고칠 방법을 찾지 못한다. 리포트에도 접지 않고 노출한다.", "minItems": 1, "items": { "type": "string" } }, "remediation": { "type": "string", "minLength": 1, "description": "finding 하나를 별도 수정 요청으로 전달할 수 있는 완결된 프롬프트. 대상 프로젝트와 파일, 문제, 구체적인 수정 요구사항, 관련 없는 변경을 피하는 제약, references 전체, 저장소 지침과 package scripts를 확인한 뒤 변경 범위에 맞게 검증하라는 요청을 포함한다. Doctor는 이 프롬프트를 생성할 뿐 실행하지 않는다." } } } }, "verdicts": { "type": "array", "description": "판정 표 전체. 통과한 것과 판정하지 못한 것을 숨기지 않는다 — 무엇을 근거로 통과했는지가 결과의 신뢰도다.", "items": { "type": "object", "required": ["rule", "verdict"], "additionalProperties": true, "properties": { "rule": { "type": "string" }, "criterionId": { "type": "string", "description": "1단계(기계 수집) 기준이면 그 id. 예: bottom-sheet.dont-1. 문서 등장 순서로 붙으므로 실행이 달라도 같은 기준은 같은 id다 — 실행 간 비교가 이것으로 된다. 2단계(판단 보충) 기준에는 없다." }, "criterion": { "type": "string", "description": "기준 번호. 같은 이유로 묶인 항목들은 콤마로 나열한다. 예: \"1,4,8\"" }, "text": { "type": "string", "description": "문서에서 도출한 기준 문장 그대로. 도출한 절도 함께." }, "verdict": { "description": "not-verified는 도구에 접근하지 못한 것(네트워크 차단 등)이고, unknown은 접근은 됐으나 판정할 수 없는 것이다. 코드 경로를 끝까지 추적했으면 확인한 것이며, 앱을 실행해볼 것을 요구하지 않는다.", "enum": ["pass", "fail", "unknown", "not-verified"] }, "unknownReason": { "description": "verdict가 unknown일 때 왜인지. doc-conflict는 SEED 문서 자체의 결함이라 조치 주체가 다르다 — 나머지 셋은 진단 대상 프로젝트의 사정이지만 이것은 SEED가 문서를 고쳐야 한다.", "enum": ["no-threshold", "runtime-dependent", "not-in-code", "doc-conflict"] }, "scope": { "type": "string", "description": "여러 기준을 한 행으로 묶었을 때 그 묶음이 성립하는 이유. 예: \"자체 구현에 사용처가 0개라 조건이 성립하지 않음\". 표를 읽는 사람이 왜 한 줄로 뭉쳐 있는지 알 수 있어야 한다." }, "evidence": { "type": "string", "description": "파일:줄, 또는 판정하지 못한 이유. 대상이 0개여서 통과했으면 그 사실." } } } }, "coverage": { "type": "array", "description": "component-guidelines를 판정한 컴포넌트마다 한 항목. expected(1단계 기계 수집 개수) ≠ judged(verdicts에 실제 나온 1단계 기준 수)면 기준을 건너뛴 실행이다 — 그 자체가 결함이다.", "items": { "type": "object", "required": ["rule", "expected", "judged"], "additionalProperties": true, "properties": { "rule": { "type": "string" }, "expected": { "type": "integer", "minimum": 0 }, "judged": { "type": "integer", "minimum": 0 }, "derived": { "type": "integer", "minimum": 0, "description": "2단계(판단 보충)로 얹은 기준 수" } } } }, "rejected": { "type": "array", "description": "위반으로 올릴까 하다 뺀 후보. 실제로 살펴본 것만 적고 칸을 채우려고 지어내지 않는다.", "items": { "type": "object", "required": ["candidate", "reason"], "additionalProperties": true, "properties": { "candidate": { "type": "string" }, "reason": { "type": "string" }, "file": { "type": "string" } } } } } } ``` ## HTML 리포트 HTML은 검증된 YAML과 같은 임시 디렉토리에 기본으로 만듭니다. 사용자가 "YAML만"을 요청한 경우에만 생략합니다. "먼저 할 것" 다음에 프로젝트 역할·범주별 검사 범위·coverage를 보여 주고, `not-applicable`·`not-verified` 이유를 접어서 볼 수 있습니다. finding마다 공식 근거와 접어 둔 "수정 프롬프트"를 제공하며, 판정 표에는 `pass | fail | unknown | not-verified` 실제 상태와 근거를 보존합니다. 외부 CDN·JavaScript 없이 한 파일로 열립니다. ## Doctor references ### doctor.md ````md # 사용 상태 진단 (Doctor) 프로젝트가 SEED를 쓰는 맥락을 먼저 찾고, 그 맥락에 적용되는 건강검진을 선택 실행하는 공통 절차입니다. 컴포넌트뿐 아니라 설정·패키지 호환·앱 셋업·Foundations 계약·라이브러리 배포 계약까지 봅니다. Doctor는 Markdown 기반 Skill입니다. 별도 실행 스크립트나 Quick/Deep 모드는 두지 않습니다. 일반 요청은 적용 가능한 룰 전체를, 범주가 지정된 요청은 그 범주만 실행합니다. ## 문서 단일 원천 진단을 시작할 때 `https://seed-design.io/llms.txt`와 선택된 플랫폼 인덱스([React](https://seed-design.io/react/llms.txt) 또는 [Lynx](https://seed-design.io/lynx/llms.txt))를 읽습니다. 지원 범위·leaf 문서 목록·컴포넌트 id 매핑을 이 파일이나 플랫폼 프로필에 유지하지 않습니다. 플랫폼 프로필은 인덱스·패키지·registry namespace의 시작점만 제공합니다. 현재 capability는 인덱스가 연결한 문서와 설치본 package metadata로 실행 시점에 판단합니다. 문서가 새로 생기거나 사라지면 스킬을 수정하지 않고 다음 진단부터 그 인덱스 상태를 따릅니다. ### 실행 문서 풀 - Doctor 요청 하나에 문서 풀 하나를 만들고, 인덱스가 제공한 절대 URL에서 fragment를 제외한 값을 key로 사용합니다. - 전체 인덱스와 선택된 플랫폼 인덱스는 실행당 URL마다 한 번만 읽습니다. 같은 실행의 여러 workspace와 rule이 공유합니다. - leaf 문서도 처음 필요한 때 한 번만 읽고 이후 rule은 저장한 내용을 재사용합니다. rule 파일의 "문서 풀에서 사용할 근거"는 새 fetch 명령이 아닙니다. - 리포트의 `references`는 근거의 provenance입니다. 같은 URL이 여러 check·finding에 있어도 다시 읽지 않습니다. - HTTP·도구 캐시는 보장으로 간주하지 않습니다. 하위 에이전트가 문서 내용을 전달받지 못했다면 그 하위 실행 안에서만 동일한 중복 제거를 다시 적용합니다. ## 원칙 - **read-only**: 대상 프로젝트의 코드·설정·의존성·산출물을 만들거나 바꾸지 않습니다. `compat`처럼 읽기 전용 명령만 실행합니다. - **근거 우선**: 전체·플랫폼 인덱스에서 이번 실행에 발견한 공식 문서, 설치본 package metadata, 실제 코드의 파일:줄을 근거로 씁니다. - **검증 공백 보존**: 확인하지 못한 것을 pass나 fail로 바꾸지 않습니다. - **플랫폼 격리**: 선택된 플랫폼 문서·패키지·registry만 사용합니다. 다른 플랫폼 문서로 빈칸을 채우지 않습니다. - **계약과 디자인 판단 분리**: Foundations는 공개성·존재·제거·내부 API 의존만 판정하고 하드코딩이나 semantic token 선택의 적절성은 추론하지 않습니다. ## Step 1: 대상 워크스페이스 찾기 다음 순서를 고정합니다. 1. 사용자가 지정한 경로가 있으면 그 경로 안에서만 후보를 찾습니다. 2. 대상 아래에서 `seed-design.json`을 찾습니다. `node_modules`, `.git`, `.claude/worktrees`는 반드시 제외합니다. 3. 설정 파일 발견 여부와 관계없이 workspace manifest를 따라 `@seed-design/*` 직접 의존성이 있는 워크스페이스도 함께 찾습니다. 설정 부재만으로 SEED 미사용이라고 결론내리지 않습니다. 4. `seed-design.json`이 속한 package와 직접 의존성이 선언된 package를 같은 package 경계로 정규화해 중복 제거합니다. 같은 경계에 두 단서가 있으면 하나의 리포트 단위에 모두 유지합니다. 여러 워크스페이스가 발견되면 어느 대상을 진단할지 확인합니다. 사용자가 "전체"를 요청했다면 **워크스페이스별 YAML을 각각** 생성합니다. 서로 다른 `meta`를 가진 결과를 하나로 합치지 않습니다. ## Step 2: 플랫폼과 프로젝트 역할 확정 ### 플랫폼 워크스페이스마다 아래 우선순위를 적용합니다. 1. 사용자 명시 2. `seed-design.json.framework` 3. 직접 의존성 - React: `@seed-design/react`, `@seed-design/css` - Lynx: `@seed-design/lynx-react`, `@seed-design/lynx-css`, `@lynx-js/react` 높은 순위 단서를 낮은 순위 단서로 덮어쓰지 않습니다. 설정과 의존성이 충돌하면 선택된 플랫폼은 우선순위대로 유지하되 `project-config`가 실제 충돌을 finding으로 냅니다. 같은 순위에서 React·Lynx가 동시에 잡혀 플랫폼을 정할 수 없으면 사용자에게 확인합니다. React를 기본값으로 추측하지 않습니다. ### app·library 역할 역할은 비배타적입니다. 한 워크스페이스가 앱을 실행하면서 다른 워크스페이스에 공개 진입점을 제공할 수도 있으므로 `meta.projectKinds`에 둘 다 넣을 수 있습니다. - `app` 증거: 실제 앱 entry, dev/start 실행, 앱 framework 설정, 배포 가능한 application target - `library` 증거: `exports`·`main`·`module`·`types` 같은 소비 진입점 **그리고** library mode·tsup·rollup·publish artifact 같은 빌드/배포 증거 `private: true`나 사내 배포는 library를 배제하지 않습니다. 반대로 `build` 스크립트 하나만으로 library라 부르지 않습니다. 어느 역할도 증명되지 않으면 `projectKinds: []`로 두고 setup·library check에 적용 제외 이유를 남깁니다. ## Step 3: 인덱스·프로필 로드와 사실 수집 1. 실행 문서 풀을 만들고 전체 문서 인덱스를 한 번 읽어 넣습니다. 2. 선택된 [React 프로필](doctor-react.md) 또는 [Lynx 프로필](doctor-lynx.md)에서 플랫폼 인덱스·패키지 후보·registry namespace를 받고, 아직 문서 풀에 없는 플랫폼 인덱스만 읽습니다. 3. 문서 풀의 인덱스에서 이번 scope의 룰에 필요한 문서를 제목·category·설명으로 찾습니다. leaf URL이 문서 풀에 없을 때만 읽고, 경로를 기억하거나 조합하지 않습니다. 4. 공통 컴포넌트는 문서 풀의 전체 인덱스가 연결한 Components 문서와 각 문서의 Platform 표에서 현재 매핑을 찾습니다. 인덱스를 정상적으로 읽었는데 관련 문서가 없으면 공식 capability 부재입니다. 인덱스 또는 연결 문서를 읽지 못했으면 부재가 아니라 검증 실패입니다. 그다음 대상에서 필요한 사실만 읽습니다. 1. `seed-design.json`의 strict schema, framework, path 2. workspace `package.json`의 직접 의존성과 app/library 증거 3. hoist를 고려한 실제 설치본 package.json, peerDependencies, exports 4. snippet root의 `@file`, `@requires` 헤더 5. TypeScript paths, 번들러 alias·plugin·external, 앱 entry와 전역 CSS 6. SEED import·토큰·CSS 변수·컴포넌트 사용처와 기존 dist 증거 lockfile로 패키지 매니저를 정할 때는 대상에 가장 가까운 파일을 우선하고, 실행이 필요하면 그 매니저의 실행기를 사용합니다. ## Step 4: 검사 범위와 룰 실행 ### 범위 선택 - "SEED 잘 쓰고 있나" 같은 일반 진단: `SKILL.md`의 공통 Doctor 룰 전체를 scope에 넣습니다. - "셋업만", "라이브러리 배포 계약만" 같은 요청: 해당 category만 scope에 넣습니다. - 탐색에 config를 읽더라도 범주 지정 요청에서 config category 룰까지 자동으로 확대하지 않습니다. category는 `config | compatibility | setup | foundations | components | library`입니다. ### 룰 상태 scope에 들어온 룰마다 `checks[]`를 하나 이상 만듭니다. | status | 사용 조건 | |---|---| | `pass` | 적용 조건이 성립하고, 정적 진단을 끝냈으며 finding이 없음 | | `fail` | 적용 조건이 성립하고 finding이 하나 이상 있음 | | `not-applicable` | 역할·사용 증거가 없거나, 정상적으로 읽은 현재 인덱스에 필요한 공식 계약이 없음 | | `not-verified` | 인덱스·연결 문서·네트워크·도구·설치본·경로를 확인하지 못함 | `pass`·`fail`은 `evidence`, 적용 제외·미검증은 `reason`을 씁니다. 모든 check에는 판정 또는 적용 제외를 뒷받침하는 공식 `references`가 필요합니다. 문서를 발견한 check는 플랫폼 인덱스와 실제로 읽은 leaf 문서를 함께 기록하고, 문서 부재 check는 확인한 플랫폼 인덱스를 기록합니다. 각 `check.rule`은 리포트 안에서 유일해야 합니다. finding은 동일한 `rule`의 `fail` check가 있을 때만 만들고, 각 `fail` check에는 적어도 하나의 finding이 있어야 합니다. `pass`·`not-applicable`·`not-verified` check의 rule은 findings에 나오면 안 됩니다. [component-guidelines](../rules/component-guidelines.md)는 현재 공통 문서와 플랫폼 인덱스로 연결 가능한 컴포넌트마다 반복하고 `coverage`·`verdicts`를 채웁니다. 공식 계약을 찾지 못한 룰도 조용히 빼지 말고 해당 범주가 scope라면 `not-applicable`로 남깁니다. ### severity - `error`: 실제 패키지·스니펫 비호환, CLI를 막는 config, 앱의 필수 setup 누락, 현재 설치본에서 해석되지 않는 공개 계약 - `warn`: deprecated 사용, 내부 component vars/API, 컴포넌트 가이드라인 이탈, peer·external·CSS 소유권 같은 라이브러리 배포 위험 - `info`: 최신 세대와의 격차, minor·patch 최신성, 알아두면 되는 교체 기회 같은 원인과 같은 수정으로 사라지는 finding은 하나로 묶고 전체 파일은 `files[]`에 둡니다. 룰 간 책임 경계는 각 룰의 "중복 경계"를 따릅니다. ## Step 5: YAML 출력 결과의 단일 원천은 schema v2 YAML입니다. 스키마는 `assets/doctor-report.schema.json`입니다. 예시의 `{...LeafUrlResolvedFromIndex}`는 실행 시 선택한 플랫폼 인덱스에서 찾은 실제 leaf URL로 바꿉니다. ```yaml schemaVersion: 2 meta: target: /path/to/project workspace: packages/ui # 모노레포일 때만 framework: react projectKinds: [app, library] # 비배타적. 증거가 없으면 [] date: "2026-08-16" # string 유지를 위해 따옴표 사용 seed: installed: { "@seed-design/react": 2.3.0, "@seed-design/css": 2.5.0 } latest: { "@seed-design/react": 2.3.0, "@seed-design/css": 2.5.0 } snippetRoot: ./src/seed-design summary: { error: 0, warn: 1, info: 0 } checks: - rule: seed/project-config category: config status: pass evidence: seed-design.json의 framework·path와 alias가 일치함 references: - https://seed-design.io/react/llms.txt - "{configurationLeafUrlResolvedFromIndex}" - rule: seed/library-authors category: library status: fail evidence: package.json은 소비 진입점을 내보내지만 SEED가 dependencies에 선언됨 references: - https://seed-design.io/react/llms.txt - "{libraryAuthorsLeafUrlResolvedFromIndex}" - rule: seed/snippet-generation category: compatibility status: not-applicable reason: 설치 스니펫이 없음 references: - https://seed-design.io/react/llms.txt findings: - rule: seed/library-authors severity: warn message: 소비 가능한 패키지가 @seed-design/react를 dependencies에 선언합니다. file: packages/ui/package.json references: - https://seed-design.io/react/llms.txt - "{libraryAuthorsLeafUrlResolvedFromIndex}" remediation: |- 다음 SEED Doctor finding을 수정해 주세요. 대상 프로젝트: /path/to/project 대상 파일: packages/ui/package.json 문제: 소비 가능한 패키지가 @seed-design/react를 dependencies에 선언합니다. 요구사항: - 공식 Library Authors 문서에서 현재 설치본과 호환되는 peer 범위를 확인해 @seed-design/react 선언을 옮겨 주세요. - 번들러 external 설정과 소비자의 CSS import 계약도 같은 문서 기준으로 맞춰 주세요. - 공개 API와 관련 없는 파일은 변경하지 마세요. 근거: - https://seed-design.io/react/llms.txt - {libraryAuthorsLeafUrlResolvedFromIndex} 먼저 저장소의 AGENTS.md와 package scripts를 확인하세요. 수정 후 package scripts에서 변경 범위에 맞는 검증을 선택해 실행하고 결과를 알려 주세요. coverage: [] verdicts: [] rejected: [] ``` ### 필드 관계 - `checks`: 실제 검사 범위. 통과·실패·적용 제외·미검증을 모두 보여 줍니다. - `findings`: 고칠 것만. `checks.status: fail`인 룰에서 나옵니다. - `findings[].remediation`: finding 하나를 별도 수정 요청으로 전달할 수 있는 완결된 프롬프트입니다. Doctor가 프롬프트를 실행했다는 뜻은 아닙니다. - `summary`: findings를 severity별로 다시 센 값입니다. 손으로 추정하지 않습니다. - `verdicts`: component-guidelines의 기준별 판정 전체. `pass | fail | unknown | not-verified`를 유지합니다. - `coverage`: component-guidelines의 기계 수집 기준 수(`expected`)와 실제 판정 수(`judged`), 판단 보충 수(`derived`). `expected != judged`면 실행 결함입니다. - `rejected`: 실제 검토했지만 공식 기준이 허용하거나 증거가 부족해 finding으로 만들지 않은 후보입니다. JSON Schema는 배열 간 동적 `rule` 일치를 표현하지 못하므로, YAML을 저장하기 전에 다음 의미 검증을 별도로 수행합니다. 1. `checks[].rule`이 중복되지 않음 2. 모든 `findings[].rule`에 동일한 rule의 `fail` check가 정확히 하나 있음 3. 모든 `fail` check에 동일한 rule의 finding이 적어도 하나 있음 4. `summary`가 findings의 severity별 개수와 일치하고, 모든 `coverage`의 `expected == judged`임 하나라도 실패하면 리포트를 완료한 것으로 보고하지 말고 판정·집계를 먼저 바로잡습니다. `verdicts.unknown`은 문서 임계값 부재·런타임 의존·코드 밖 정보·문서 충돌처럼 기준별 판정이 불가능할 때 사용합니다. 룰 실행 자체의 적용 여부를 나타내는 `checks.status`와 혼동하지 않습니다. `verdicts.unknownReason`은 다음 네 값으로 이유를 보존합니다. | 값 | 뜻 | 조치 주체 | |---|---|---| | `no-threshold` | 문서가 위반 임계값을 정하지 않음 | SEED 문서 | | `runtime-dependent` | 런타임 데이터에 따라 달라짐 | 프로젝트 | | `not-in-code` | 코드만으로 확인할 수 없음 | 프로젝트 | | `doc-conflict` | 공식 문서 문장끼리 충돌하거나 두 가지로 읽힘 | SEED 문서 | component-guidelines finding은 1단계 기계 기준에서 나왔으면 `criterionIds`, 2단계 판단 기준에서 나왔으면 `criterion`으로 verdict와 연결합니다. 같은 기준의 위반이 여러 파일에 있으면 파일별로 내되, 공유 구현 하나가 원인이거나 수정 한 번으로 모두 사라지면 대표 `file` 한 건과 `files[]` 전체 목록으로 묶습니다. `rejected`는 실제로 살펴본 후보만 적습니다. 공식 문서가 허용하거나, 증거가 부족하거나, 역할이 다른 구현이거나, 의도적인 도메인 선택으로 보이는 경우에 candidate·reason·file을 남깁니다. 칸을 채우기 위해 후보를 만들지 않습니다. ### 수정 프롬프트 계약 각 finding의 `remediation`은 설명문이 아니라 그대로 복사해 코딩 에이전트에 전달할 수 있는 명령형 프롬프트로 씁니다. 하나의 프롬프트만 읽어도 수정 범위를 이해할 수 있도록 다음을 포함합니다. 1. `meta.target`과 finding의 `file`, 값이 있으면 `line` 2. finding의 `message`로 확인한 문제 3. 공식 문서에서 도출한 구체적인 수정 요구사항 4. 관련 없는 파일·공개 API·사용자 변경을 보존하는 제약 5. finding의 `references` 전체 6. 저장소 지침과 package scripts를 먼저 확인하고 변경 범위에 맞게 검증하라는 요청 존재하지 않는 명령·파일·대체 API를 프롬프트에 추측해서 넣지 않습니다. 여러 finding이 같은 원인과 한 번의 수정으로 해결되면 기존 묶음 규칙대로 하나의 finding과 하나의 프롬프트를 만듭니다. Doctor는 이 프롬프트를 생성만 하며, 사용자가 실제 수정을 요청하기 전에는 실행하지 않습니다. ## 저장과 다중 워크스페이스 - 대상 프로젝트에는 쓰지 않습니다. schema v2 YAML과 HTML을 같은 임시 디렉토리에 저장하고 두 경로를 알려줍니다. - 사용자가 명시적으로 "YAML만"을 요청한 경우에만 HTML을 생략합니다. - 여러 워크스페이스를 전체 진단하면 각 workspace마다 schema v2 YAML과 HTML을 한 쌍씩 만듭니다. - 같은 workspace를 범주별로 나눠 검사했다면 `checks`·`findings`·`verdicts`·`coverage`·`rejected`를 합치고 findings에서 summary를 다시 계산합니다. `meta`가 다르면 합치지 않습니다. - 채팅에는 workspace별 요약, 적용 제외·미검증 수, "먼저 할 것"과 YAML·HTML 경로만 전달합니다. ## HTML 리포트 스키마와 필드 관계 검증을 통과한 YAML만 입력으로 사용해 `assets/report-template.html`의 구조를 채웁니다. HTML에서 판정이나 집계를 별도로 만들지 않습니다. 렌더링에 실패하면 검증된 YAML은 보존하고 실패 이유를 알리며, HTML까지 생성된 것처럼 보고하지 않습니다. - 한 파일로 완결합니다. CDN·외부 폰트·JavaScript를 쓰지 않고 `
`로 접습니다. - "먼저 할 것" 다음에 **범주별 검사 범위**를 보여 줍니다. - `not-applicable`·`not-verified` 이유와 references를 숨기지 않습니다. - 기존 finding 근거·수정 프롬프트, 판정 표, coverage, 기각 목록, severity count를 보존합니다. - footer에 대상 코드를 수정하지 않았음을 명시합니다. ```` ### doctor-react.md ```md # React Doctor 프로필 `references/doctor.md`가 React 워크스페이스를 진단할 때 사용하는 라우팅 프로필입니다. 현재 지원 범위나 문서 목록을 이 파일에 복제하지 않습니다. ## 고정 진입점 - React 문서 인덱스: `https://seed-design.io/react/llms.txt` - registry namespace: `react` - 플랫폼 판별 후보: `@seed-design/react`, `@seed-design/css`와 React 앱 의존성 전체 문서 인덱스는 공통 Doctor 절차가 제공합니다. 이 프로필은 React 진입점을 문서 풀에 등록하며 이미 로드된 URL을 다시 읽지 않습니다. 패키지 이름은 플랫폼 후보를 찾기 위한 앵커입니다. 구현·스타일·선택 패키지의 실제 역할과 호환 범위는 현재 인덱스가 연결한 설치·업그레이드 문서와 설치본 `package.json`에서 확정합니다. ## 문서 발견 1. 문서 풀의 전체 인덱스에서 공통 Components·Foundations·Design Guidelines와 React 진입점을 찾습니다. 2. 문서 풀의 React 인덱스에서 요청한 룰과 의미가 맞는 문서를 찾습니다. 제목이나 category가 바뀔 수 있으므로 고정 경로를 조합하지 않습니다. 3. 문서 풀에 없는 leaf만 읽고 그 실행에서만 capability와 판정 기준을 구성합니다. 4. 리포트 `references`에는 React 인덱스와 실제로 읽은 leaf 문서를 함께 기록합니다. React 인덱스를 정상적으로 읽었는데 필요한 공식 계약이 없으면 해당 check를 `not-applicable`로 두고 인덱스 부재를 이유로 남깁니다. 인덱스나 연결 문서를 읽지 못했으면 `not-verified`입니다. 과거에 문서가 있었거나 없었다는 기억으로 상태를 고정하지 않습니다. ## 컴포넌트·registry 연결 공통 컴포넌트 문서의 Platform 표 → React 인덱스 → React registry 전체 인덱스 → 재export를 따라간 설치본 package exports 순으로 실제 구현·registry id를 찾습니다. id 매핑 목록을 이 프로필에 유지하지 않습니다. registry URL 구조는 공통 Doctor 절차의 형식을 사용하되, 아이템·세대의 존재 여부는 현재 registry와 인덱스 응답으로 확인합니다. 연결 실패를 아이템 부재로 바꾸지 않습니다. ## 적용 원칙 - 일반 진단의 룰 목록과 category는 [doctor.md](doctor.md)와 `SKILL.md`를 단일 원천으로 사용합니다. - 설치 방식, 업그레이드 경계, deprecation, Library Authors 계약은 React 인덱스가 현재 연결한 문서에서만 가져옵니다. - Lynx 문서로 React 문서의 빈칸을 채우지 않습니다. - 패키지 metadata와 공식 문서가 충돌하면 둘 다 evidence에 남기고 임의로 합의하지 않습니다. ``` ### doctor-lynx.md ```md # Lynx Doctor 프로필 `references/doctor.md`가 Lynx 워크스페이스를 진단할 때 사용하는 라우팅 프로필입니다. 현재 지원·미지원 capability나 컴포넌트 목록을 이 파일에 복제하지 않습니다. ## 고정 진입점 - Lynx 문서 인덱스: `https://seed-design.io/lynx/llms.txt` - registry namespace: `lynx` - 플랫폼 판별 후보: `@seed-design/lynx-react`, `@seed-design/lynx-css`, `@lynx-js/react` 전체 문서 인덱스는 공통 Doctor 절차가 제공합니다. 이 프로필은 Lynx 진입점을 문서 풀에 등록하며 이미 로드된 URL을 다시 읽지 않습니다. 패키지 이름은 플랫폼 후보를 찾기 위한 앵커입니다. 구현·스타일·보조 패키지의 실제 역할과 호환 범위는 현재 인덱스가 연결한 문서와 설치본 `package.json`에서 확정합니다. ## 문서 발견 1. 문서 풀의 전체 인덱스에서 공통 Components·Foundations·Design Guidelines와 Lynx 진입점을 찾습니다. 2. 문서 풀의 Lynx 인덱스에서 요청한 룰과 의미가 맞는 문서를 찾습니다. 제목이나 category가 바뀔 수 있으므로 고정 경로를 조합하지 않습니다. 3. 문서 풀에 없는 leaf만 읽고 그 실행에서만 capability와 판정 기준을 구성합니다. 4. 리포트 `references`에는 Lynx 인덱스와 실제로 읽은 leaf 문서를 함께 기록합니다. Lynx 인덱스를 정상적으로 읽었는데 필요한 공식 계약이 없으면 해당 check를 `not-applicable`로 두고 인덱스 부재를 이유로 남깁니다. 인덱스나 연결 문서를 읽지 못했으면 `not-verified`입니다. 현재 없는 문서가 나중에 추가될 수 있으므로 부재를 프로필의 영구 정책으로 적지 않습니다. ## 컴포넌트·registry 연결 공통 컴포넌트 문서의 Platform 표 → Lynx 인덱스 → Lynx registry 전체 인덱스 → 재export를 따라간 설치본 package exports 순으로 실제 구현·registry id를 찾습니다. id 매핑과 지원 컴포넌트 목록을 이 프로필에 유지하지 않습니다. registry URL 구조는 공통 Doctor 절차의 형식을 사용하되, 아이템·세대의 존재 여부는 현재 registry와 인덱스 응답으로 확인합니다. 연결 실패를 아이템 부재로 바꾸지 않습니다. ## 적용 원칙 - 일반 진단의 룰 목록과 category는 [doctor.md](doctor.md)와 `SKILL.md`를 단일 원천으로 사용합니다. - 설치 방식, 업그레이드, deprecation, 라이브러리 저자 계약은 Lynx 인덱스가 현재 연결한 문서가 있을 때만 판정합니다. - React 문서로 Lynx 문서의 빈칸을 채우지 않습니다. 단, 현재 공식 CLI 문서가 다른 섹션에 있더라도 문서 본문이 Lynx 지원을 명시하면 그 CLI 계약만 사용할 수 있습니다. - 패키지 metadata와 공식 문서가 충돌하면 둘 다 evidence에 남기고 임의로 합의하지 않습니다. ```