Matt Pocock Skills 저장소 심층 분석
대상 저장소: mattpocock/skills 분석 범위: engineering, productivity 카테고리 중심 (deprecated, misc, personal, in-progress 제외) 작성 기준일: 2026-05-14
목차
- 먼저 알아야 할 문서들: CONTEXT.md, ADR, LANGUAGE.md
- 제 1 장 — 왜 에이전트는 실패하는가: 문제 진단과 스킬이라는 처방전
- 제 2 장 — 스킬 해부학: 각 스킬의 의도, 구조, 동작 원리
- 부록: 주요 개념 용어집
먼저 알아야 할 문서들: CONTEXT.md, ADR, LANGUAGE.md
이 저장소의 핵심 스킬들은 단순히 “프롬프트를 잘 쓰는 법”이 아니라, 에이전트가 반복해서 참고할 문서화된 기억을 전제로 한다. 문제 #1~#4를 읽기 전에 아래 문서들의 역할을 먼저 구분하면 이후 처방전이 훨씬 덜 헷갈린다.
| 문서 | 위치 | 한 줄 정의 | 누가 주로 사용하나 |
|---|---|---|---|
| CONTEXT.md | 저장소 루트 또는 각 컨텍스트 디렉토리 | 프로젝트 고유의 도메인 용어, 관계, 모호함을 정리한 공유 언어 문서 | /grill-with-docs, /tdd, /diagnose, /improve-codebase-architecture, /zoom-out |
| CONTEXT-MAP.md | 저장소 루트 | 모노레포처럼 여러 도메인 컨텍스트가 있을 때, 각 CONTEXT.md의 위치와 관계를 알려주는 지도 |
도메인 문서를 읽는 모든 엔지니어링 스킬 |
| ADR | docs/adr/0001-slug.md 형식 |
Architecture Decision Record의 약어. 되돌리기 어렵고 맥락 없이는 이상해 보이는 아키텍처 결정을 “왜 그렇게 했는지”와 함께 기록 | /grill-with-docs, /improve-codebase-architecture, /tdd, /diagnose |
| LANGUAGE.md | improve-codebase-architecture/ 내부 |
특정 프로젝트의 도메인 언어가 아니라, 아키텍처를 논의할 때 쓰는 공통 어휘 사전 | /improve-codebase-architecture |
| docs/agents/domain.md | /setup-matt-pocock-skills가 생성 |
에이전트가 이 저장소에서 도메인 문서를 어디서 읽어야 하는지 알려주는 소비 규칙 | 설정 이후의 엔지니어링 스킬 |
CONTEXT.md는 “이 프로젝트에서 이 단어는 정확히 무엇을 뜻하는가”를 정한다. 예를 들어 커머스 코드베이스에서 Customer, User, Account가 섞이면 에이전트는 셋을 마음대로 바꿔 쓴다. CONTEXT.md는 canonical term을 하나 고르고, 피해야 할 동의어와 관계를 기록한다. 일반 프로그래밍 용어가 아니라 프로젝트 고유의 도메인 언어만 들어간다.
ADR은 Architecture Decision Record의 약어다. 데이터베이스 선택, 컨텍스트 간 통신 방식, ORM 대신 SQL을 쓰기로 한 이유처럼 나중에 다시 논쟁하기 쉬운 결정을 작게 기록한다. 이 저장소의 ADR은 거창한 템플릿이 아니라 1~3문장짜리 문서도 허용한다. 핵심은 “결정했다”와 “그 이유”를 남겨 미래의 사람과 에이전트가 같은 논쟁을 반복하지 않게 하는 것이다.
LANGUAGE.md는 CONTEXT.md와 결이 비슷하지만 대상이 다르다. CONTEXT.md가 주문, 강의, 결제 같은 비즈니스 도메인 언어라면, LANGUAGE.md는 Module, Interface, Depth, Seam, Adapter, Leverage, Locality 같은 아키텍처 분석 언어다. /improve-codebase-architecture가 component, service, API, boundary 같은 애매한 말을 피하고 같은 기준으로 리팩토링 후보를 설명하게 만든다.
관련 보조 문서도 있다. CONTEXT-FORMAT.md와 ADR-FORMAT.md는 각각 CONTEXT.md와 ADR을 어떤 형식으로 작성할지 알려주는 템플릿 문서다. docs/agents/issue-tracker.md, docs/agents/triage-labels.md, docs/agents/domain.md는 /setup-matt-pocock-skills가 만드는 저장소별 운영 설정으로, 스킬들이 이슈 트래커와 도메인 문서 위치를 찾는 데 사용한다.
제 1 장 — 왜 에이전트는 실패하는가: 문제 진단과 스킬이라는 처방전
다른 사람의 스킬을 이해하는 가장 좋은 방법은, 어떤 문제점으로부터 그 스킬이 필요해졌는지를 이해하는 것이다.
Matt Pocock은 README에서 AI 에이전트의 네 가지 구조적 실패 모드(failure mode)를 식별하고, 각 실패 모드에 대응하는 스킬을 제시한다. 이 접근은 “vibe coding”이 아닌 실제 소프트웨어 엔지니어링 원칙에 기반한다.
graph LR
A["AI 에이전트의<br/>4가지 실패 모드"] --> B["#1 Misalignment<br/>의도 불일치"]
A --> C["#2 Verbosity<br/>과도한 장황함"]
A --> D["#3 No Feedback<br/>피드백 부재"]
A --> E["#4 Big Ball of Mud<br/>구조적 부패"]
B --> B1["/grill-me"]
B --> B2["/grill-with-docs"]
C --> C1["/grill-with-docs<br/>(CONTEXT.md)"]
C --> C2["/caveman"]
D --> D1["/tdd"]
D --> D2["/diagnose"]
E --> E1["/improve-codebase-<br/>architecture"]
E --> E2["/zoom-out"]
E --> E3["/to-prd"]
style A fill:#ff6b6b,color:#fff
style B fill:#ffa07a
style C fill:#ffa07a
style D fill:#ffa07a
style E fill:#ffa07a
문제 #1: 에이전트가 내 의도를 이해하지 못한다
“No-one knows exactly what they want” — David Thomas & Andrew Hunt, The Pragmatic Programmer
문제 진단
소프트웨어 개발에서 가장 흔한 실패 모드는 미스얼라인먼트(misalignment)다. 개발자가 알고 있다고 생각하는 것과, 에이전트가 이해한 것 사이에 간극이 존재한다. 사람 간 커뮤니케이션에서도 동일한 문제가 발생하지만, AI 에이전트는 “명확해질 때까지 질문한다”는 습관이 약하기 때문에 이 간극이 더 크다.
처방전: /grill-me와 /grill-with-docs
핵심 메커니즘은 “그릴링 세션(grilling session)”이다. 에이전트가 사용자에게 설계와 계획에 대해 집요하게 질문을 던져, 의사결정 트리(decision tree)의 모든 가지를 하나씩 해소한다.
/grill-me — 범용 그릴링
SKILL.md에서 핵심 지시문을 인용하면:
“Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.”
핵심 규칙:
- 질문은 한 번에 하나씩 — 사용자가 답변한 후 다음 질문으로 진행
- 코드베이스 탐색으로 답할 수 있는 질문은 직접 탐색 — 사용자에게 불필요한 부담을 주지 않음
- 각 질문에 에이전트의 추천 답변 제시 — 사용자가 “맞다/아니다”로 빠르게 결정할 수 있음
/grill-with-docs — 도메인 인식 그릴링
/grill-me의 상위 호환. 동일한 그릴링 구조 위에 도메인 문서 관리 계층을 추가한다:
“When the user uses a term that conflicts with the existing language in CONTEXT.md, call it out immediately.”
실제 효과를 내는 메커니즘들:
| 메커니즘 | SKILL.md 근거/예시 | 의도하는 효과 |
|---|---|---|
| 용어 충돌 감지 | “Your glossary defines ‘cancellation’ as X, but you seem to mean Y — which is it?” | 도메인 용어의 일관성 강제 |
| 모호한 언어 날카롭게 만들기 | “You’re saying ‘account’ — do you mean the Customer or the User?” | 오버로드된 용어 해소 |
| 구체적 시나리오 검증 | “stress-test them with specific scenarios… Invent scenarios that probe edge cases” | 엣지 케이스를 사전에 발견 |
| 코드와 교차 검증 | “check whether the code agrees. If you find a contradiction, surface it” | 코드와 설계 사이의 불일치 탐지 |
| CONTEXT.md 즉시 업데이트 | “When a term is resolved, update CONTEXT.md right there. Don’t batch these up” | 결정이 날 때마다 문서에 즉각 반영 |
| ADR 후보 여부 판단 | 결정이 “나중에 바꾸기 어렵고”, “맥락 없이는 이상해 보이며”, “실제 대안 사이의 선택”인지 확인한다. 예: 동기 HTTP 대신 도메인 이벤트로 컨텍스트를 연결하기로 한 결정 | 미래의 사람/에이전트가 같은 논쟁을 반복하거나 의도적 결정을 되돌리지 않게 함 |
sequenceDiagram
participant U as 사용자
participant A as 에이전트
participant C as CONTEXT.md
participant ADR as docs/adr/
U->>A: "주문 취소 기능을 추가하고 싶어"
A->>A: 코드베이스 탐색
A->>C: 기존 용어 확인
A->>U: "'취소'가 Order 전체인지 개별 Item인지?"<br/>(추천: 전체 Order)
U->>A: "개별 Item도 취소 가능해야 해"
A->>C: "Cancellation" 용어 업데이트<br/>(Order-level + Item-level 구분)
A->>U: "Item 취소 시 Order 상태는?"<br/>(추천: Partial 상태 추가)
U->>A: "맞아, Partial 상태"
A->>C: "PartialCancellation" 용어 추가
Note over A,ADR: 되돌리기 어렵고,<br/>맥락 없이 놀라운 결정이면<br/>ADR 제안
문제 #2: 에이전트가 너무 장황하다
“With a ubiquitous language, conversations among developers and expressions of the code are all derived from the same domain model.” — Eric Evans, Domain-Driven Design
문제 진단
에이전트가 프로젝트에 투입될 때, 프로젝트 고유의 전문 용어(jargon)를 모른다. 그래서 한 단어로 충분한 곳에 20단어를 사용한다. 이는 단순히 출력이 길어지는 문제가 아니다:
- 변수명과 함수명이 일관되지 않고
- 코드베이스 네비게이션이 어려워지고
- 에이전트가 사고(thinking)에 불필요한 토큰을 소비한다
핵심 개념: 유비쿼터스 언어 (Ubiquitous Language)
유비쿼터스 언어는 Eric Evans의 Domain-Driven Design에서 나온 개념이다. 개발자, 도메인 전문가, 그리고 코드 자체가 동일한 용어 체계를 공유해야 한다는 원칙이다.
예를 들어, 강의 관리 시스템에서:
- Before (유비쿼터스 언어 없음): “강좌 안의 섹션 안에 있는 레슨이 파일 시스템에 실제로 배치되는 과정에 문제가 있어요”
- After (유비쿼터스 언어 적용): “materialization cascade에 문제가 있어요”
처방전: CONTEXT.md + /grill-with-docs
문제 #2의 처방은 앞 절에서 설명한 CONTEXT.md를 실제 세션 중에 계속 갱신하는 것이다. README의 표현대로, 이 문서는 에이전트가 프로젝트에서 쓰는 jargon을 해독하도록 돕는다.
CONTEXT.md의 포맷(CONTEXT-FORMAT.md에서 발췌):
# {Context Name}
{이 컨텍스트가 무엇인지, 왜 존재하는지 1-2문장}
## Language
**Order**: 고객이 접수하는 주문
_Avoid_: Purchase, transaction
**Invoice**: 배송 후 고객에게 보내는 결제 요청서
_Avoid_: Bill, payment request
## Relationships
- **Order** → 하나 이상의 **Invoice** 생성
- **Invoice** → 정확히 하나의 **Customer**에 속함
## Example dialogue
> **Dev:** "**Customer**가 **Order**를 접수하면, 즉시 **Invoice**를 만드나요?"
> **Domain expert:** "아니요 — **Fulfillment**이 확인된 후에만 **Invoice**가 생성됩니다."
## Flagged ambiguities
- "account"이 **Customer**와 **User** 모두를 가리키는 데 사용됨 — 해소: 별개 개념.
핵심 규칙(CONTEXT-FORMAT.md 인용):
“Be opinionated. When multiple words exist for the same concept, pick the best one and list the others as aliases to avoid.”
“Only include terms specific to this project’s context. General programming concepts don’t belong.”
이 문서는 /grill-with-docs 세션 중에 용어가 확정될 때마다 즉시 업데이트된다.
배치 처리하지 않는다 - 대화 중 발견한 용어 변경 사항을 메모만 해두었다가 마지막에 한꺼번에 정리하지 않는다.
예를 들어 사용자가 “account는 Customer가 아니라 로그인 주체인 User를 뜻한다”고 답하는 순간, 바로 CONTEXT.md의 Account/User/Customer 정의와 피해야 할 표현을 갱신한다.
그래야 다음 질문, 다음 코드 탐색, 다음 테스트 이름이 곧바로 새 용어 체계를 사용한다.
graph TD
subgraph "CONTEXT.md 효과"
A["용어 통일"] --> B["변수/함수/파일명<br/>일관된 명명"]
A --> C["코드베이스<br/>네비게이션 용이"]
A --> D["에이전트 사고 시<br/>토큰 절약"]
A --> E["세션 간<br/>누적 효과"]
end
subgraph "추가 문서"
F["docs/adr/<br/>Architecture Decision Records"] --> G["과거 결정의 근거 보존"]
F --> H["에이전트가 같은 결정을<br/>재논의하지 않음"]
end
style A fill:#4ecdc4,color:#fff
style F fill:#45b7d1,color:#fff
문제 #3: 코드가 작동하지 않는다
“Always take small, deliberate steps. The rate of feedback is your speed limit.” — David Thomas & Andrew Hunt, The Pragmatic Programmer
문제 진단
에이전트와 의도가 정렬되어도, 피드백 루프(feedback loop)가 없으면 코드 품질은 보장되지 않는다. 에이전트가 작성한 코드가 실제로 동작하는지에 대한 피드백 없이는, 에이전트는 시야 없이 비행(flying blind)하는 것과 같다.
핵심 개념: Red-Green-Refactor Loop
Red-Green-Refactor는 TDD(Test-Driven Development)의 핵심 리듬이다:
- RED: 실패하는 테스트를 먼저 작성
- GREEN: 테스트를 통과하는 최소한의 코드 작성
- REFACTOR: 테스트가 통과하는 상태에서 코드 구조 개선
graph LR
R["RED<br/>실패하는 테스트 작성"] --> G["GREEN<br/>최소 코드로 통과"]
G --> RF["REFACTOR<br/>구조 개선"]
RF --> R
style R fill:#e74c3c,color:#fff
style G fill:#2ecc71,color:#fff
style RF fill:#3498db,color:#fff
실체를 더 구체적으로 보면 다음과 같다.
실패하는 테스트는 “문법이 깨진 테스트”가 아니다. 아직 구현되지 않은 사용자 관찰 동작을 검증하기 때문에 실패하는 테스트다. 실패 이유도 중요하다. 함수가 없거나, 반환값이 기대와 다르거나, 아직 지원하지 않는 동작이라 실패해야 한다. 설정 오류나 오타로 실패하면 좋은 RED가 아니다.
// RED: 아직 priceCart가 할인 쿠폰을 처리하지 못하므로 실패해야 한다.
test("applies a percentage coupon to the cart total", () => {
const result = priceCart({ total: 10000 }, { type: "percent", value: 10 });
expect(result.total).toBe(9000);
});
최소 코드로 통과한다는 말은 이번 테스트가 요구한 동작만 구현한다는 뜻이다. 미래에 필요할 것 같은 쿠폰 만료, 중복 쿠폰, 통화 변환까지 미리 만들지 않는다.
// GREEN: 현재 테스트가 요구한 percent 쿠폰만 통과시킨다.
function priceCart(cart: { total: number }, coupon: { type: "percent"; value: number }) {
return {
total: cart.total - cart.total * (coupon.value / 100),
};
}
구조 개선은 테스트가 GREEN인 상태에서만 한다. 예를 들어 다음 테스트로 고정 금액 쿠폰까지 추가한 뒤 중복 계산이 보이면, 공개 인터페이스 priceCart는 유지하고 내부 계산만 분리한다.
function priceCart(cart: Cart, coupon: Coupon) {
return {
total: cart.total - calculateDiscountAmount(cart.total, coupon),
};
}
function calculateDiscountAmount(total: number, coupon: Coupon) {
if (coupon.type === "percent") return total * (coupon.value / 100);
return coupon.value;
}
이 리팩토링은 새 기능을 추가하지 않는다. 이미 통과하던 테스트가 계속 통과하는 상태에서 중복을 줄이고, 이름을 명확히 하고, 복잡도를 더 알맞은 내부 함수나 모듈 뒤로 옮기는 작업이다.
핵심 개념: Vertical Slice (수직 슬라이스)
Vertical Slice는 시스템의 모든 계층(layer)을 관통하는 얇은 기능 단위다. “UI 전체 → API 전체 → DB 전체”처럼 한 레이어씩 완성하는 수평 슬라이스와 반대다. 예를 들어 결제 기능을 만들 때 먼저 DB 스키마 전체를 완성하고, 그다음 API 전체를 만들고, 마지막에 UI를 붙이는 방식이 아니라, “유효한 장바구니 하나를 결제하면 주문이 confirmed가 된다”라는 아주 좁은 기능 하나가 UI/API/도메인/DB/테스트를 모두 통과하게 만든다.

