# 03. 포맷 스펙과 변환 어댑터 설계

작성일: 2026-08-20
목적: designpaca를 Claude Code / Codex / Cursor(+ Windsurf, VS Code Copilot)에서 동일하게 동작시키기 위한 정확한 포맷 스펙과 변환 시 주의점.

**중요한 전제 변화**: 2026년 8월 현재, **Cursor와 Codex 모두 Agent Skills 표준을 네이티브 지원한다.** 따라서 "SKILL.md를 .mdc로 변환"하는 어댑터는 더 이상 1순위가 아니다. 1순위는 **하나의 SKILL.md를 세 도구가 모두 읽을 수 있는 위치에 두는 것**이다. 변환 어댑터는 레거시 경로(`.cursor/rules/*.mdc`, `AGENTS.md`) 지원용으로 남는다.

---

## 1. Agent Skills 오픈 표준 (모든 도구의 공통 분모)

출처: https://agentskills.io/specification (직접 fetch)

### 1.1 디렉터리 구조

```
skill-name/
├── SKILL.md          # Required: metadata + instructions
├── scripts/          # Optional: executable code
├── references/       # Optional: documentation
├── assets/           # Optional: templates, resources
└── ...               # Any additional files or directories
```

### 1.2 프론트매터 — 허용 필드 6개 전부

| Field | Required | Constraints (원문) |
|---|---|---|
| `name` | Yes | "Max 64 characters. Lowercase letters, numbers, and hyphens only. Must not start or end with a hyphen." |
| `description` | Yes | "Max 1024 characters. Non-empty. Describes what the skill does and when to use it." |
| `license` | No | "License name or reference to a bundled license file." |
| `compatibility` | No | "Max 500 characters. Indicates environment requirements (intended product, system packages, network access, etc.)." |
| `metadata` | No | "Arbitrary key-value mapping for additional metadata (a map from string keys to string values)." |
| `allowed-tools` | No | "Space-separated string of pre-approved tools the skill may use. **(Experimental)**" |

### 1.3 `name` 상세 규칙 (원문)

> * Must be 1-64 characters
> * May only contain unicode lowercase alphanumeric characters (`a-z`, `0-9`) and hyphens (`-`)
> * Must not start or end with a hyphen (`-`)
> * **Must not contain consecutive hyphens (`--`)**
> * **Must match the parent directory name**

무효 예시:
```yaml
name: PDF-Processing  # uppercase not allowed
name: -pdf            # cannot start with hyphen
name: pdf--processing # consecutive hyphens not allowed
```

Anthropic 플랫폼 문서는 여기에 두 가지를 더 추가한다:

> `name`: ... **Cannot contain XML tags. Cannot contain reserved words: "anthropic", "claude"**
> `description`: ... **Cannot contain XML tags**
> — platform.claude.com Skill authoring best practices

**→ designpaca 결론**: `name: designpaca`. 예약어 없음, 하이픈 없음, 소문자만. 디렉터리명도 `designpaca`여야 한다.

### 1.4 Progressive Disclosure 3계층 (원문)

> 1. **Metadata** (~100 tokens): The `name` and `description` fields are loaded at startup for all skills
> 2. **Instructions** (< 5000 tokens recommended): The full `SKILL.md` body is loaded when the skill is activated
> 3. **Resources** (as needed): Files (e.g. those in `scripts/`, `references/`, or `assets/`) are loaded only when required
>
> **Keep your main `SKILL.md` under 500 lines.** Move detailed reference material to separate files.

### 1.5 파일 참조 규칙 (원문)

> When referencing other files in your skill, use **relative paths from the skill root**:
> ```markdown
> See [the reference guide](references/REFERENCE.md) for details.
> Run the extraction script: scripts/extract.py
> ```
> **Keep file references one level deep from `SKILL.md`. Avoid deeply nested reference chains.**

Anthropic이 이유를 설명한다:

> Claude may partially read files when they're referenced from other referenced files. When encountering nested references, **Claude might use commands like `head -100` to preview content rather than reading entire files, resulting in incomplete information.**

그리고 100줄 초과 참조 파일에는 목차를 넣으라고 한다:

> For reference files longer than 100 lines, include a table of contents at the top. **This ensures Claude can see the full scope of available information even when previewing with partial reads.**

### 1.6 검증 도구

