| name | antipattern |
| description | 발견된 안티패턴을 훅 하네스로 전환한다. "이거 하지 마", "이건 안티패턴", "훅으로 막아", "하네스 만들어", "antipattern", "/antipattern" 등으로 트리거. 메모리에 기록하는 게 아니라 guardOsPatterns.mjs 등의 훅에 정적 검사 규칙을 추가하여 구조적으로 재발을 차단하는 것이 목적이다. 정적 탐지가 어려운 경우는 프로젝트 안티패턴 매뉴얼 파일에 추가한다. 안티패턴을 발견했을 때, 또는 코드리뷰 중 "이건 하면 안 돼"라는 피드백이 나왔을 때 사용한다. |
핵심 원칙
메모리는 잊는다. 하네스는 잊지 않는다.
사용자가 "이거 하지 마"라고 말했을 때:
- 메모리에 기록 → LLM이 다음 세션에서 떠올리길 바람 (불안정)
- 훅에 규칙 추가 → 다음에 시도하면 즉시 차단 (확실)
- 정적 탐지 불가 → 프로젝트 매뉴얼에 기록하여 사람·AI가 코드리뷰에서 참조 (반영구)
이 스킬은 안티패턴을 훅 규칙 또는 프로젝트 매뉴얼 항목으로 변환하는 파이프라인이다. 스킬 자체에는 누적하지 않는다 — 안티패턴 목록은 프로젝트의 자산이지 스킬의 자산이 아니다.
입력
안티패턴은 다양한 형태로 들어온다:
- 사용자 피드백: "이거 하지 마", "이건 위반이야", "왜 이렇게 했어"
- 코드리뷰: 리뷰어가 거부한 패턴
- 세션 중 발견: 구현하다가 잘못된 방향으로 간 것을 나중에 수정한 경우
- 직접 요청: "이 패턴을 훅으로 막아줘"
실행 절차
Step 1: 안티패턴 식별
사용자가 지적한 것 또는 대화에서 드러난 안티패턴을 구체적으로 정의한다.
안티패턴: [이름]
위반 코드: [구체적 코드 패턴]
올바른 대안: [어떻게 해야 하는지]
탐지 가능성: 정적 / 맥락 필요
Step 2: 분류 — 훅 vs 매뉴얼
| 탐지 가능성 | 조치 |
|---|
| 정적 탐지 가능 — regex나 AST 패턴으로 잡힘 | → 프로젝트 훅(예: .claude/hooks/guardOsPatterns.mjs)에 규칙 추가 |
| 맥락 판단 필요 — 파일 간 관계, 용도 이해 필요 | → 프로젝트 안티패턴 매뉴얼에 항목 추가 |
| 양쪽 다 — 일부는 정적, 일부는 맥락 | → 훅 + 매뉴얼 모두 |
정적 탐지 판단 기준: "이 패턴이 코드에 나타나면 100% 위반인가?" → Yes면 훅, No면 매뉴얼.
Step 3-A: 훅 규칙 작성 (정적 탐지 가능한 경우)
프로젝트의 가드 훅(예: .claude/hooks/guardOsPatterns.mjs)에 규칙을 추가한다. 훅 파일 경로는 프로젝트마다 다를 수 있으니 먼저 기존 훅을 찾아 컨벤션을 확인한다.
규칙 작성 원칙:
- 검사 대상 파일 범위를 명확히 (isPages, isTsx, isCss, isExempt 등)
- regex는 false positive를 최소화 — 너무 넓으면 개발이 멈춤
- 에러 메시지에 올바른 대안을 구체적으로 안내
- 기존 규칙 번호 체계를 이어감
규칙 템플릿:
if ([조건] && [패턴].test(content)) {
violations.push(
'[위반 설명] — [올바른 대안 안내]'
)
}
Step 3-B: 매뉴얼 항목 작성 (맥락 판단이 필요한 경우)
프로젝트 안티패턴 매뉴얼 파일에 항목을 추가한다.
파일 위치 규칙:
- 프로젝트에 이미 안티패턴 매뉴얼이 있으면 그 파일에 이어 적는다 (예:
docs/antipatterns.md, ANTIPATTERNS.md, .claude/antipatterns.md 등 — 프로젝트 컨벤션을 따른다).
- 없으면 프로젝트 루트 또는
docs/ 아래에 신규 생성하고, CLAUDE.md에 위치를 한 줄 등록한다.
- 스킬 디렉터리(
plugins/.../skills/antipattern/)에는 절대 적지 않는다 — 스킬은 변환기이지 저장소가 아니다.
항목 템플릿:
### [번호]. [안티패턴 이름]
**한 줄 정의:** [무엇이 위반인가]
- 위반 신호: [구체적 코드 패턴 / 파일 조합]
- 핵심 인식: [왜 이게 문제인가 — 현상이 아니라 구조적 이유]
- 올바른 대안: [어떻게 해야 하는지 — 가능하면 코드 한 토막]
- 판단 기준: [한 줄 자문 — "X가 Y인가?" → Yes/No로 분기]
- (선택) 정적 탐지 한계: [왜 훅으로 못 잡는지]
- (선택) 참조: [관련 훅 규칙 번호 / 외부 표준]
Step 4: 테스트 (훅 규칙을 추가한 경우)
훅 규칙을 추가한 후, 양성/음성 케이스를 stdin으로 테스트한다:
printf '{"tool_name":"Write","tool_input":{"file_path":"...", "content":"[위반 코드]"}}' \
| node .claude/hooks/guardOsPatterns.mjs
printf '{"tool_name":"Write","tool_input":{"file_path":"...", "content":"[정상 코드]"}}' \
| node .claude/hooks/guardOsPatterns.mjs
양성은 {"decision":"block",...}이 출력되어야 하고, 음성은 출력 없이 통과해야 한다.
Step 5: 보고
## Antipattern → Harness 결과
### 추가된 훅 규칙
| # | 이름 | 패턴 | 파일 범위 |
|---|------|------|----------|
| 15 | 네이티브 다이얼로그 | prompt/alert/confirm | !isExempt, tsx |
### 매뉴얼에 추가된 항목 (맥락 판단)
- [파일경로]#[항목 번호/이름]
### 테스트 결과
- 양성 N건 차단 확인
- 음성 N건 통과 확인
매뉴얼 ↔ 훅 승격
매뉴얼 항목 중 패턴이 명확해진 것은 훅으로 승격하고, 매뉴얼에는 "→ 훅 규칙 N으로 승격" 표시만 남긴다(원문 삭제 가능). 반대로 훅이 false positive를 너무 많이 일으키면 훅에서 빼고 매뉴얼로 강등한다.
훅 확장 시 주의사항
- false positive 최소화: 규칙이 너무 넓으면 정상 코드도 차단하여 개발 흐름이 멈춤. 의심스러우면 매뉴얼에 먼저 두고, 패턴이 명확해지면 훅으로 승격
- 에러 메시지가 곧 문서: 차단 메시지에 "왜 안 되는지"와 "대신 뭘 써야 하는지"를 명확히 적어야 함. 메시지를 읽고 바로 수정할 수 있어야 한다
- 제외 범위 존중: 프로젝트가 정의한 예외 영역(예:
isExempt)은 날코딩이 허용되는 영역 — 새 규칙도 이 예외를 따라야 한다