차단만 하면 같은 시도가 반복된다 — Rules·Hooks·Skills 3계층과 차단 규칙 7종

에이전트를 통제하는 세 수단을 규범·강제·절차로 갈라 놓고, 비교표의 「강제력」 열이 셋 중 하나에서만 「있음」이 되는 구조를 본다. 훅 5종·차단 규칙 7종·운영 규약 6항목을 전부 펼치고, 훅 표가 요약한 사고 5가지를 차단 규칙 7종에 하나씩 배정해 어느 둘이 남는지 센다. 훅의 차단 사유가 어느 채널로 나가는지에 대해 원 자료의 표 안에서 두 행이 갈리고, 같은 카테고리의 다른 두 글도 서로 다르게 적어 두었다는 사실도 나란히 놓는다.

"AI가 안전하게 일하는 틀을 만들었다"는 문장은 그 자체로는 아무것도 말하지 않는다. 무엇이 그 틀을 강제하는지, 강제가 실패했을 때 무엇이 남는지가 빠져 있기 때문이다.

이 시리즈는 그 추상적 표현을 읽는 규범 / 막는 강제 / 반복되는 절차 세 계층의 실제 파일로 환원한 원 자료 한 벌을 네 편에 걸쳐 옮긴다. 첫 편인 이 글이 통제 계층 전체를 다루고, 나머지 세 편이 그 위에서 돌아가는 작업과 운영을 맡는다.

이 글에서 가장 오래 남는 관찰을 먼저 적어 둔다. 세 계층을 나란히 놓은 비교표에서 「강제력」 열이 「있음」이 되는 칸은 하나뿐이다. 나머지 둘은 모델이 지키기로 선택해야 작동한다. 그리고 그 하나뿐인 강제 계층조차 차단만 하고 대안을 돌려주지 않으면 같은 시도가 반복된다 — 원 자료가 훅 예제의 설계 요점으로 든 것이 바로 그 지점이다.

이 글이 옮긴 원 자료의 작성 기준일은 2026-07-26이다. 훅 이벤트 이름·종료코드 규약·설정 파일 위치는 그 시점의 것이며 버전에 따라 바뀐다.

아래의 Rules 5종·Hooks 5종·Skills 5종과 차단 규칙 7종은 원 자료가 제공한 예제 구현체이며, 이 글이 운영해 얻은 실적이 아니다. 가져갈 것은 계층을 어떻게 가르는가라는 판단 프레임이지 파일 목록 자체가 아니다.

용어 정리

시리즈 네 편이 공유하는 어휘다. 원 자료의 용어·약어 풀이 전량이며, 순서도 원 자료를 따랐다. 이어지는 세 편은 여기서 자기 글이 쓰는 행만 추려 다시 싣는다.