> Use the [skills-ref](https://github.com/agentskills/agentskills/tree/main/skills-ref) reference library to validate your skills:
> ```bash
> skills-ref validate ./my-skill
> ```

**→ designpaca는 이 검증기를 CI에 걸어야 한다.**

---

## 2. Claude Code SKILL.md

출처: https://code.claude.com/docs/en/skills (직접 fetch)

### 2.1 설치 위치와 우선순위

| Location | Path | Applies to |
|---|---|---|
| Enterprise | managed settings 참조 | 조직 전체 |
| Personal | `~/.claude/skills/<skill-name>/SKILL.md` | 모든 프로젝트 |
| Project | `.claude/skills/<skill-name>/SKILL.md` | 해당 프로젝트만 |
| Plugin | `<plugin>/skills/<skill-name>/SKILL.md` | 플러그인 활성 범위 |

이름 충돌 해소 순서 (원문):

> * Across levels, **enterprise overrides personal, and personal overrides project.**
> * A skill at any of these levels also overrides a bundled skill with the same name, **but not the bundled skill's aliases.**
> * Plugin skills use a `plugin-name:skill-name` namespace, so they can't conflict with other levels.
> * If you have files in `.claude/commands/`, ... **if a skill and a command share the same name, the skill takes precedence.**

**중첩 스킬** (모노레포용):

> Skills also load from nested `.claude/skills/` directories below your working directory. ... The nested one appears under a directory-qualified name, `apps/web:deploy`.
> **Skills in nested `.claude/skills/` directories below your starting directory aren't loaded at startup.** They load the first time Claude reads or edits a file inside that subdirectory.

**심링크 지원** (중요):

> A `<skill-name>` entry in the enterprise, personal, or project locations **can be a symlink to a directory elsewhere on disk.** Claude Code follows the symlink and reads `SKILL.md` from the target directory, and **if the same target is reachable from more than one location, Claude Code loads the skill once.**

→ 이 사용자의 환경이 이미 이 방식이다. `~/.claude/skills/design-taste-frontend` → `~/.agents/skills/design-taste-frontend`. **designpaca도 `~/.agents/skills/designpaca/`를 정본으로 두고 심링크하는 것이 옳다.**

### 2.2 프론트매터 전체 필드 (Claude Code 확장 포함)

> All fields are optional. Only `description` is recommended so Claude knows when to use the skill.
> Boolean fields accept `yes`, `no`, `on`, `off`, `1`, and `0` in any letter case, in addition to `true` and `false`.

| Field | 표준? | 설명 (요약) |
|---|:-:|---|
| `name` | O | 스킬 목록 표시명. **개인/프로젝트 스킬에서는 커맨드명을 바꾸지 못한다** (디렉터리명이 커맨드명). 플러그인 스킬에서만 마지막 세그먼트를 결정 |
| `description` | O | 무엇을 하고 언제 쓰는지. **"the combined `description` and `when_to_use` text is truncated at 1,536 characters in the skill listing"** |
| `when_to_use` | X | description에 덧붙는 추가 트리거 문구. **1,536자 상한에 함께 포함됨** |
| `argument-hint` | X | 자동완성 힌트. 예: `[issue-number]` |
| `arguments` | X | `$name` 치환용 명명 위치 인자 |
| `disable-model-invocation` | X | `true`면 Claude가 자동 로드 못 함. **"Description not in context"** |
| `user-invocable` | X | `false`면 `/` 메뉴에서 숨김. Claude만 호출 |
| `allowed-tools` | O(실험) | 해당 턴 동안 승인 없이 쓸 도구. **"The grant clears when you send your next message"** |
| `disallowed-tools` | X | 스킬 활성 중 제거할 도구 |
| `model` | X | 스킬 활성 시 모델 오버라이드 |
| `effort` | X | `low`/`medium`/`high`/`xhigh`/`max` |
| `context` | X | `fork` → 포크된 서브에이전트에서 실행 |
| `agent` | X | `context: fork` 시 서브에이전트 타입 |
| `background` | X | `context: fork` 시 백그라운드 여부 (기본 `true`) |
| `hooks` | X | 스킬 호출 시 등록되는 훅 |
| `paths` | X | 글롭 패턴. **"Claude loads the skill automatically only when working with files matching the patterns"** |
| `shell` | X | `bash`(기본) 또는 `powershell` |
| `metadata` | O | 자유 형식 YAML 맵 |
| `license` | O | Claude Code는 받아들이지만 아무 동작 안 함 |
| `compatibility` | O | 최대 500자. Claude Code는 받아들이지만 아무 동작 안 함 |

### 2.3 도구 밖으로 나갈 때의 하드 에러 (가장 중요한 제약)

원문:

> Claude Code accepts every field in the table above. **Outside Claude Code, you can use only the fields in the Agent Skills spec:**
>
> | Distribution path | Frontmatter fields you can use |
> |---|---|
> | Claude Code skills at any level, including plugin skills | Every field in the table above |
> | claude.ai skill uploads, the Skills API, and packaging with `package_skill.py` | `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools` |
>
> **If you include any field the spec doesn't allow, packaging or upload fails with a hard error instead of ignoring the field:**
> ```
> Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name
> ```

**→ designpaca 결정: 프론트매터는 `name` + `description`만 쓴다.** 크로스툴 휴대성이 목표이므로 확장 필드는 전부 배제. 이는 로컬 커뮤니티 스킬 13개가 이미 도달한 결론과 같다.

(참고: 로컬 `graphify`의 `trigger: /graphify`는 스펙에 없는 필드다. Claude Code는 무시하지만 claude.ai 업로드/패키징 시 위 에러가 난다. designpaca는 이 패턴을 복제하면 안 된다.)

### 2.4 커맨드명이 결정되는 규칙

| Skill location | Command name source | Example |
|---|---|---|
| `~/.claude/skills/` 또는 `.claude/skills/` 아래 디렉터리 | **디렉터리명** | `.claude/skills/deploy-staging/SKILL.md` → `/deploy-staging` |
| 중첩 `.claude/skills/` (이름 충돌 시) | 작업 디렉터리 상대 경로 + 스킬 디렉터리명 | `apps/web/.claude/skills/deploy/` → `/apps/web:deploy` |
| `.claude/commands/` 아래 파일 | 확장자 뺀 파일명 | `.claude/commands/deploy.md` → `/deploy` |
| 플러그인 `skills/` 하위 | 프론트매터 `name` 또는 디렉터리명 + 플러그인 네임스페이스 | `my-plugin/skills/review/` → `/my-plugin:review` |
| 플러그인 루트 `SKILL.md` | 프론트매터 `name` (없으면 플러그인 디렉터리명) | `name: review` → `/my-plugin:review` |

### 2.5 컨텍스트 수명 (설계 제약)

원문 그대로:

> When you or Claude invoke a skill, the rendered `SKILL.md` content enters the conversation as a single message and **stays there for the rest of the session**. ... **Claude Code does not re-read the skill file on later turns.**
>
> When Claude re-invokes a skill whose rendered content is identical to the copy already in context, Claude Code adds a short note that the skill is already loaded rather than a second copy.
>
> Auto-compaction carries invoked skills forward within a token budget. When the conversation is summarized to free context, Claude Code re-attaches the most recent invocation of each skill after the summary, **keeping the first 5,000 tokens of each. Re-attached skills share a combined budget of 25,000 tokens.**
>
> **If a skill seems to stop influencing behavior after the first response, the content is usually still present and the model is choosing other tools or approaches.** Strengthen the skill's `description` and instructions so the model keeps preferring it, or use hooks to enforce behavior deterministically.

**→ 설계 결론 3개**
1. SKILL.md 본문은 **5,000토큰(약 500줄) 이내**여야 컴팩션 후에도 온전히 살아남는다.
2. **가장 중요한 규칙은 파일 앞부분**에 있어야 한다.
3. 여러 스킬을 쓰는 세션에서는 25,000토큰을 나눠 쓰므로, 큰 스킬은 다른 스킬을 밀어낸다.

### 2.6 스킬 목록 예산 (트리거 실패의 숨은 원인)

원문:

> Claude Code loads a listing of skill names and descriptions into context so Claude knows what's available. The listing always contains every skill name, but **if you have many skills, Claude Code shortens descriptions to fit the listing's character budget, which can strip the keywords Claude needs to match your request. The budget scales at 1% of the model's context window.**
>
> Run `/doctor` for an estimate of the listing's context cost and its biggest contributors.
> To raise the budget, set the `skillListingBudgetFraction` setting (e.g. `0.02` = 2%) or the `SLASH_COMMAND_TOOL_CHAR_BUDGET` environment variable.

**→ description을 짧게 유지해야 하는 진짜 이유.** 이 사용자 환경에는 스킬이 40개 이상 있다. 620자 description(imagegen-frontend-web)은 잘려나갈 위험이 크다. **200~350자를 권장.**

### 2.7 프론트매터 파싱 실패 시

> If the frontmatter YAML is malformed, Claude Code loads the skill body with empty metadata, so `/skill-name` still works but Claude has no `description` to match against. Run with `--debug` to see the parse error.

→ 조용히 실패한다. 검증기를 돌려야 하는 이유.

### 2.8 커스텀 커맨드와의 통합

> **Custom commands have been merged into skills.** A file at `.claude/commands/deploy.md` and a skill at `.claude/skills/deploy/SKILL.md` both create `/deploy` and work the same way.
> Files in `.claude/commands/` support the same frontmatter, **except `name` and `paths`, which Claude Code ignores in a command file.**

---

## 3. Codex (OpenAI) — 두 가지 경로

Codex는 **AGENTS.md**(항상 로드되는 컨텍스트)와 **Agent Skills**(온디맨드 로드) 둘 다 지원한다. 이 둘은 역할이 다르다.

### 3.1 Codex Agent Skills

출처: https://learn.chatgpt.com/docs/build-skills (developers.openai.com/codex/skills 에서 308 리다이렉트)

**스캔 위치 (우선순위 순, 원문 기반)**

| 범위 | 경로 |
|---|---|
| Repository | `.agents/skills` — 현재 작업 디렉터리와 상위 폴더들을 repo root까지 |
| User | `$HOME/.agents/skills` |
| Admin | `/etc/codex/skills` |
| System | OpenAI 번들 |

> "If two skills share the same `name`, Codex doesn't merge them; both can appear in skill selectors."

**프론트매터**

```yaml
---
name: skill-name
description: Explain exactly when this skill should and should not trigger.
---
```

Codex 문서의 description 지침이 특히 명확하다: **"when this skill should and should not trigger"** — 배제 조건을 스펙 수준에서 요구한다.

**컨텍스트 예산**

> Skills use "progressive disclosure to manage context efficiently." The initial skills list uses at most **"2% of the model's context window, or 8,000 characters when the context window is unknown"**, though full `SKILL.md` instructions load when a skill is selected.

**→ 중대한 발견**: Codex의 스킬 스캔 경로가 `.agents/skills`와 `$HOME/.agents/skills`다. **이 사용자 머신의 `C:\Users\encep\.agents\skills\`가 정확히 그 경로다.** 즉 현재 설치된 디자인 스킬들은 Codex와 Cursor 양쪽에서 동시에 인식되도록 배치된 것이다.

### 3.2 Codex AGENTS.md

출처: https://agents.md/ (직접 fetch)

**포맷 (원문)**

> **No required fields.** "AGENTS.md is just standard Markdown. Use any headings you like; the agent simply parses the text you provide."
> **프론트매터를 쓰지 않는다.**

**중첩과 우선순위 (원문)**

> "The closest AGENTS.md to the edited file wins; **explicit user chat prompts override everything**."

Codex 구현의 3계층 (검색 결과 종합, 다수 소스 일치):
1. `~/.codex/AGENTS.override.md` (최고 우선순위 글로벌 오버라이드)
2. `~/.codex/AGENTS.md`
3. 프로젝트: git root부터 현재 디렉터리까지 걸어가며 각 디렉터리의 `AGENTS.override.md` 또는 `AGENTS.md`
- 병합 순서: root부터 아래로 연결(concatenate), 가까운 파일이 앞의 것을 오버라이드
- **기본 크기 상한 32 KiB에서 중단**

**권장 섹션 (원문)**

> Project overview / Build and test commands / Code style guidelines / Testing instructions / Security considerations / Commit message/PR guidelines / Deployment steps

**성격**

> "Think of AGENTS.md as a **README for agents**: a dedicated, predictable place to provide the context and instructions"

**지원 도구**: OpenAI Codex, Google Jules, Factory, Aider, Zed, VS Code, Devin, GitHub Copilot, Cursor, Gemini CLI 외 15개 이상. 6만 개 이상의 오픈소스 프로젝트에서 사용.

**→ AGENTS.md는 스킬이 아니다.** 항상 로드된다. designpaca 전체를 AGENTS.md에 넣으면 모든 대화에서 토큰을 먹는다. **AGENTS.md에는 포인터만 두고, 본체는 `.agents/skills/designpaca/`에 두는 것이 옳다.**

---

## 4. Cursor — 두 가지 경로

### 4.1 Cursor Agent Skills (신규, 권장)

출처: https://cursor.com/docs/context/skills (직접 fetch)

**로드 위치 4곳**
- 프로젝트: `.agents/skills/` 와 `.cursor/skills/`
- 사용자: `~/.agents/skills/` 와 `~/.cursor/skills/`

> Cursor "walks the skills root recursively and picks up any `SKILL.md` it finds."

**프론트매터**

필수:
- `name` — "Skill identifier. Lowercase letters, numbers, and hyphens only."
- `description` — "Describes what the skill does and when to use it."

선택 (Cursor 확장):
- `paths` — 글롭 패턴으로 스코프 제한
- `disable-model-invocation` — true면 `/skill-name`으로만 호출
- `icon` — "Icon shown on the badge when the skill is used as a Custom Mode"
- `color` — `default, green, cyan, blue, purple, magenta, orange, yellow, red, brand`
- `metadata`

> "Skills in nested project directories are automatically scoped to files inside that directory."

**→ `~/.agents/skills/designpaca/` 하나가 Cursor와 Codex 양쪽에서 인식된다.** 이것이 크로스툴 배포의 정답이다.

### 4.2 Cursor Rules (.mdc) — 레거시 경로

출처: https://cursor.com/docs/rules (직접 fetch)

**파일 위치**
```
.cursor/rules/
  react-patterns.mdc
  frontend/
    components.mdc
```

**프론트매터 필드는 정확히 3개** (문서에 명시된 것 전부):

| Field | Type | 설명 (원문) |
|---|---|---|
| `alwaysApply` | boolean | "Apply to every chat session" |
| `description` | string | "Helps Agent decide relevance; omitting it restricts to manual @-mention only" |
| `globs` | string | "File pattern(s) for auto-attachment; supports comma-separated patterns" |

> "No other frontmatter fields are specified in the documentation."

**4가지 규칙 타입**

| Type | 조건 | 동작 |
|---|---|---|
| Always Apply | `alwaysApply: true` | 모든 채팅 세션에 적용 |
| Apply Intelligently | `description` 있음, `globs` 없음 | 에이전트가 관련성 판단 |
| Apply to Specific Files | `globs` 있음 | "Auto-attached when a matching file is in context" |
| Apply Manually | `description`·`globs` 둘 다 없음 | "@-mention in chat (e.g., `@my-rule`)" |

**공식 베스트 프랙티스 (원문)**

> - "Keep rules under 500 lines"
> - "Split large rules into multiple, composable rules"
> - Reference files via `@filename.ts` rather than copying content
> - Avoid duplicating style guides; use linters instead

**중요한 스코프 제약**

> Rules apply only to Agent (Chat), **not Cursor Tab or Inline Edit (Cmd/Ctrl+K).**

**Cursor의 AGENTS.md 지원**

> "`AGENTS.md` is a simple markdown file for defining agent instructions" without frontmatter. Supports nested placement: "You can place `AGENTS.md` files in any subdirectory" with hierarchical precedence.

---

## 5. Windsurf / Cascade Rules

출처: https://docs.windsurf.com/windsurf/cascade/memories → 307 리다이렉트 → https://docs.devin.ai/desktop/cascade/memories (직접 fetch)

**주의**: Windsurf 문서가 Devin 문서로 리다이렉트된다(Cognition의 Windsurf 인수 이후 통합). 아래는 리다이렉트된 최신 문서 기준이므로, `.windsurf/` 경로는 "legacy"로 표기되어 있다.

### 5.1 파일 위치 3계층

| 범위 | 경로 |
|---|---|
| Global | `~/.codeium/windsurf/memories/global_rules.md` (단일 파일, 항상 활성) |
| Workspace | `.devin/rules/*.md` (권장) 또는 `.windsurf/rules/*.md` (legacy), 그리고 legacy `.windsurfrules` |
| System (Enterprise) | macOS `/Library/Application Support/Devin/rules/`, Linux `/etc/devin/rules/`, Windows `C:\ProgramData\Devin\rules\` |

### 5.2 문자 수 제한 (하드)

> - Global rules: "Limited to **6,000 characters**"
> - Workspace rules: "Limited to **12,000 characters per file**"

**이것이 다른 어떤 포맷보다 강한 제약이다.** designpaca 본문이 12,000자를 넘으면 Windsurf에서는 반드시 분할해야 한다.

### 5.3 활성화 모드 (`trigger:` 필드)

| Mode | Trigger 값 | 동작 (원문) |
|---|---|---|
| Always On | `always_on` | "Full rule content is included in the system prompt on every message" |
| Model Decision | `model_decision` | "Description shown always; full content retrieved when Cascade deems relevant" |
| Glob | `glob` | "Applied when files matching specified patterns are accessed" |
| Manual | `manual` | "Activated only via `@rule-name` mention in input" |

### 5.4 프론트매터 예시 (원문)

```markdown
---
trigger: glob
globs: **/*.test.ts
---

All test files must use `describe`/`it` blocks and mock external API calls.
```

> Global and root-level files don't require frontmatter and remain perpetually active.

**주의**: Windsurf의 `trigger:`는 값이 `always_on`/`model_decision`/`glob`/`manual` 중 하나다. Claude Code SKILL.md의 슬래시 커맨드 이름을 넣는 필드가 아니다. (`graphify`의 `trigger: /graphify`와 혼동 금지 — 서로 다른 스펙의 같은 이름 필드다.)

---

## 6. VS Code / GitHub Copilot Agent Skills

출처: https://code.visualstudio.com/docs/copilot/customization/agent-skills (직접 fetch)

**로드 위치**
- 프로젝트: `.github/skills/`, `.claude/skills/`, `.agents/skills/`
- 개인: `~/.copilot/skills/`, `~/.claude/skills/`, `~/.agents/skills/`
- 추가 경로: `chat.agentSkillsLocations` 설정

**프론트매터**
- `name` (필수): "A unique identifier for the skill. Only lowercase letters, numbers, and hyphens are allowed"
- `description` (필수): "A description of what the skill does **and when to use it**"
- `argument-hint` (선택)
- `user-invocable` (선택)
- `disable-model-invocation` (선택)
- `context` (선택, 실험): `fork`

**custom instructions와의 차이 (원문)**

> skills are "task-specific, loaded on-demand" and work across multiple tools, while custom instructions are "Always applied (or via glob patterns)" and limited to "VS Code and GitHub.com only."

---

## 7. 포맷 비교 통합표

| 항목 | Claude Code SKILL.md | Agent Skills 표준 | Codex AGENTS.md | Cursor .mdc | Windsurf rules |
|---|---|---|---|---|---|
| **파일 위치** | `~/.claude/skills/<n>/SKILL.md`, `.claude/skills/<n>/SKILL.md` | `<n>/SKILL.md` | 리포 루트 + 각 하위 디렉터리 `AGENTS.md` | `.cursor/rules/*.mdc` | `~/.codeium/windsurf/memories/global_rules.md`, `.windsurf/rules/*.md` |
| **프론트매터** | YAML, 22개 필드 | YAML, 6개 필드 | **없음** | YAML, 3개 필드 | YAML, `trigger` + `globs` |
| **필수 필드** | 없음 (`description` 권장) | `name`, `description` | 없음 | 없음 | 없음 |
| **로드 시점** | 온디맨드 (description 매칭 or `/이름`) | 온디맨드 | **항상** | 4모드 (always/글롭/설명매칭/수동) | 4모드 (always_on/glob/model_decision/manual) |
| **크기 제한** | 본문 500줄 권장, 컴팩션 시 5K 토큰 생존 | 본문 500줄 / 5,000토큰 권장 | 32 KiB 병합 상한 | 500줄 권장 | **6,000자(글로벌) / 12,000자(워크스페이스) 하드** |
| **description 상한** | 1,536자(+`when_to_use` 합산), 목록 예산 1% | 1,024자 | N/A | 미명시 | 미명시 |
| **참조 파일** | O (`references/`, `scripts/`, `assets/`) | O | X (별도 AGENTS.md 중첩으로 대체) | `@filename` 참조 | X |
| **스크립트 실행** | O | O | X | X | X |
| **네임스페이스** | 플러그인 `plugin:skill`, 중첩 `dir:skill` | X | 경로 기반 | X | X |
| **심링크** | O (중복 로드 방지 포함) | 구현 의존 | N/A | 미명시 | 미명시 |

---

## 8. designpaca 배포 전략 (권장안)

### 8.1 단일 정본 + 심링크 (Tier 1)

**정본 위치**: `~/.agents/skills/designpaca/`

이 한 곳이 다음 세 도구에서 **변환 없이** 인식된다:
- **Cursor**: `~/.agents/skills/` 를 직접 스캔
- **Codex**: `$HOME/.agents/skills` 를 직접 스캔
- **VS Code Copilot**: `~/.agents/skills/` 를 직접 스캔

**Claude Code용 심링크**:
```bash
# Git Bash / WSL
ln -s ~/.agents/skills/designpaca ~/.claude/skills/designpaca
```
```powershell
# Windows PowerShell (관리자 또는 개발자 모드)
New-Item -ItemType SymbolicLink -Path "$HOME\.claude\skills\designpaca" -Target "$HOME\.agents\skills\designpaca"
```

Claude Code 문서가 이 방식을 명시적으로 지원한다:
> A `<skill-name>` entry ... can be a symlink to a directory elsewhere on disk. Claude Code follows the symlink and reads `SKILL.md` from the target directory.

**프로젝트 스코프**: 리포에 `.agents/skills/designpaca/`를 두면 Cursor·Codex·Copilot이 전부 읽는다. Claude Code용으로 `.claude/skills/designpaca` 심링크를 추가한다.

### 8.2 파일 구조 (권장)

```
designpaca/
├── SKILL.md                          # 400~480줄. 절차 + 인덱스 + 핵심 게이트
├── references/
│   ├── anti-patterns.md              # AI 텔 카탈로그 (무엇/왜/대신)
│   ├── slop-gates.md                 # 출력 후 예/아니오 게이트 목록
│   ├── typography.md                 # 폰트 페어링, 스케일, 세리프 규율
│   ├── color.md                      # 팔레트 규칙, 금지 hex 패밀리, 대비
│   ├── layout.md                     # 매크로구조 인덱스 + 섹션 리듬
│   ├── motion.md                     # 이징, 스크롤, reduced-motion
│   ├── copy.md                       # 카피 규율 + 자가 감사 목록
│   ├── responsive.md                 # 브레이크포인트, 모바일 붕괴, 실무 버그
│   ├── design-systems.md             # 공식 DS 매핑 + 설치 명령 + 문서 링크
│   ├── redesign.md                   # 리디자인 프로토콜 (감사/보존/레버)
│   └── design-md-template.md         # 산출용 design.md 템플릿
├── assets/
│   └── themes/                       # 테마별 개별 파일 (인덱스-후-선택)
└── scripts/
    └── check_contrast.(js|py)        # 대비/팔레트 검증기 (선택)
```

**모든 references 파일은 SKILL.md에서 1단계 링크로만 참조.** 참조 파일끼리 서로 링크하지 않는다.

### 8.3 프론트매터 (확정안)

```yaml
---
name: designpaca
description: <용도 + 트리거 문구 + 배제 조건. 200~350자. 3인칭.>
---
```

**확장 필드를 쓰지 않는 이유**:
1. claude.ai 업로드/패키징 시 하드 에러
2. Cursor·Codex·Copilot이 지원하는 필드 집합이 서로 다름
3. 로컬 커뮤니티 스킬 13개가 이미 같은 결론에 도달

### 8.4 레거시 어댑터 (Tier 2, 필요 시)

Agent Skills를 지원하지 않는 경로용 변환. **자동 생성 스크립트로 만들고 손으로 관리하지 않는다.**

#### (a) → Cursor `.mdc` 규칙

```
.cursor/rules/designpaca.mdc
```

```markdown
---
description: Use when building or reshaping web UI - landing pages, portfolios, marketing sites, product pages, or redesigns - and the visual result matters.
alwaysApply: false
---

<SKILL.md 본문>

<!-- references/ 는 @-참조로 대체 -->
See @.cursor/rules/designpaca-anti-patterns.mdc for the full anti-pattern catalogue.
```

**변환 시 주의점**
1. **`name` 필드를 제거한다.** `.mdc`는 `description`/`globs`/`alwaysApply` 3개만 인식. 다른 필드는 문서화되지 않았다.
2. **`alwaysApply: true`를 쓰지 마라.** Cursor 문서: "Use sparingly, this is your global config, not your per-feature config." 디자인 스킬은 항상 켜져 있으면 안 된다.
3. **`globs`를 쓸지 말지**: `**/*.{tsx,jsx,vue,svelte,astro,html,css}` 로 걸면 파일 컨텍스트 기반 자동 첨부가 되지만, "새 랜딩 만들어줘"처럼 파일이 아직 없는 경우 발동하지 않는다. **디자인 스킬은 `description`만 두는 "Apply Intelligently" 모드가 맞다.**
4. **참조 파일 링크를 `@경로`로 바꾼다.** `.mdc`는 `references/*.md` 상대 경로를 읽지 않는다.
5. **500줄 상한 준수.** 넘으면 여러 `.mdc`로 쪼개고 서로 `@`로 연결.
6. **Tab/Inline Edit에는 적용 안 됨**을 문서에 명시.

#### (b) → Windsurf 규칙

```
.windsurf/rules/designpaca.md   (또는 .devin/rules/designpaca.md)
```

```markdown
---
trigger: model_decision
description: Use when building or reshaping web UI ...
---

<SKILL.md 본문 — 12,000자 이내로 압축>
```

**변환 시 주의점**
1. **12,000자 하드 상한.** SKILL.md가 이를 넘으면 반드시 분할. 파일 여러 개로 쪼개고 각각 `trigger: model_decision`.
2. **`trigger: model_decision`을 쓴다.** `always_on`은 6,000자 글로벌 규칙에만.
3. `references/` 개념이 없다. 핵심만 남기고 나머지는 버리거나 별도 규칙 파일로.
4. `name` 필드 없음.

#### (c) → AGENTS.md

**전체를 넣지 마라.** AGENTS.md는 항상 로드되므로 디자인 스킬 본문을 넣으면 모든 대화에서 비용이 든다. 포인터만 넣는다:

```markdown
## Design work

When building or changing UI in this repo, load the `designpaca` skill
(`.agents/skills/designpaca/SKILL.md`) before writing any markup or styles.
The project's locked design system lives at `design.md` at the repo root;
it overrides the skill's defaults.
```

**변환 시 주의점**
1. 프론트매터가 없다. YAML 블록을 넣으면 그냥 본문 텍스트로 읽힌다.
2. 32 KiB 병합 상한이 있으므로 짧게.
3. 중첩 시 가까운 파일이 이긴다. 모노레포에서 패키지별로 다른 디자인 지시를 줄 수 있다.

### 8.5 변환 시 절대 하면 안 되는 것

| 실수 | 결과 |
|---|---|
| SKILL.md에 `trigger: /designpaca` 넣기 | claude.ai 업로드/패키징 하드 에러. Windsurf `trigger`와 의미 충돌 |
| `.mdc`에 `name:` 남기기 | 문서화되지 않은 필드. 무시되거나 파싱 실패 |
| `.mdc`에서 `references/x.md` 상대 링크 유지 | Cursor가 읽지 못함. `@` 참조로 바꿔야 함 |
| Windsurf 규칙에 `alwaysApply` 넣기 | Cursor 필드다. Windsurf는 `trigger`를 쓴다 |
| AGENTS.md에 YAML 프론트매터 넣기 | 본문으로 렌더링됨 |
| SKILL.md `name`을 디렉터리명과 다르게 | 스펙 위반 ("Must match the parent directory name"). 개인/프로젝트 스킬에서는 어차피 디렉터리명이 커맨드가 되므로 혼란만 유발 |
| description에 XML 태그 | Anthropic 스펙 위반 |
| description 1,024자 초과 | Agent Skills 스펙 위반 (Claude Code는 1,536까지 받지만 표준은 1,024) |
| 참조 파일이 다른 참조 파일을 링크 | 부분 읽기(`head -100`)로 정보 유실 |
| 참조 파일 100줄 초과인데 목차 없음 | 부분 읽기 시 전체 범위를 모름 |

### 8.6 검증 체크리스트

배포 전 확인:

- [ ] `name`이 소문자+숫자+하이픈만, 64자 이내, 연속 하이픈 없음, 디렉터리명과 일치
- [ ] `description`이 1,024자 이내, 3인칭, 용도+트리거+배제 3요소
- [ ] 프론트매터에 표준 6필드 외 필드 없음
- [ ] SKILL.md 본문 500줄 이내
- [ ] 가장 중요한 규칙이 앞 100줄 안에 있음
- [ ] 모든 참조 파일이 SKILL.md에서 1단계로 링크됨
- [ ] 참조 파일 중 100줄 넘는 것에 목차 있음
- [ ] 파일 경로에 백슬래시 없음 (전부 `/`)
- [ ] `skills-ref validate ./designpaca` 통과
- [ ] Cursor `.mdc` 변환본이 500줄 이내
- [ ] Windsurf 변환본이 12,000자 이내
- [ ] Claude Code에서 `/doctor`로 스킬 목록 예산 확인

---

## 9. 확인 못한 것

- **Windsurf 공식 문서 원본**: `docs.windsurf.com`이 `docs.devin.ai`로 리다이렉트되어, 리다이렉트된 문서 기준으로 정리했다. `.windsurfrules` 단일 파일 레거시 포맷의 정확한 상한과 파싱 규칙은 리다이렉트 문서에 "legacy"로만 표기되어 있고 상세 스펙은 확인하지 못했다.
- **Cursor `.mdc`의 미문서화 필드**: 커뮤니티 문서들이 `alwaysApply`/`description`/`globs` 외 필드를 언급하기도 하지만, 공식 문서는 "No other frontmatter fields are specified"라고 한다. 미문서화 필드는 사용하지 않는 것이 안전하다.
- **`skills-ref` CLI의 실제 검증 항목 전체**: 저장소 URL만 확인했고 실행해보지 않았다.
- **Cursor Skills와 `.mdc` Rules가 동시에 있을 때의 우선순위**: 공식 문서에 명시되어 있지 않다.