처방전: /tdd
SKILL.md의 핵심 철학:
“Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn’t.”
이 문장은 “테스트는 내부 구현을 감시하지 말고, 사용자가 관찰할 수 있는 동작을 공개 인터페이스로 검증하라”는 뜻이다. 예를 들어 checkout() 내부에서 paymentService.process()를 호출하는지 spy로 확인하면, 결제 로직을 리팩토링하는 순간 테스트가 깨진다. 반대로 checkout(cart, paymentMethod)를 호출했을 때 주문 상태가 confirmed가 되고 영수증이 발급되는지를 검증하면, 내부 구현이 함수형이든 클래스로 바뀌든 테스트는 유지된다.
TDD 스킬이 강제하는 Anti-Pattern 방지(SKILL.md 인용):
“DO NOT write all tests first, then all implementation. This is ‘horizontal slicing’ — treating RED as ‘write all tests’ and GREEN as ‘write all code.’ This produces crap tests.”
이 말은 “테스트를 먼저 쓰라”를 “상상 가능한 테스트를 전부 한 번에 쓰라”로 오해하지 말라는 뜻이다. 한 번에 테스트 20개를 쓰면 실제 구현을 배우기 전에 테스트 구조를 고정하게 된다. 그러면 테스트가 사용자 동작보다 데이터 모양, 함수 이름, 내부 호출 순서에 묶이기 쉽다.
올바른 접근(Vertical Slice via Tracer Bullet):
RIGHT (vertical):
RED→GREEN: test1→impl1
RED→GREEN: test2→impl2
RED→GREEN: test3→impl3
좋은 테스트 vs 나쁜 테스트 (tests.md 인용):
| 구분 | 좋은 테스트 | 나쁜 테스트 |
|---|---|---|
| 대상 | 공개 인터페이스를 통한 동작 검증 | 내부 구현 세부사항 검증 |
| 생존성 | 리팩토링 후에도 통과 | 리팩토링하면 깨짐 |
| 읽기 | 스펙처럼 읽힘 (“user can checkout with valid cart”) | 구현 방법 기술 (“checkout calls paymentService.process”) |
| 모킹 | 시스템 경계에서만 (외부 API, DB) | 내부 모듈끼리 모킹 |
예를 들어 좋은 테스트는 “유효한 쿠폰을 적용하면 총액이 할인된다”라고 말한다. 나쁜 테스트는 “CouponService.calculate()가 정확히 한 번 호출된다”라고 말한다. 전자는 비즈니스 동작을 보호하고, 후자는 현재 구현 방식을 얼려버린다.
처방전: /diagnose
SKILL.md에서 가장 강력한 선언:
“This is the skill. Everything else is mechanical. If you have a fast, deterministic, agent-runnable pass/fail signal for the bug, you will find the cause.”
이 선언에서 말하는 핵심은, 버그를 잡기 전에 먼저 버그가 아직 존재하는지 자동으로 판정하는 장치를 만들라는 것이다. 여기서 pass/fail 신호는 “고쳤는지 아닌지”를 사람이 감으로 판단하지 않아도 알려주는 실행 가능한 확인 방법이다. 빠르다는 것은 여러 번 돌려도 부담이 없다는 뜻이고, deterministic하다는 것은 같은 코드와 같은 입력이면 같은 결과가 나온다는 뜻이며, agent-runnable하다는 것은 에이전트가 직접 명령어, 테스트, 스크립트로 실행할 수 있다는 뜻이다.
예를 들어 “쿠폰이 두 번 적용된다”는 버그가 있으면, 좋은 신호는 pnpm test coupon-replay처럼 실행했을 때 버그가 있으면 빨간색으로 실패하고, 고치면 초록색으로 통과하는 테스트다. 나쁜 신호는 “브라우저에서 몇 번 눌러보면 가끔 이상하다”처럼 느리고, 사람 손이 필요하고, 성공/실패 기준이 흐린 확인 방식이다. 좋은 신호가 있으면 에이전트는 가설을 하나씩 검증할 수 있다. 신호가 없으면 수정처럼 보이는 변경을 해도 실제 버그를 고쳤는지 알 수 없다.
6단계 진단 루프:
graph TD
P1["Phase 1<br/>피드백 루프 구축"] --> P2["Phase 2<br/>재현"]
P2 --> P3["Phase 3<br/>가설 수립<br/>(3~5개, 순위 매기기)"]
P3 --> P4["Phase 4<br/>계측<br/>(한 번에 하나의 변수)"]
P4 --> P5["Phase 5<br/>수정 + 회귀 테스트"]
P5 --> P6["Phase 6<br/>정리 + 사후 분석"]
P1 -. "루프 없으면 멈추고<br/>사용자에게 알림" .-> STOP["STOP"]
P6 -. "아키텍처 문제 발견 시" .-> ICA["/improve-codebase-<br/>architecture로 핸드오프"]
style P1 fill:#e74c3c,color:#fff
style P3 fill:#f39c12,color:#fff
style P5 fill:#2ecc71,color:#fff
style STOP fill:#95a5a6,color:#fff
여기서 회귀 테스트(regression test)는 “한 번 고친 버그가 다시 생기면 바로 실패하는 테스트”다. 버그 수정 직전에 그 버그를 재현하는 테스트를 추가하고, 먼저 실패하는지 확인한 뒤, 수정 후 통과하게 만든다. 이렇게 하면 이번 수정이 우연히 증상을 가린 것인지 실제 원인을 막은 것인지 확인할 수 있고, 미래의 변경이 같은 버그를 되살리면 테스트가 즉시 알려준다.
예시로 “쿠폰이 가끔 두 번 적용되어 결제 금액이 10%가 아니라 20% 할인된다”는 버그를 진단한다고 하자.
| Phase | 실제 예시 |
|---|---|
| 1. 피드백 루프 구축 | 장바구니 생성 → 쿠폰 적용 → 체크아웃 API 호출 → 총액이 9000원인지 확인하는 통합 테스트나 curl 스크립트를 만든다. 사람이 브라우저를 클릭해야만 재현된다면 Playwright나 HITL 스크립트로 반복 가능하게 만든다. |
| 2. 재현 | 루프를 여러 번 실행해 사용자가 말한 증상과 같은 실패인지 확인한다. 예를 들어 기대값 9000원인데 실제 8000원이 나오는지, 아니면 전혀 다른 500 에러인지 구분한다. |
| 3. 가설 수립 | 3~5개 가설을 순위로 세운다. 예: 1) 쿠폰 이벤트가 두 번 처리된다. 2) 재시도 로직이 idempotency key를 잃는다. 3) 프론트엔드가 Apply 버튼을 중복 제출한다. 각 가설은 “X가 원인이면 Y를 바꾸면 실패가 사라진다”처럼 반증 가능해야 한다. |
| 4. 계측 | [DEBUG-coupon-replay] 같은 고유 태그로 주문 생성, 쿠폰 적용, 결제 직전 금액 경계에만 로그를 넣는다. 한 번에 한 변수만 바꿔 어떤 가설이 맞는지 확인한다. |
| 5. 수정 + 회귀 테스트 | 실제 원인이 이벤트 중복 처리라면, 먼저 “같은 쿠폰 이벤트를 두 번 replay해도 총액은 한 번만 할인된다”는 테스트를 만든다. 이 테스트는 수정 전에는 8000원이 나와 실패해야 한다. 그다음 이벤트 ID나 idempotency key를 기준으로 이미 처리한 쿠폰 이벤트를 무시하도록 고친다. 수정 후 같은 테스트가 9000원으로 통과하면, 버그를 재현하던 사례가 테스트로 잠겼다는 뜻이다. 마지막으로 원래의 더 큰 피드백 루프도 다시 실행해 실제 사용자 시나리오에서도 문제가 사라졌는지 확인한다. |
| 6. 정리 + 사후 분석 | 디버그 로그를 모두 제거하고, 원래 루프와 새 회귀 테스트를 다시 실행한다. 좋은 테스트 seam이 없어서 임시 하네스로만 막았다면, 그 사실을 기록하고 /improve-codebase-architecture로 구조 개선 후보를 넘긴다. |
“Build the right feedback loop, and the bug is 90% fixed.”
문제 #4: 진흙 덩어리를 만들었다
“Invest in the design of the system every day.” — Kent Beck, Extreme Programming Explained
“The best modules are deep. They allow a lot of functionality to be accessed through a simple interface.” — John Ousterhout, A Philosophy of Software Design
문제 진단
에이전트가 코딩 속도를 급격히 높이면, 소프트웨어 엔트로피(software entropy)도 전례 없는 속도로 가속된다. 결과물은 복잡하고 변경하기 어려운 코드베이스, 즉 “Big Ball of Mud”가 된다.
핵심 개념: Deep Module vs Shallow Module
John Ousterhout의 A Philosophy of Software Design에서 나온 개념이다. Deep Module은 작은 인터페이스 뒤에 많은 동작과 복잡도를 숨긴다. 호출자는 적은 것만 알면 큰 기능을 얻는다. Shallow Module은 반대로 인터페이스가 구현만큼 복잡하다. 호출자가 알아야 할 것이 많고, 모듈 안에는 전달(pass-through) 로직만 얇게 있다.
예를 들어 주문 가격 계산을 생각해보자.
| 형태 | 예시 | 결과 |
|---|---|---|
| Deep Module | priceOrder(order, pricingContext) 하나가 쿠폰, 세금, 반올림, 통화 규칙, 예외 조건을 내부에 숨김 |
호출자는 가격 계산 규칙을 몰라도 되고, 테스트도 가격 계산 인터페이스 하나를 통과하면 됨 |
| Shallow Module | 호출자가 validateCoupon, applyCoupon, calculateTax, roundMoney, convertCurrency를 순서대로 직접 호출하고 중간 상태를 관리 |
파일은 나뉘었지만 복잡도는 호출자에게 남아 있음. 호출 순서가 바뀌면 버그가 나고, 테스트도 내부 단계에 묶임 |
중요한 점은 “파일이 작다”가 곧 좋은 설계가 아니라는 것이다. 작은 함수가 많아도 호출자가 조립법을 전부 알아야 하면 shallow하다. 반대로 내부 구현이 길어도 인터페이스가 작고 호출자에게 높은 레버리지를 제공하면 deep할 수 있다.