용어풀이
Rules에이전트가 매 세션 자동으로 읽는 정적 지침서(.md). 강제력 없음, 규범 역할
Skills특정 작업의 표준 절차서. frontmatter의 description이 자동 호출 트리거 키
Hooks특정 이벤트 발생 시 자동 실행되는 스크립트. 도구 호출 자체를 차단할 수 있음
SKILL.md스킬 정의 파일. name / description / allowed-tools 를 frontmatter에 둔다
settings.json훅 등록·권한·환경변수를 담는 설정 파일. 훅은 여기 등록해야 동작
PreToolUse / PostToolUse도구 실행 직전 / 직후에 발동하는 훅 이벤트
SessionEnd / SubagentStop세션 종료 시 / 서브에이전트 종료 시 발동하는 훅 이벤트
matcher훅이 반응할 도구를 좁히는 필터. 빈 문자열이면 전체 매칭
additionalContext훅이 stdout으로 출력한 내용이 모델 컨텍스트에 주입되는 경로
kill switch훅을 임시로 끄는 환경변수 스위치(export XXX_DISABLED=1)
SSOTSingle Source of Truth. 같은 데이터는 한 곳에서만 관리한다는 원칙
BLUFBottom Line Up Front. 결론을 첫 줄에 쓰는 보고 방식
SDDSpec-Driven Development. 사양 → 계획 → 구현 순서로 진행하는 방식
Plan Mode코드를 바꾸기 전에 계획서를 먼저 제출하고 승인받는 실행 모드
MREMinimum Reproducible Example. 버그를 재현하는 가장 작은 코드
5-Why"왜?"를 5번 물어 표면 증상이 아닌 근본 원인에 도달하는 분석 기법
git bisect이진 탐색으로 회귀 버그를 만든 커밋을 찾는 Git 명령
회귀 테스트고친 버그가 다시 나오지 않는지 자동으로 검사하는 테스트
RLSRow Level Security. DB 행 단위 접근 제어. 애플리케이션이 아니라 DB가 막는다
auth.uid()현재 요청의 JWT에서 추출된 사용자 UUID를 반환하는 Supabase 함수
service_role 키RLS를 우회하는 관리자 키. 서버 사이드 전용, 클라이언트 노출 시 전체 데이터 유출
anon 키클라이언트에 노출해도 되는 공개 키. RLS의 통제를 받는다
PIIPersonally Identifiable Information. 이메일·전화·카드번호 등 개인식별정보
redact로그·기록에서 민감정보를 마스킹하거나 해시로 치환하는 처리
Prompt Injection사용자 입력에 지시문을 숨겨 모델의 원래 지시를 덮어쓰려는 공격
Smoke Test배포 직후 핵심 경로가 살아 있는지 5분 내로 확인하는 최소 검증
Core Web VitalsLCP·FID(INP)·CLS. 사용자 체감 성능을 측정하는 표준 지표
MCPModel Context Protocol. 외부 도구·데이터 소스를 에이전트에 연결하는 규약
Seed 데이터개발·테스트용으로 미리 넣어두는 샘플 데이터
KPTKeep / Problem / Try. 회고를 세 칸으로 나누는 형식
SPICEDSituation·Pain·Impact·Critical event·Decision. 영업 디스커버리 프레임

31개 행이고, 통제(Rules·Hooks·Skills·settings.json)·프롬프트(BLUF·SDD·Plan Mode)·디버깅(MRE·5-Why·git bisect)·DB와 인증(RLS·anon 키·PII)·성능과 배포(Smoke Test·Core Web Vitals)·회고(KPT·SPICED)까지 걸쳐 있다. 한 편이 다 쓰는 어휘가 아니라 시리즈 네 편의 합집합이라 이렇게 넓다.

이 시리즈가 다루는 자산

원 자료는 자기가 담고 있는 것을 세 계층으로 먼저 그려 둔다.

도식을 탭하면 확대해서 볼 수 있습니다

「15종」은 이 글이 아래에서 펼치는 Rules 5 + Hooks 5 + Skills 5의 합이다. 세어 보면 맞는다.

여덟 자산이 시리즈 어느 편으로 갔는지를 함께 적으면 이 표가 그대로 목차가 된다.

자산한 줄 정의이 시리즈에서의 위치
Rules·Skills·Hooks 키트에이전트를 통제하는 세 가지 수단의 실제 구현체 15종이 글에서 아래에 전부 펼친다
프롬프트 패턴 가이드4요소 프레임 + Claude Code 고유 7패턴 + 안티패턴 5한 편으로 떨어지지 않는다 — 아래 별도 설명
실전 프로젝트 빌드 가이드빈 폴더에서 배포까지 8단계로 SaaS 1개를 완주하는 절차빈 폴더에서 배포까지
배포 체크리스트배포 전·중·후·롤백·보안·성능 6섹션 체크리스트배포 65항목과 디버깅
디버깅 노하우재현→가설→검증→회귀방지 사이클과 흔한 함정 카탈로그
DB에서 인증까지 6단계스키마→마이그레이션→RLS→인증→API→테스트/배포 순서빈 폴더에서 배포까지
CLAUDE.md 템플릿 3종1인 SaaS / 제조·유통 / 서비스·콘텐츠 업종별 헌법 골격업종별 CLAUDE.md 템플릿
MCP 6종 설치 패키지외부 도구 연결을 스크립트 한 번으로 끝내는 부트스트랩배포 65항목과 디버깅