처방전: /improve-codebase-architecture
SKILL.md의 목적:
“Surface architectural friction and propose deepening opportunities — refactors that turn shallow modules into deep ones. The aim is testability and AI-navigability.”
이 스킬은 “코드를 더 예쁘게 정리하자”가 아니라, 코드를 이해하고 변경하고 테스트할 때 실제로 마찰이 생기는 지점을 찾는다. 그리고 그 마찰을 줄이기 위해 shallow module을 deep module로 바꾸는 리팩토링 후보를 제안한다. 목표는 두 가지다. 테스트가 내부 구현이 아니라 올바른 인터페이스를 통과하게 만들고, 에이전트가 코드베이스를 탐색할 때 덜 헤매게 만드는 것이다.
이 스킬은 전용 아키텍처 용어 사전(LANGUAGE.md)을 사용한다. 아래 표는 스킬이 아키텍처 제안을 할 때 반드시 같은 의미로 쓰도록 고정한 어휘 목록이다.
| 용어 | 정의 | 사용 금지 동의어 |
|---|---|---|
| Module | 인터페이스와 구현을 가진 모든 것 (함수, 클래스, 패키지) | unit, component, service |
| Interface | 호출자가 알아야 할 모든 것 (타입 + 불변식 + 에러 모드 + 설정) | API, signature |
| Depth | 인터페이스 대비 레버리지의 크기 | — |
| Seam | 인터페이스가 존재하는 위치 (Michael Feathers) | boundary |
| Adapter | Seam에서 인터페이스를 만족시키는 구체적인 것 | — |
| Leverage | 호출자가 Depth로부터 얻는 것 | — |
| Locality | 유지보수자가 Depth로부터 얻는 것 (변경/버그/지식의 집중) | — |
“사용 금지 동의어”는 일상적으로 비슷해 보이지만 이 스킬의 분석에서는 의미를 흐리기 쉬운 단어들이다.
예를 들어 여기서 Interface는 TypeScript interface나 함수 시그니처만 뜻하지 않는 넓은 범주의 용어이기 때문에 API나 signature로 바꿔 쓰지 않는다.
Deletion Test (LANGUAGE.md 인용):
“Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep.”
Deletion Test는 “이 모듈을 지우면 복잡도가 어디로 가는가”를 묻는 사고 실험이다. 모듈을 삭제했는데 호출자 코드가 오히려 단순해지거나 별 변화가 없다면, 그 모듈은 복잡도를 숨기지 못하고 이름만 붙인 pass-through였을 가능성이 크다. 반대로 모듈을 삭제하는 순간 같은 로직이 여러 호출자에 복제되고, 호출 순서와 예외 처리가 여기저기 퍼진다면, 그 모듈은 자기 역할을 하고 있던 것이다.
예를 들어 OrderPricing을 지웠더니 모든 checkout, quote, invoice 코드가 쿠폰/세금/반올림 규칙을 직접 알아야 한다면 OrderPricing은 가치 있는 deep module이다. 반대로 OrderPricing.calculate()가 단순히 calculateOrderPricing() 한 줄을 다시 호출할 뿐이고 호출자가 여전히 모든 플래그와 중간값을 조립해야 한다면 shallow module이다.
3단계 프로세스(탐색 → 후보 제시 → 그릴링 루프)는 다음처럼 작동한다.
| 단계 | 의미 | 예시 |
|---|---|---|
| 1. Explore | CONTEXT.md와 ADR을 읽고 코드베이스를 유기적으로 탐색하며 마찰 지점을 찾는다 |
결제 금액을 이해하려면 CouponRules, TaxHelpers, CurrencyFormatter, CheckoutController를 계속 왕복해야 한다는 사실을 발견 |
| 2. Present candidates | deepening opportunity를 번호 목록으로 제시한다. 아직 인터페이스 설계안은 내지 않는다 | “1. 가격 계산 규칙을 OrderPricing 모듈 뒤로 모으기 — locality가 생기고 테스트 seam이 명확해짐” |
| 3. Grilling loop | 사용자가 고른 후보에 대해 설계 트리를 질문으로 좁힌다 | OrderPricing의 입력은 Order 전체인가, 가격에 필요한 스냅샷인가? 세금 서비스는 내부 adapter인가 외부 port인가? 어떤 테스트가 인터페이스를 통과해야 하는가? |
이 과정에서 새 도메인 용어가 확정되면 CONTEXT.md를 갱신하고, 사용자가 특정 리팩토링 후보를 중요한 이유로 거절하면 ADR로 남길지 제안한다. 예를 들어 “가격 계산을 모듈화하지 않는 이유가 외부 파트너 계약상 계산 단계별 감사 로그가 필요하기 때문”이라면, 미래의 아키텍처 리뷰가 같은 제안을 반복하지 않도록 ADR 후보가 된다.
보조 스킬들
/zoom-out — 코드의 상위 추상화 계층을 보여줌:
“Go up a layer of abstraction. Give me a map of all the relevant modules and callers, using the project’s domain glossary vocabulary.”
disable-model-invocation: true 플래그가 설정되어 있어, 별도 모델 호출 없이 즉시 동작한다.
/to-prd — 대화 맥락을 PRD로 변환 (모듈 설계 포함):
“Sketch out the major modules you will need to build or modify… Actively look for opportunities to extract deep modules that can be tested in isolation.”
문제-해결 전체 맵
flowchart TB
subgraph "개발 라이프사이클"
direction TB
PLAN["계획 수립"] --> ALIGN["정렬 확인"]
ALIGN --> BUILD["구현"]
BUILD --> VERIFY["검증"]
VERIFY --> MAINTAIN["유지보수"]
MAINTAIN -.-> PLAN
end
subgraph "스킬 매핑"
direction TB
S1["/grill-me<br/>/grill-with-docs"] --> S2["/to-prd"]
S2 --> S3["/to-issues"]
S3 --> S4["/tdd<br/>/prototype"]
S4 --> S5["/diagnose"]
S5 --> S6["/improve-codebase-<br/>architecture<br/>/zoom-out"]
S6 -.-> S1
end
PLAN --- S1
PLAN --- S2
ALIGN --- S3
BUILD --- S4
VERIFY --- S5
MAINTAIN --- S6
subgraph "보조 인프라"
T1["/triage<br/>(이슈 관리)"]
T2["/setup-matt-pocock-skills<br/>(저장소 설정)"]
T3["/handoff<br/>(세션 인계)"]
T4["/caveman<br/>(토큰 절약)"]
end