여덟 행 중 일곱은 한 편으로 떨어지고, 「프롬프트 패턴 가이드」 한 행만 세 곳으로 갈린다. 이 카테고리에 이미 발행된 글들이 그 내용의 상당 부분을 먼저 다뤘기 때문이다 — 4요소 프레임과 슬래시 커맨드·@ 파일 참조·파이프라인은 .claude 디렉터리가, 멀티턴 관리의 70% 룰과 컨텍스트 압축 흐름은 컨텍스트 예산이 다뤘다. 원 자료의 7패턴 중 남는 세 행(CLAUDE.md 컨텍스트 주입 · Plan Mode + SDD · 이미지 입력)과 안티패턴 5가지, 30초 응급처치 카드를 업종별 CLAUDE.md 템플릿 편이 잇는다. 한 칸에 링크 하나를 억지로 넣지 않고 이렇게 갈라 적는 것은 이 글의 정리다.

세 계층 — 규범·강제·절차

도식을 탭하면 확대해서 볼 수 있습니다
구분RulesSkillsHooks
본질정적 지침서 (.md)동적 절차서 (frontmatter + .md)자동 트리거 스크립트 (.sh)
로드 시점세션 시작 시 컨텍스트 주입명시적 호출 또는 description 매칭이벤트 발생 시 자동 실행
표현 언어자연어 + 마크다운자연어 + 코드 블록 (allowed-tools 명시)Bash / Python / Node
위치rules/ (글로벌·프로젝트)skills/<name>/SKILL.mdhooks/*.sh + settings.json 등록
강제력없음 (모델의 준수에 의존)없음 (호출 여부는 모델 판단)있음 (프로세스가 도구 호출을 거부)
선택 기준"매 세션 적용할 원칙""특정 작업의 표준 절차""이벤트에 반응하는 자동화"

여섯 행 중 판단을 가르는 것은 「강제력」 한 행이다. 세 칸 중 「있음」은 Hooks 하나이고, 나머지 둘은 괄호 안에 각각 "모델의 준수에 의존" · "호출 여부는 모델 판단"이라고 적혀 있다.

한 문장 요약: Rules는 사규, Skills는 업무 매뉴얼, Hooks는 출입 게이트다.

사규는 어기면 지적당하지만 몸이 막히지 않는다. 게이트는 카드가 없으면 문이 열리지 않는다.

그래서 정말 사고를 막아야 하는 항목은 Rules가 아니라 Hooks에 둔다.

우선순위 — 좁은 범위가 이긴다

순위위치성격
1 (최우선)프로젝트 ./.claude/해당 저장소 전용 규칙. 팀에 공유됨
2프로젝트 루트 ./CLAUDE.md저장소 헌법
3사용자 글로벌 ~/.claude/CLAUDE.md모든 프로젝트 공통 기본값
별도settings.local.json개인 재정의. gitignore 대상

같은 규칙이 충돌하면 좁은 범위가 이긴다. 법령 → 시행령 → 사규 구조와 같다. 이 구조가 있어야 "전사 표준은 유지하되 팀별 예외는 허용"이 가능해진다.

이 카테고리의 CLAUDE.md의 4계층 Scope 편이 같은 원리를 네 계층으로 적었다 — 그 글은 "지시가 충돌하면 더 구체적인 Scope가 우선한다(서브디렉토리 > 프로젝트 > 전역)" 고 쓰고, 로드 자체는 override가 아니라 누적이라는 점을 함께 짚는다. 위 표의 3행과 그 글의 네 계층은 계층 수가 다르므로(여기는 3+1, 그쪽은 4) 같은 목록이 아니다. 겹치는 것은 충돌 시 좁은 쪽이 이긴다는 규칙 하나이며, 이렇게 한정해 읽는 것은 이 글의 정리다.

Rules 5종 — 규범 계층

규칙 파일통제 대상대표 조항위반 시 리스크
coding-style.md코드의 형태와 변경 범위파일 800줄·함수 50줄·중첩 4단계·인자 5개 한도 / 요청받은 줄만 바꾸는 수술적 변경요청 범위 밖 코드까지 손대 회귀 발생. 리뷰 diff가 커져 검토 실효성 상실
data-policy.md데이터의 저장 위치GitHub(문서·코드) / DB(정형) / Cloud Storage(미디어) 3분할, 한 곳만 SSOT같은 데이터를 두 곳에서 관리해 불일치 발생. 대용량 바이너리가 저장소로 유입
interaction.md응답 방식과 판단 절차한국어 / 결론 먼저 / 가정을 명시하고 확인 / 해석이 갈리면 옵션 제시조용한 가정으로 잘못된 방향을 끝까지 구현. 재작업 비용이 통째로 발생
logging.md운영 관측성구조화 JSON 로그, 필수 필드 5종, PII 자동 redact, 에러는 로깅 후 재throw사고 후 원인 추적 불가. 로그에 PII가 평문 축적되어 2차 유출
security.md보안 경계시크릿 단일 원천, RLS 필수, 파라미터화 쿼리, 위험 명령 차단시크릿 커밋·RLS 미적용으로 전체 데이터 노출

다섯 파일의 통제 대상이 코드 형태 · 데이터 위치 · 응답 방식 · 관측성 · 보안 경계로 갈린다. 다만 축이 완전히 배타적이지는 않다 — logging.md의 「PII 자동 redact」와 그 위반 리스크(「로그에 PII가 평문 축적되어 2차 유출」)는 security.md가 맡은 데이터 노출과 같은 곳에서 만난다.

각 규칙의 대표 조항 상세

규칙기억할 만한 조항왜 그렇게 정했나
coding-style"변경된 모든 줄은 사용자 요청 또는 KPI 목표로 추적 가능해야 한다"이유를 못 대는 줄은 삭제 후보. 변경의 정당성을 줄 단위로 요구
coding-style발생할 수 없는 시나리오에 fallback 추가 금지방어 코드가 늘수록 진짜 에러가 묻힌다
data-policy"같은 데이터를 두 곳에 동기화하지 않는다"동기화는 영구 비용. 한 곳을 SSOT로 정하고 나머지는 경로만 참조
data-policy보관 기간을 데이터 유형별로 명시 (결제 5년 / 로그 3개월 등)삭제 기준이 없으면 데이터는 영원히 쌓인다
interaction사용자 제안보다 단순한 길이 보이면 push back무조건 동의하는 보조자는 복잡도를 막지 못한다
interaction불확실하면 추측 대신 확인 방법을 제시자신감 있는 오답이 가장 비싸다
logging에러를 잡고 삼키지 말 것. 로깅 후 재throw 또는 명시적 fallbackcatch {} 는 장애를 조용한 오작동으로 바꾼다
security노출된 키는 1시간 내 폐기를 목표로유출 대응은 완벽함보다 속도가 중요

Hooks 5종 — 강제 계층

트리거 시점하는 일차단·예방하는 사고
bash-pre-guard.shPreToolUse (matcher Bash)실행 직전 명령 문자열을 7개 정규식으로 검사, 위반 시 종료코드 2로 거부시스템 파괴·권한 상승·미검증 원격 코드 실행·메인 강제 푸시·시크릿 평문 출력
post-edit-lint.shPostToolUse (matcher Edit|Write)확장자별 포매터·린터 자동 실행. node_modules·dist·build 등은 제외포맷 불일치로 diff가 부풀어 리뷰가 무력화되는 상황
prompt-logger.shUserPromptSubmit프롬프트를 PII redact 후 일별 jsonl로 적재, 1000자로 절단, 30일 경과분 정리요청 이력 소실 / 로그에 이메일·전화·카드번호가 평문 축적
session-summary.shSessionEnd브랜치·최근 커밋·변경 파일·툴 호출 수를 JSON으로 저장, 일일 마스터 로그에 append수동 기록 누락으로 생기는 인수인계 공백
subagent-cleanup.shSubagentStop7일 경과 아티팩트 삭제, 빈 디렉터리 정리, 종료 감사 로그 기록아티팩트 무한 증식 / 동일 에이전트 남용을 아무도 모르는 상태

다섯 훅이 붙는 이벤트가 PreToolUse · PostToolUse · UserPromptSubmit · SessionEnd · SubagentStop으로 전부 다르다. 같은 이벤트에 둘이 붙는 자리가 없다.

훅 응답 규약

종료코드 / 채널의미
exit 0허용. 도구 호출이 그대로 진행된다
exit 2차단. stderr 메시지가 모델에게 전달되어 이유를 알 수 있다
stdoutadditionalContext로 주입. 경고용으로만 쓰고 짧게 유지
stderr사람·로그용. 모델 컨텍스트에 주입되지 않는다

⚠️ 이 네 행 중 두 행이 stderr를 서로 다르게 말한다

표를 행 단위로 대조하면 stderr가 두 번 등장하고 서술이 갈린다.

  • exit 2 행 — "차단. stderr 메시지가 모델에게 전달되어 이유를 알 수 있다"
  • stderr 행 — "사람·로그용. 모델 컨텍스트에 주입되지 않는다"

조건부로 읽으면 양립한다. exit 2일 때에 한해 stderr가 전달되고 그 외에는 사람·로그용이라면 두 행이 부딪히지 않는다. 그러나 표가 그 조건을 어디에도 적지 않았다 — 위 네 행이 이 규약의 전부이고, 어느 셀에도 「exit 2인 경우」라는 한정어가 없다.

어느 쪽이 맞는지는 이 표의 네 행만으로는 판정되지 않는다. 다만 원 자료가 표 밖 본문에서 조건부 독해 쪽에 근거를 남겨 두었다 — 아래 「bash-pre-guard 핵심 로직」의 세 줄 요약이 "종료코드 2와 함께 대안을 stderr로 돌려준다" 고 적고, 곧이어 "차단만 하고 대안을 안 주면 모델은 같은 시도를 반복한다" 고 잇는다. 모델이 그 stderr를 읽는다는 전제가 없으면 뒤 문장이 성립하지 않는다. 표 안에서는 갈리고 표 밖에서는 조건부 독해 쪽에 근거가 있다 — 이렇게 갈라 읽는 것은 이 글의 정리다.

⚠️ 같은 카테고리의 다른 두 글도 이 채널을 서로 다르게 적었다

자료차단 사유가 나가는 채널
settings.json과 훅의 2차 방어선"exit 2가 차단의 핵심이다. 표준 에러로 출력한 메시지가 차단 사유로 전달된다."
커맨드·스킬·훅과 플러그인 번들"훅은 이벤트 JSON을 stdin으로 받고, 결과를 stdout으로 돌려주는 양방향 통신 계약을 갖는다." — 차단 사유는 stdout JSON의 reason 필드로 나간다
이 글이 옮긴 원 자료위 4행 표. exit 2 행은 stderr가 전달된다고 하고, stderr 행은 주입되지 않는다고 한다

두 번째 글은 이 불일치를 이미 자기 본문에 적어 두었다 — "두 자료가 서로 다른 채널을 들고 있으며 어느 쪽이 현재 사양인지는 두 자료 안에서 판정되지 않는다. 실제로 훅을 걸 때는 exit 2 직후의 출력 채널을 직접 확인한다."

이 글은 그 판정을 뒤집지 않는다. 세 자료를 나란히 놓으면 갈리는 자리가 하나 더 늘어날 뿐이고, 실무의 결론은 그 글이 적은 것과 같다 — exit 2 직후의 출력 채널을 자기 환경에서 직접 확인한다. 세 자료를 이렇게 나란히 놓는 것은 이 글의 정리다.

bash-pre-guard 핵심 로직 (발췌)

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

if echo "$COMMAND" | grep -qE '\brm\s+-rf?\s+(/|/\*|\$HOME|~|--no-preserve-root)'; then
  echo "차단: 시스템 루트 또는 홈 디렉터리 전체 삭제 시도" >&2
  echo "대안: 명시적 경로를 지정하세요. 예: rm -rf ./build" >&2
  exit 2
fi

세 줄로 요약하면 — (1) 훅 입력 JSON에서 실제 명령을 꺼내고, (2) 정규식으로 위험 패턴을 판정하고, (3) 종료코드 2와 함께 대안을 stderr로 돌려준다. 차단만 하고 대안을 안 주면 모델은 같은 시도를 반복한다. "왜 막혔는지 + 무엇으로 대체하는지"를 함께 돌려주는 것이 이 훅의 설계 요점이다.

차단 규칙 7종

#탐지 패턴막는 사고허용되는 대안
1rm -rf /, rm -rf $HOME, --no-preserve-root시스템·홈 디렉터리 전체 삭제명시적 상대 경로 지정 (rm -rf ./build)
2문장 첫머리의 sudo의도치 않은 권한 상승사용자 권한으로 가능한 경로·도구 사용
3curl ... | bash검증되지 않은 원격 코드 실행다운로드 후 내용 확인, 그다음 실행
4chmod -R 777 /전역 권한 파괴대상 디렉터리 한정, 최소 권한 부여
5git push --force + main|master메인 브랜치 이력 파괴--force-with-lease 또는 새 브랜치
6> /dev/sda, /dev/nvme디스크 직접 쓰기해당 없음 (의도 재확인 대상)
7echo/cat/printf + 시크릿 환경변수명터미널 스크롤백·CI 로그에 시크릿 평문 노출앞 8자만 확인 (echo "${API_KEY:0:8}...")

7번 항목이 특히 실무적이다. 파괴적 명령만 막는 훅은 흔하지만, **"확인해보려고 키를 출력하는 습관"**이 CI 로그에 영구 기록으로 남는 사고를 막는 규칙은 드물다. 게다가 완전 차단이 아니라 "앞 8자만 보라"는 대안을 제시해 디버깅 실무를 죽이지 않는다.

⚠️ 훅 표가 요약한 사고는 다섯인데 규칙은 일곱이다 — 하나씩 배정해 본다

앞의 Hooks 5종 표에서 bash-pre-guard.sh 행의 「차단·예방하는 사고」 칸은 다섯 항목을 나열한다 — "시스템 파괴·권한 상승·미검증 원격 코드 실행·메인 강제 푸시·시크릿 평문 출력". 바로 아래 차단 규칙 표는 일곱 행이다. 일곱을 다섯에 하나씩 배정하면 이렇게 된다.

차단 규칙그 규칙의 「막는 사고」요약 5항목 중 대응하는 것
1 rm -rf / 계열시스템·홈 디렉터리 전체 삭제시스템 파괴
2 문장 첫머리 sudo의도치 않은 권한 상승권한 상승
3 curl ... | bash검증되지 않은 원격 코드 실행미검증 원격 코드 실행
4 chmod -R 777 /전역 권한 파괴대응하는 항목이 없다
5 git push --force + main메인 브랜치 이력 파괴메인 강제 푸시
6 > /dev/sda, /dev/nvme디스크 직접 쓰기대응하는 항목이 없다
7 echo/cat/printf + 시크릿시크릿 평문 노출시크릿 평문 출력

일곱 행을 전수 배정한 결과 다섯이 대응하고 둘이 남았다. 4번과 6번을 남긴 근거는 문구 대조다.

  • 4번의 사고는 「전역 권한 파괴」다. 2번의 「권한 상승」과 방향이 반대다 — 하나는 자기 권한을 올리는 것이고 다른 하나는 모두에게 여는 것이다. 같은 항목으로 묶을 근거가 두 셀 어디에도 없다.
  • 6번의 사고는 「디스크 직접 쓰기」다. 1번의 「시스템·홈 디렉터리 전체 삭제」와 별개 행으로 적혀 있고, 요약 5항목의 「시스템 파괴」는 1번의 문구를 그대로 줄인 형태다.

차단 규칙 표 앞뒤에 붙은 산문 — 앞의 「bash-pre-guard 핵심 로직」 세 줄 요약과 뒤의 7번 항목 해설 — 은 어느 쪽도 다섯 항목과 일곱 규칙을 짝지어 적지 않는다. 이 배정은 이 글의 정리이며, 원 자료가 대응표를 제시한 것이 아니다.

훅 운영 규약

항목규약지키지 않으면
실행 권한chmod +x 필수훅이 조용히 무시된다. 실패 사실조차 모른다
첫 줄set -euo pipefail중간 실패 후에도 계속 진행해 부분 실행 상태가 남는다
matcher필요한 도구로 좁힌다 ("Bash", "Edit|Write")모든 도구 호출마다 발동해 지연이 누적된다
출력량stdout은 50자 이내, 상세는 stderradditionalContext가 폭주해 컨텍스트를 잡아먹는다
kill switchexport XXX_DISABLED=1 지원훅이 오작동할 때 작업 자체가 멈춘다
로그 회수주 1회 특정 시각에만 정리 작업 수행매 호출마다 find 를 돌려 훅이 느려진다

마지막 항목은 예제 훅들이 공통으로 쓰는 기법이다. 정리 작업을 매번 하지 않고 요일 == 일요일 && 시각 == 01시 같은 조건에서만 수행한다. 부수 작업이 주 경로를 느리게 만들지 않게 하는 설계로, 훅 도입 후 체감 지연이 생기는 가장 흔한 원인을 미리 제거한다.

Skills 5종 — 절차 계층

스킬자동 발동 조건산출물
daily-report"오늘 뭐 했지" / "퇴근 리포트" / 17시 이후 "이만·끝내자"작업시간·커밋·변경파일·내일계획·인사이트가 담긴 1페이지 일일 리포트
retrospective"주간 회고" / "이번 주 어땠지" / "KPT 회고"일일 리포트 7개를 집계한 Keep·Problem·Try 회고 + 다음 주 목표 표
quote-builder"견적서 만들어" / "프로젝트 견적" / "용역 견적"부가세 자동 계산된 견적서 DOCX/PDF + 견적번호 체계
design-review"디자인 리뷰" / "접근성 점검" / "출시 전 검수"접근성 10 + 반응형 10 + 일관성 10 = 30항목 점검 리포트 (위반·경고 분류)
meeting-prep"미팅 준비" / "고객 미팅 브리핑" / "discovery call"고객 이력·SPICED 목표·시간 배분 안건·핵심 질문 5·예상 반론 대응 브리핑

Skill 설계에서 배울 점 3가지

설계 요소예제에서의 구현왜 중요한가
description은 라우팅 키다트리거 어구를 5개 이상 나열 ("퇴근 리포트", "wrap up the day" 등 표현 변형 포함)모호한 description은 호출 자체가 안 된다. 스킬을 안 쓰는 가장 흔한 원인
네거티브 트리거를 명시한다daily-report에 "주간·월간 리포트는 호출 금지" / meeting-prep에 "회의록 작성은 별도 스킬"경계를 안 그으면 인접 스킬끼리 서로 잡아먹는다
allowed-tools로 권한을 좁힌다Bash, Read, Write 만 허용. design-review만 브라우저 도구 추가스킬 단위 최소 권한. 문서 작성 스킬이 DB에 접근할 이유가 없다

첫 행은 이 카테고리의 커맨드·스킬·훅과 플러그인 번들 편이 같은 주장을 더 앞에서 적었다 — "에이전트는 사용자 입력이 들어오면 스킬 디렉토리를 탐색해 각 description을 읽고 가장 적합한 스킬을 고른다. 즉 description이 곧 라우팅 키다." 두 자료가 같은 결론에 도달했고, 이 글의 원 자료는 거기에 "트리거 어구 5개 이상"이라는 개수 기준을 덧붙였다.

각 스킬 파일은 공통적으로 When to invoke 표 → Step 1~4 절차 → 출력 형식 예시 → 응용 → 주의사항 순서를 따른다. 이 골격 자체가 "반복 업무를 절차로 고정하는 서식"으로 재사용 가능하다.

세 계층이 언제 개입하는가

도식을 탭하면 확대해서 볼 수 있습니다

이 흐름도가 말하는 것은 하나다. 모델의 선의에 의존하는 지점(Rules, Skills)과 프로세스가 강제하는 지점(Hooks)이 분리되어 있다. 검증 파이프라인을 설계한다는 것은 이 두 지점을 어디에 배치할지 정하는 일이다.

차단 경로(H → E)가 흐름의 시작이 아니라 계획 수립 단계로 되돌아간다는 점이 앞의 "대안을 함께 돌려준다"와 이어진다. 사유와 대안을 받은 모델이 계획을 고쳐 다시 내려오는 구조다.

자주 발생하는 실수 7가지

실수증상해결
Rules가 20개 이상으로 늘어남컨텍스트 폭주, 응답 지연10개 이하 유지. 사용 빈도 낮은 항목은 월 1회 점검해 제거
Skill description이 모호모델이 스킬을 호출하지 않음description에 정확한 트리거 어구를 5개 이상 나열
훅 실행 권한 누락훅이 조용히 실패 (에러도 안 남음)chmod +x 를 설치 절차에 포함
set -e 누락부분 실행 후 무시되어 상태가 어긋남훅 첫 줄에 set -euo pipefail
같은 규칙이 Rules와 CLAUDE.md에 중복컨텍스트 낭비 + 충돌 시 판정 불가한 곳으로 통합 (보통 rules 쪽)
matcher를 빈 문자열로 방치PreToolUse가 모든 도구에 발동필요한 도구로 좁힌다
훅이 stdout으로 긴 출력additionalContext 폭주50자 이내 또는 stderr로 우회

일곱 항목 중 (실행 권한 누락 · set -e 누락 · matcher를 빈 문자열로 방치 · stdout 긴 출력)은 앞의 「훅 운영 규약」 여섯 항목과 같은 것을 반대편에서 적은 것이다. matcher 쌍이 가장 뚜렷하다 — 규약의 「필요한 도구로 좁힌다」가 이 표의 「해결」 칸에 같은 문구로 다시 나온다. 짝이 닫히는지 양쪽에서 세면, 규약 여섯 중 짝이 없는 것은 kill switch·로그 회수 이고(4 + 2 = 6), 실수 일곱 중 짝이 없는 것은 Rules 20개 초과·Skill description 모호·Rules와 CLAUDE.md 중복 이다(4 + 3 = 7). 규약 표는 "이렇게 하라"이고 이 표는 "안 하면 이렇게 된다"이다. 두 표를 이렇게 짝지어 읽는 것은 이 글의 정리다.

이 시리즈의 나머지

통제 계층은 여기까지다. 남은 세 편은 이 계층 위에서 실제로 돌아가는 것들이다.

다루는 것
업종별 CLAUDE.md 템플릿1인 SaaS·제조유통·서비스콘텐츠 3종 문서 골격 10축 비교, 7패턴 중 남은 세 행과 프롬프트 안티패턴 5가지, 30초 응급처치 카드
빈 폴더에서 배포까지SaaS 하나를 완주하는 빌드 8단계와 DB에서 인증까지 6단계, AI 기능의 비용·주입 방어
배포 65항목과 디버깅배포 전·중·후·롤백·보안·성능 6섹션 65항목, 재현→가설→검증→회귀방지 4 Phase, MCP 6종

남은 세 편 중 마지막 편이 이 글로 되돌아오는 자리가 있다. 5-Why를 끝까지 밀면 답이 코드가 아니라 규칙·게이트로 바뀐다 — 원 자료가 디버깅 절에서 이 글의 Rules·Hooks 계층을 명시적으로 되짚는 이유다.