제 2 장 — 스킬 해부학: 각 스킬의 의도, 구조, 동작 원리
어떠한 스킬을 잘 사용하려면, 그 스킬의 의도(why)와 목적(what), 그리고 동작 메커니즘(how) 대해 잘 알아야 한다.
Engineering 스킬
매일 코드 작업에 사용하는 핵심 스킬들.
/grill-with-docs
역할: 도메인 모델과 대조하며 계획을 검증하는 그릴링 세션. CONTEXT.md와 ADR을 실시간 갱신.
트리거: 프로젝트의 언어 체계와 문서화된 결정에 대해 계획을 스트레스 테스트하고 싶을 때.
동작 순서:
graph TD
A["1. 계획에 대해<br/>집요하게 질문 시작"] --> B["2. 코드베이스 탐색<br/>(가능한 질문은 직접 확인)"]
B --> C["3. 용어 충돌 감지<br/>(CONTEXT.md 대조)"]
C --> D["4. 모호한 용어 선명화<br/>(정확한 canonical term 제안)"]
D --> E["5. 구체적 시나리오로<br/>엣지 케이스 검증"]
E --> F["6. 코드와 교차 검증<br/>(코드 vs 사용자 발언)"]
F --> G{용어 확정?}
G -->|Yes| H["CONTEXT.md<br/>즉시 업데이트"]
G -->|No| A
H --> I{되돌리기 어렵고<br/>놀랍고 트레이드오프?}
I -->|3가지 모두 Yes| J["ADR 제안"]
I -->|No| A
결과물: 정련된 계획 + 갱신된 CONTEXT.md + (선택적) ADR 문서
보조 파일:
CONTEXT-FORMAT.md— CONTEXT.md의 정확한 포맷 정의ADR-FORMAT.md— ADR의 최소 포맷 (docs/adr/0001-slug.md)
ADR 작성 기준 (ADR-FORMAT.md 인용):
세 조건이 모두 참일 때만:
- “Hard to reverse” — 나중에 바꾸는 비용이 의미 있을 때
- “Surprising without context” — 미래 독자가 “왜 이렇게 했지?” 할 때
- “The result of a real trade-off” — 진짜 대안이 있었고 이유가 있어서 선택했을 때
/tdd
역할: Red-Green-Refactor 루프 기반의 테스트 주도 개발. Vertical Slice 단위로 기능을 구축하거나 버그를 수정.
트리거: TDD, red-green-refactor, 테스트 우선 개발, 통합 테스트 요청 시.
동작 순서:
graph TD
P["1. Planning<br/>- 인터페이스 변경 확인<br/>- 테스트할 동작 합의<br/>- Deep module 기회 탐색<br/>- 사용자 승인"] --> T["2. Tracer Bullet<br/>첫 번째 동작에 대해<br/>RED→GREEN 1회"]
T --> L["3. Incremental Loop<br/>나머지 동작 각각<br/>RED→GREEN 반복"]
L --> R["4. Refactor<br/>모든 테스트 통과 상태에서<br/>구조 개선"]
R -. "새로운 동작 발견" .-> L
사이클별 체크리스트 (SKILL.md 인용):
[ ] Test describes behavior, not implementation
[ ] Test uses public interface only
[ ] Test would survive internal refactor
[ ] Code is minimal for this test
[ ] No speculative features added
보조 파일 체계:
| 파일 | 내용 |
|---|---|
tests.md |
좋은 테스트 vs 나쁜 테스트 예시 (코드 포함) |
mocking.md |
모킹 가이드: 시스템 경계에서만, DI 활용, SDK 스타일 인터페이스 |
deep-modules.md |
Deep Module 개념 설명과 ASCII 다이어그램 |
interface-design.md |
테스트 용이한 인터페이스 설계 3원칙 |
refactoring.md |
리팩토링 후보 목록 (중복, 긴 메서드, shallow module, feature envy, primitive obsession) |
/diagnose
역할: 어려운 버그와 성능 회귀에 대한 체계적 진단 루프.
트리거: “이거 디버깅해줘”, 버그 리포트, 뭔가 깨짐/실패/에러 발생, 성능 회귀 시.
동작 순서:
| Phase | 이름 | 핵심 행동 | 선행 조건 |
|---|---|---|---|
| 1 | 피드백 루프 구축 | 10가지 방법 중 택1로 agent-runnable pass/fail 신호 생성 | — |
| 2 | 재현 | 루프 실행, 버그 확인. 사용자 묘사와 동일한 실패인지 확인 | Phase 1 완료 |
| 3 | 가설 수립 | 3~5개 순위 매겨진 가설 생성. 각각 falsifiable 예측 포함. 사용자에게 보여주기 | Phase 2 완료 |
| 4 | 계측 | 한 번에 하나의 변수만 변경. 디버거 > 타겟 로그 > 전체 로그. 디버그 로그에 [DEBUG-xxxx] 태그 |
Phase 3 완료 |
| 5 | 수정 + 회귀 테스트 | 올바른 seam이 있으면 회귀 테스트를 먼저 작성. 없으면 발견 사항으로 기록 | Phase 4 완료 |
| 6 | 정리 + 사후 분석 | 디버그 로그 제거, 프로토타입 삭제, 올바른 가설을 커밋 메시지에 기록 | Phase 5 완료 |
Phase 6에서 /improve-codebase-architecture로 핸드오프 (SKILL.md 인용):
“Then ask: what would have prevented this bug? If the answer involves architectural change… hand off to the
/improve-codebase-architectureskill with the specifics.”
/triage
역할: 이슈 트래커의 이슈를 상태 머신(state machine)을 통해 분류/관리.
트리거: 이슈 생성, 트리아지, 버그/기능요청 리뷰, AFK 에이전트용 이슈 준비 시.
상태 머신:
stateDiagram-v2
[*] --> Unlabeled : 새 이슈
Unlabeled --> needs_triage : 초기 분류
needs_triage --> needs_info : 정보 부족
needs_triage --> ready_for_agent : AFK 에이전트 가능
needs_triage --> ready_for_human : 사람 필요
needs_triage --> wontfix : 미조치
needs_info --> needs_triage : 리포터 응답
state "Category" as cat {
bug : bug (버그)
enhancement : enhancement (개선)
}
note right of ready_for_agent
Agent Brief 코멘트 작성
(AGENT-BRIEF.md 참조)
end note
note right of wontfix
enhancement → .out-of-scope/ 기록
bug → 정중한 설명 후 닫기
end note
보조 파일:
AGENT-BRIEF.md— AFK 에이전트를 위한 브리프 작성법 (내구성 > 정밀도, 동작 기반, 파일 경로 금지)OUT-OF-SCOPE.md— 거절된 기능 요청을.out-of-scope/디렉토리에 기록하는 지식 베이스
AI 면책 조항 (SKILL.md 인용):
모든 코멘트/이슈에 반드시 포함: ”> *This was generated by AI during triage.”*
/improve-codebase-architecture
역할: 코드베이스의 Shallow Module을 Deep Module로 전환하는 리팩토링 기회 발견.
트리거: 아키텍처 개선, 리팩토링 기회 탐색, 모듈 통합, 테스트 용이성/AI 네비게이션 향상 시.
동작 순서:
graph TD
E["1. Explore<br/>CONTEXT.md + ADR 읽기<br/>→ 코드베이스 유기적 탐색<br/>→ 마찰 지점 기록"] --> P["2. Present Candidates<br/>번호 매긴 deepening<br/>opportunity 목록 제시"]
P --> Q["사용자에게: '어떤 걸 탐색할래요?'"]
Q --> G["3. Grilling Loop<br/>선택된 후보에 대해<br/>설계 트리 탐색"]
G --> G1["CONTEXT.md 용어 갱신<br/>(필요시)"]
G --> G2["ADR 제안<br/>(거절 사유가 load-bearing일 때)"]
G --> G3["인터페이스 대안 탐색<br/>(INTERFACE-DESIGN.md)"]
인터페이스 설계 탐색 (INTERFACE-DESIGN.md 인용):
“Design It Twice” (Ousterhout) 원칙 기반으로, 3개 이상의 병렬 서브 에이전트를 생성하여 각각 급진적으로 다른 인터페이스를 설계:
- Agent 1: 최소 인터페이스 (1-3 entry point)
- Agent 2: 최대 유연성
- Agent 3: 가장 흔한 호출자에 최적화
- Agent 4: Ports & Adapters 패턴
탐색 시 확인하는 마찰 지점 (SKILL.md 인용):
- 하나의 개념을 이해하기 위해 여러 작은 모듈을 오가야 하는 곳
- 인터페이스가 구현만큼 복잡한 Shallow Module
- 테스트 용이성만을 위해 추출된 순수 함수 (진짜 버그는 호출 방식에 숨어 있는데)
- Seam을 넘어 누수되는 결합
/to-prd
역할: 현재 대화 맥락을 PRD(Product Requirements Document)로 합성하여 이슈 트래커에 게시.
트리거: 현재 컨텍스트에서 PRD 생성 요청 시.
핵심 특징: 사용자를 인터뷰하지 않는다. 이미 논의된 내용을 합성만 한다.
동작 순서:
- 코드베이스 탐색 (CONTEXT.md 용어 사용)
- 주요 모듈 스케치 — Deep Module 추출 기회 적극 탐색. 사용자에게 모듈 구조와 테스트 대상 확인
- PRD 템플릿으로 작성 → 이슈 트래커에
ready-for-agent레이블로 게시
PRD 템플릿 구조:
- Problem Statement → Solution → User Stories (광범위하게) → Implementation Decisions → Testing Decisions → Out of Scope → Further Notes
프로토타입 코드 인용 (SKILL.md 인용):
“Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it… Trim to the decision-rich parts.”
/to-issues
역할: 계획/스펙/PRD를 이슈 트래커의 독립적인 이슈들로 분해. Vertical Slice (Tracer Bullet) 방식.
트리거: 계획을 이슈로 변환, 구현 티켓 생성, 작업 분해 요청 시.
동작 순서:
graph TD
G["1. Gather Context<br/>대화 컨텍스트 또는<br/>이슈 참조 가져오기"] --> E["2. Explore Codebase<br/>(선택, 미탐색 시)"]
E --> D["3. Draft Vertical Slices<br/>HITL vs AFK 분류<br/>의존관계 설정"]
D --> Q["4. Quiz User<br/>- 입도 적절?<br/>- 의존관계 정확?<br/>- 합칠/쪼갤 것?"]
Q -->|반복| D
Q -->|승인| P["5. Publish Issues<br/>의존 순서대로 게시<br/>(blocker 먼저)"]
Vertical Slice 규칙 (SKILL.md 인용):
- “Each slice delivers a narrow but COMPLETE path through every layer (schema, API, UI, tests)”
- “A completed slice is demoable or verifiable on its own”
- “Prefer many thin slices over few thick ones”
HITL vs AFK:
- HITL (Human-In-The-Loop): 아키텍처 결정, 디자인 리뷰 등 사람의 개입 필요
- AFK (Away From Keyboard): 사람 개입 없이 에이전트가 구현+머지 가능
/prototype
역할: 설계 결정을 검증하기 위한 일회용 프로토타입 구축.
트리거: “프로토타입 해줘”, “이 데이터 모델 확인해볼래”, “UI 몇 가지 옵션 보여줘”, “한번 만져보고 싶어” 등.
두 갈래 분기:
graph TD
Q["질문이 뭐야?"] --> L{"'이 로직/상태 모델이<br/>맞는 느낌이야?'"}
Q --> U{"'이게 어떻게<br/>보여야 해?'"}
L --> LOGIC["LOGIC 브랜치<br/>인터랙티브 터미널 앱<br/>(TUI)"]
U --> UI["UI 브랜치<br/>여러 급진적 변형<br/>+ 전환 바"]
LOGIC --> L1["순수 리듀서/상태머신<br/>+ 키보드 단축키<br/>+ 상태 시각화"]
UI --> U1["Sub-shape A: 기존 페이지<br/>에서 ?variant= 파라미터<br/>(선호)"]
UI --> U2["Sub-shape B: 새 페이지<br/>(정말 갈 곳 없을 때만)"]
공통 규칙 (SKILL.md 인용):
- “Throwaway from day one, and clearly marked as such”
- “One command to run”
- “No persistence by default”
- “Skip the polish. No tests, no error handling”
- “Surface the state”
- “Delete or absorb when done”
LOGIC 브랜치의 핵심 (LOGIC.md 인용):
“Put the actual logic behind a small, pure interface that could be lifted out and dropped into the real codebase later. The TUI around it is throwaway; the logic module shouldn’t be.”
로직은 순수(pure)하게, TUI는 얇은 셸(shell)로. 프로토타입의 가치는 TUI가 아니라 검증된 로직 모듈.
UI 브랜치의 핵심 (UI.md 인용):
“Variants must be structurally different — different layout, different information hierarchy, different primary affordance, not just different colours.”
3개 이상의 급진적으로 다른 변형을, floating bottom bar로 전환하며 비교. ?variant= URL 파라미터로 공유 가능.
/zoom-out
역할: 코드의 상위 추상화 계층 맵 제공.
트리거: 코드 영역에 익숙하지 않거나, 전체 그림에서 어떻게 맞는지 이해하고 싶을 때.
전체 SKILL.md:
“I don’t know this area of code well. Go up a layer of abstraction. Give me a map of all the relevant modules and callers, using the project’s domain glossary vocabulary.”
disable-model-invocation: true — 별도 모델 호출 없이 즉시 적용되는 인라인 지시문. 가장 짧은 스킬이지만, 에이전트가 코드를 설명할 때의 추상화 수준을 즉시 끌어올리는 효과가 있다.
/setup-matt-pocock-skills
역할: 다른 엔지니어링 스킬들이 참조하는 저장소별 설정 스캐폴딩.
트리거: 저장소에서 처음 mattpocock 스킬을 사용할 때. to-issues, to-prd, triage, diagnose, tdd, improve-codebase-architecture, zoom-out 사용 전 1회 실행.
설정 3가지 (순서대로 하나씩 사용자에게 질문):
| 설정 | 설명 | 옵션 |
|---|---|---|
| A. Issue Tracker | 이슈가 어디에 있는지 | GitHub, GitLab, Local markdown, Other |
| B. Triage Labels | 5개 canonical role의 실제 레이블 문자열 | 기본값: needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix |
| C. Domain Docs | CONTEXT.md 레이아웃 | Single-context (대부분), Multi-context (모노레포) |
결과물: CLAUDE.md(또는 AGENTS.md)에 ## Agent skills 블록 추가 + docs/agents/ 하위 3개 파일 생성.
Productivity 스킬
코드에 특정되지 않는 일반 워크플로우 도구들.
/grill-me
역할: 계획이나 설계에 대해 집요하게 인터뷰하여, 의사결정 트리의 모든 가지를 해소.
트리거: 계획 스트레스 테스트, 설계 검증, “grill me” 언급 시.
전체 SKILL.md 지시문:
“Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.”
“Ask the questions one at a time.”
“If a question can be answered by exploring the codebase, explore the codebase instead.”
/grill-with-docs와의 차이: 도메인 문서 관리(CONTEXT.md, ADR)가 없다. 코드 외 용도(비즈니스 전략, 글쓰기 계획 등)에도 사용 가능한 범용 그릴링.
/caveman
역할: 초압축 커뮤니케이션 모드. 토큰 사용량 ~75% 절감.
트리거: “caveman mode”, “less tokens”, “be brief”, /caveman 호출 시.
규칙 (SKILL.md 인용):
“Drop: articles (a/an/the), filler (just/really/basically), pleasantries (sure/certainly/of course), hedging.”
“Technical terms stay exact. Code blocks unchanged. Errors quoted exact.”
Before → After 예시:
| Before | After |
|---|---|
| “Sure! I’d be happy to help you with that. The issue you’re experiencing is likely caused by…” | “Bug in auth middleware. Token expiry check use < not <=. Fix:” |
| “The reason your React component is re-rendering is because you’re passing inline objects as props, which creates a new reference each time.” | “Inline obj prop -> new ref -> re-render. useMemo.” |
Auto-Clarity Exception: 보안 경고, 되돌릴 수 없는 작업 확인, 순서가 중요한 다단계 시퀀스에서는 일시적으로 caveman 해제.
지속성: 한 번 활성화되면 “stop caveman” 또는 “normal mode” 전까지 모든 응답에 적용. 여러 턴이 지나도 자동 해제되지 않음.
/handoff
역할: 현재 대화를 핸드오프 문서로 압축하여, 다른 에이전트가 이어서 작업 가능하게 함.
트리거: 세션 인계 요청 시.
동작:
mktemp -t handoff-XXXXXX.md로 파일 생성- 현재 대화를 요약 (다른 아티팩트—PRD, ADR, 이슈, 커밋, diff—에 이미 있는 내용은 중복하지 않고 경로/URL로 참조)
- 다음 세션에서 사용할 스킬 추천
- 사용자가 인수를 전달하면, 다음 세션의 초점에 맞춰 문서 조정
/write-a-skill
역할: 적절한 구조, progressive disclosure, 번들 리소스를 갖춘 새 스킬 생성.
트리거: 스킬 생성/작성/빌드 요청 시.
프로세스:
graph TD
R["1. Gather Requirements<br/>- 도메인/태스크<br/>- 유스케이스<br/>- 스크립트 필요?<br/>- 참조 자료?"] --> D["2. Draft the Skill<br/>SKILL.md + 보조 파일"]
D --> V["3. Review with User<br/>커버리지, 누락, 상세도"]
스킬 구조:
skill-name/
├── SKILL.md # 메인 지시문 (필수)
├── REFERENCE.md # 상세 문서 (필요시)
├── EXAMPLES.md # 사용 예시 (필요시)
└── scripts/ # 유틸리티 스크립트 (필요시)
└── helper.js
Description 작성 요건 (SKILL.md 인용):
“The description is the only thing your agent sees when deciding which skill to load.”
- 최대 1024자
- 3인칭으로 작성
- 첫 문장: 기능 설명
- 둘째 문장: “Use when [특정 트리거]”
분할 기준:
- SKILL.md가 100줄을 초과하면 별도 파일로 분리
- 고급 기능은 별도 참조 파일로
리뷰 체크리스트:
[ ] Description includes triggers ("Use when...")
[ ] SKILL.md under 100 lines
[ ] No time-sensitive info
[ ] Consistent terminology
[ ] Concrete examples included
[ ] References one level deep
Anthropic skill-creator와의 압축 비교:
기존 비교 분석 섹션의 핵심만 이 항목에 병합하면, /write-a-skill은 가볍고 수동적인 스킬 작성 가이드이고 Anthropic의 skill-creator는 평가와 최적화를 포함한 대형 제작 프레임워크다.
| 차원 | /write-a-skill |
Anthropic skill-creator |
|---|---|---|
| 철학 | 좋은 스킬은 명확하게 쓴 작업 지시문 | 좋은 스킬은 eval로 성능을 측정하고 개선하는 산출물 |
| 규모 | SKILL.md 중심, 보조 파일은 필요할 때만 |
SKILL.md + eval/benchmark/분석 스크립트 + 보조 에이전트 |
| 검증 | 사용자 리뷰와 체크리스트 | baseline 대비 with-skill 실행, grader/comparator/analyzer로 자동 평가 |
| 강점 | 빠르게 만들고 이해하기 쉬움 | 트리거 정확도, 성능 분산, 품질 개선을 정량적으로 다룸 |
| 적합한 상황 | 개인 프로젝트, 빠른 워크플로우 캡슐화, 스킬 작성 원칙 학습 | 팀 배포, 품질 보증, 많은 스킬 중 정확한 선택이 중요한 환경 |
특히 가장 큰 차이는 description 최적화다. /write-a-skill은 “첫 문장은 기능, 둘째 문장은 Use when 트리거”처럼 사람이 잘 쓰도록 가이드한다. Anthropic skill-creator는 should-trigger/should-not-trigger 쿼리를 만들고 반복 평가해 description을 자동으로 개선하는 쪽에 가깝다. 따라서 이 저장소의 /write-a-skill은 빠른 제작과 작문 원칙에 강하고, Anthropic 방식은 운영 환경에서 성능을 계측하며 다듬는 데 강하다.
부록: 주요 개념 용어집
| 영어 용어 | 한국어 설명 |
|---|---|
| Agent Loop | 에이전트가 도구 호출 → 결과 관찰 → 다음 행동 결정을 반복하는 루프. 스킬은 이 루프의 각 반복에서 에이전트의 행동을 구조화한다. |
| Red-Green-Refactor Loop | TDD의 핵심 리듬. 실패하는 테스트(Red) → 최소 코드로 통과(Green) → 구조 개선(Refactor)을 반복. |
| Vertical Slice | 시스템의 모든 계층(UI, API, DB, 테스트)을 관통하는 얇은 기능 단위. Horizontal Slice(한 계층씩 완성)의 반대. |
| Tracer Bullet | The Pragmatic Programmer에서 유래. 전체 경로를 관통하는 최소한의 end-to-end 구현. 첫 Vertical Slice. |
| Deep Module | A Philosophy of Software Design에서 유래. 작은 인터페이스 뒤에 많은 기능을 숨기는 모듈. 높은 레버리지. |
| Shallow Module | 인터페이스가 구현만큼 복잡한 모듈. 추상화의 가치가 낮음. |
| Ubiquitous Language | Domain-Driven Design에서 유래. 개발자, 도메인 전문가, 코드가 공유하는 단일 용어 체계. |
| ADR (Architecture Decision Record) | 아키텍처 결정과 그 근거를 기록하는 경량 문서. |
| Seam | Working Effectively with Legacy Code에서 유래. 코드를 편집하지 않고도 동작을 변경할 수 있는 지점. |
| AFK (Away From Keyboard) Agent | 사람의 개입 없이 이슈를 구현하고 머지할 수 있는 자율 에이전트. |
| HITL (Human-In-The-Loop) | 프로세스에 사람의 판단/개입이 필요한 단계. |
| Grilling Session | 에이전트가 사용자에게 집요하게 질문하여 모호함을 해소하는 대화 패턴. |
| Progressive Disclosure | 정보를 필요에 따라 점진적으로 드러내는 패턴. 메인 파일은 간결하게, 상세 내용은 참조 파일로. |
| Deletion Test | 모듈을 삭제했을 때 복잡성이 사라지면 pass-through, 호출자에 퍼지면 가치 있는 모듈. |
이 문서는 mattpocock/skills 저장소의 engineering, productivity 스킬 구조, 동작 원리, 적용 순서를 분석한 것입니다.