CCAR-P 개념 카드

◆ CLAUDE.md(지시) vs 훅(강제)

CLAUDE.md guidance vs hooks — 어느 훅 이벤트7.1 본편

표시가 없는 문장은 공식 문서에서 확인한 내용이에요. 다른 표시는 읽는 법

왜 배우나 — 시험이 요구하는 것

시험 목표 7.1 팀 도구·환경 설정 · D7 개발팀 7%
Configure Claude tools and environments for teams (e.g., Claude Code)

이 개념으로 푸는 판단 (할 수 있어야 하는 것)

  • 7.1② '반드시' 돌아야 하는 검사, 어디에 거나? — 지시(CLAUDE.md) vs 훅, 그리고 어느 훅 이벤트
  • 7.1③ 에이전트에 줄 권한, 어디까지? — 행동을 allow/ask/deny 로 나눈 공유 설정 + MCP 자격증명 최소 권한
  • 7.1① 팀 규칙을 모두의 모든 세션에 똑같이 싣으려면? — 개인 설정 vs 저장소에 커밋한 프로젝트 설정 vs 조직 관리형 설정

한눈에

정해진 시점에 반드시 돌아야 하는 규칙은 훅으로 강제하고, 스타일·관례는 CLAUDE.md 에 둔다. CLAUDE.md 는 굵게 써도 맥락일 뿐 강제가 아니다.
그림으로 보기 (AI 생성 · Codex · 누르면 크게)

ELI5

벽에 붙인 "뛰지 마세요" 안내문과, 문 앞 개찰구의 차이예요.

  • 안내문은 대부분 지키지만, 급하면 깜빡해요.
  • 개찰구는 표가 없으면 문이 안 열려요.
  • 개찰구는 들어가기 전에만 막을 수 있어요.
  • 이미 들어간 사람은 나올 때 잡아도 늦어요.

개념 설명

영상 — 지시와 강제 — 커밋을 누가 막나 (약 41초 · 소리 없음 · 자막). '10번 중 9번 멈춤' 은 그림용 가정 · 실측 아님 작은 화면에서는 전체화면(⛶)으로 보세요.

원리

CLAUDE.md 는 모델이 읽는 글이다

  • CLAUDE.md 는 세션마다 컨텍스트에 실린다. 모델은 그것을 읽고 따른다. 따를 확률은 높지만 0 이 아닌 실패가 남는다. 공식 표현은 "context, not enforced configuration" 이다.
  • 길수록 덜 따른다(파일당 200줄 목표). 충돌하는 규칙이 있으면 아무거나 고를 수 있다. 강조(IMPORTANT)는 주변보다 우선순위를 올릴 뿐이다(Skilljar).
  • 그래서 CLAUDE.md 에 맞는 것은 스타일·관례·구조 설명처럼 어겨도 되돌릴 수 있는 것이다.

훅은 Claude Code 가 돌리는 코드다

  • 훅은 정해진 시점(lifecycle event)에 셸 명령으로 실행된다. 모델이 뭘 정하든 실행된다. 그래서 결정론적(deterministic)이다.
  • 막을 수 있는지는 이벤트가 정한다.
    • 아직 안 일어난 일(도구 호출 전·응답 끝내기 전·프롬프트 처리 전)은 막을 수 있다.
    • 이미 일어난 일(도구 실행 뒤·세션 종료)은 막지 못한다.
  • 막는 신호는 exit 2 하나다. exit 1 등 다른 0 아닌 코드는 오류로 적히고 진행한다.

훅과 권한 규칙의 자리

  • 명령 이름만으로 가를 수 있으면 권한 규칙(permissions.deny)이 더 단순하다. 훅 스크립트 없이 한 줄이면 된다.
  • 명령 내용과 인자를 내 로직으로 봐야 하면(시크릿 패턴, 우회 표기) PreToolUse 훅을 쓴다.
  • 둘은 겹쳐 동작한다. PreToolUse 훅이 권한 확인창보다 먼저 실행된다. exit 2 는 allow 규칙이 있어도 막는다. 훅의 "allow" 는 deny·ask 규칙을 넘지 못한다.

핵심 질문은 두 개다

  • 어기면 되돌리기 어려운가(매번·반드시)?
  • 막아야 할 순간이 일이 벌어지기 전인가 후인가?

규칙과 판단

도구 실행 전 PreToolUse 는 exit 2 로 막을 수 있지만 PostToolUse 와 SessionEnd 는 못 막고, Stop 은 계속 일하게 한다. pre-commit 이벤트는 없다.
그림으로 보기 (AI 생성 · Codex · 누르면 크게)

갈림길

지시냐 강제냐 [7.1②]

정해진 시점에 반드시 돌아야 하나?매 커밋 전 · 매 편집 후 · 어기면 큰일
예 (시크릿 · 위험 명령 · 매 편집 후 검사)

훅

정해진 시점에 셸 명령으로 실행된다. Claude 가 뭘 정하든 실행된다

아니오 (스타일 · 관례)

CLAUDE.md

맥락일 뿐 강제가 아니다. 구체적이고 확인 가능하게 쓴다. 파일당 200줄 미만으로 둔다

어느 이벤트 [7.1②]

언제 걸어야 하나?
도구 실행 전

PreToolUse

exit 2 로 도구 호출을 막는다

편집 뒤 (린트·포맷)

PostToolUse

막지 못한다. 도구는 이미 실행됐고 stderr 만 Claude 에게 간다

Claude 가 응답을 끝낼 때

Stop

exit 2 로 멈춤을 막고 계속 일하게 한다

세션이 끝날 때

SessionEnd

막지 못한다. 정리만 한다

커밋 전

PreToolUse + if 로 git 명령만

'pre-commit' 이벤트는 없다

권한 규칙과 겹칠 때 [7.1②] [7.1③]

명령 이름만으로 가르나?
예 (git push 금지)

permissions.deny

규칙 한 줄로 막는다. 자세한 것은 ■ 에이전트 권한 에 있다

아니오 (내용 검사 · 시크릿 가리기)

PreToolUse 훅

명령 내용을 내 코드로 본다. updatedInput 으로 고쳐서 실행하게 할 수도 있다 (Skilljar)

흐름

그림 속 이름·금액·시간·토큰 수는 예시예요. 공식 한도·동작은 카드 본문 값이 기준.

장면 글로 보기

칸 : Claude → 훅 → 도구

규칙 (훅) : 막을 수 있는지는 그 일이 아직 안 일어났느냐로 정해진다

질문 : 커밋을 실제로 막는 건 어느 칸일까?

① PreToolUse 에서 막기 ✓

  1. 시작 : Claude — 쪽지 : Bash: git commit -a / 스테이징: .env
  2. 호출 : Claude → 훅 : 도구 실행 전에 부른다 — 쪽지 : PreToolUse / if: "Bash(git *)" → 일치
  3. 차단 : 훅 : exit 2 로 도구 호출을 막는다 — 쪽지 : stderr: .env 커밋 차단 / exit 2
  4. 끝 : Claude 가 뭘 정하든 도구 호출을 막는다. git commit 은 실행되지 않는다

② CLAUDE.md 에만 적기 ≠

  1. 시작 : Claude — 쪽지 : CLAUDE.md: / IMPORTANT: .env 커밋 금지
  2. 결정 : Claude : 맥락일 뿐 강제가 아니다 — 쪽지 : Bash: git commit -a / 스테이징: .env
  3. 건너뜀 : 훅
  4. 호출 : Claude → 도구 : 대부분 지켜지지만 보장은 아니다 — 쪽지 : git commit 실행됨 / + .env
  5. 끝 : CLAUDE.md 는 맥락일 뿐 강제가 아니다. 그래서 보장되지 않는다

③ PostToolUse 로 막기 ≠

  1. 시작 : Claude — 쪽지 : Bash: git commit -a / 스테이징: .env
  2. 호출 : Claude → 도구 : 실행이 먼저 일어난다 — 쪽지 : git commit 실행됨 / + .env
  3. 검사 : 훅 : 막지 못한다. stderr 만 Claude 에게 간다 — 쪽지 : PostToolUse / stderr: .env 발견 / (이미 커밋됨)
  4. 끝 : 도구는 이미 실행됐다. 막으려면 PreToolUse 를 쓴다
규칙 원문 갈림 기준 어느 이벤트 (갈림길로 그린 규칙)

갈림 기준

어기면 큰일인가를 먼저 본다

  • CLAUDE.md 는 맥락일 뿐 강제가 아니다(context, not enforced configuration). 대부분 지켜지지만 보장은 아니다. 길수록 덜 따른다. 그래서 파일당 200줄 미만으로, 구체적이고 확인 가능하게 쓴다
  • "매 커밋 전 · 매 편집 후" 처럼 정해진 시점에 꼭 돌아야 하면 훅을 쓴다. 훅은 정해진 시점에 셸 명령으로 실행된다. Claude 가 뭘 정하든 실행된다
  • 공식 표는 이렇게 나눈다. 도구·명령·경로 막기는 settings permissions.deny 가 맡는다. 코드 스타일·품질 지침은 CLAUDE.md 가 맡는다
  • 명령 이름만으로 막을 수 있으면 permissions.deny 한 줄을 쓴다(예 Bash(git push *)). 명령 내용을 내 코드로 봐야 하면 PreToolUse 훅을 쓴다
  • PreToolUse 훅은 호출을 막을 수 있다. updatedInput 으로 고쳐서 실행하게 할 수도 있다(시크릿 가리기) (Skilljar). 자세한 것은 ■ 에이전트 권한 에 있다
  • 훅은 권한 규칙보다 먼저 실행된다. exit 2 훅은 allow 규칙이 있어도 막는다. 반대로 훅이 "allow" 를 내도 deny·ask 규칙은 그대로 적용된다
  • 팀에 거는 훅은 커밋한 .claude/settings.json 에 둔다(■ 팀 설정 위치). 조직이 못 끄게 하려면 관리형 훅을 쓴다. 관리형 훅은 사용자·프로젝트의 disableAllHooks 로 끄지 못한다. allowManagedHooksOnly 면 사용자·프로젝트·로컬 훅은 실행되지 않는다

어느 이벤트

막을 수 있는지는 그 일이 아직 안 일어났느냐로 정해진다

하고 싶은 것이벤트exit 2
실행 전 차단 (위험 명령·시크릿·보호 파일)PreToolUse도구 호출을 막는다
편집 뒤 린트·포맷·경고PostToolUse막지 못한다. stderr 만 Claude 에게 간다. 도구는 이미 실행됐다
응답 끝낼 때 "아직 안 끝났다"(테스트 통과 확인)Stop멈춤을 막고 계속 일하게 한다
프롬프트 검사UserPromptSubmit프롬프트 처리를 막고 프롬프트를 지운다
세션 끝 정리SessionEnd막지 못한다. 사용자에게 stderr 만 보인다

막는 것은 exit 2 뿐이다. 다른 0 아닌 코드(예 1)는 막지 않고 계속 진행한다

SessionStart 훅은 맥락만 넣는다(additionalContext). 막는 힘이 없다. 그래서 규칙을 SessionStart 로 싣는 것은 여전히 지시이고 강제가 아니다

matcher 는 도구 이름을 정확히 맞춘다. Bash 는 Bash 도구만 잡는다. 편집까지 잡으려면 Edit|Write 를 따로 적어야 한다. 그래서 "셸에서는 실행되고 편집에서는 안 된다" 면 matcher 범위부터 본다

Stop 은 "세션 끝" 이 아니다. Claude 가 응답을 끝낼 때마다(턴마다) 실행된다. 끝없는 반복은 두 가지로 막는다. stop_hook_active 를 확인한다. 연속 8번 계속시키면 Claude Code 가 턴을 끝낸다

Claude Code 이벤트 목록에 'pre-commit' 은 없다. 그래서 PreToolUse 에 if 필드(권한 규칙 문법, 예 "Bash(git *)")를 달아 git 명령만 거른다

git 자체 pre-commit 훅도 방법이다 업계 일반

더 깊이 : 판단 규칙 · 상황 변수 (설명)

판단 규칙

조건답근거
어떤 행동을 Claude 판단과 무관하게 막아야 한다PreToolUse 훅을 쓴다memory "To block an action regardless of what Claude decides, use a PreToolUse hook instead."
매 커밋 전·매 편집 후처럼 정해진 시점에 꼭 돌아야 한다훅을 쓴다memory "such as before every commit or after each file edit, write it as a hook instead."
코드 스타일·품질 지침·데이터 취급 알림이다CLAUDE.md 에 둔다memory
도구·명령·경로를 막는다settings permissions.deny 를 쓴다memory
편집 뒤에 자동 포맷·린트를 돌린다PostToolUse 를 쓴다 (막지는 못한다)hooks · Skilljar 486933
테스트 통과 전에는 응답을 못 끝내게 한다Stop 을 쓴다 (exit 2 면 계속 일한다)hooks
세션 끝에 정리·기록한다SessionEnd 를 쓴다 (막는 힘이 없다)hooks
커밋 전에 검사한다PreToolUse + if 로 git 명령만 거른다hooks(이벤트 목록에 pre-commit 이 없다) ·(if)

상황 변수

변수값답 쪽근거
요구 강도"반드시"·되돌리기 어렵다훅이나 권한 규칙판단 규칙 1·2
요구 강도"되도록"·스타일CLAUDE.md판단 규칙 3
시점도구 실행 전PreToolUsehooks
시점도구 실행 뒤PostToolUse 다. 경고와 정리만 한다hooks
시점응답 끝낼 때Stophooks
시점세션 끝SessionEnd 다. 막지 못한다hooks
판단 재료명령 이름뿐이다permissions.denypermissions
판단 재료명령 내용·다른 표기다PreToolUse 훅이나 샌드박스permissions
누가 끌 수 있나팀원이 꺼도 된다.claude/settings.json 에 훅을 커밋한다hooks
누가 끌 수 있나아무도 못 끄게 한다관리형 훅hooks
실행 방식async: true 훅이다막지 못한다hooks

연습 문제

팀 CLAUDE.md 에 "IMPORTANT: .env 는 절대 커밋하지 마" 가 굵게 적혀 있는데도 가끔 커밋된다. 팀은 git commit 이 실행되기 전에커밋 전 반드시 막는반드시 장치를 원한다. 한 팀원은 Claude Code 의 pre-commit 훅 이벤트에 걸자고 한다. 어디에 무엇을 걸까?

시험 대비

함정

  • "CLAUDE.md 에 '반드시 검사'를 굵게, IMPORTANT 로 적는다" 는 함정이다. CLAUDE.md 는 맥락일 뿐 강제가 아니다. 강조는 주변보다 우선순위만 올린다 (Skilljar)
  • "Stop 훅에 걸어 세션이 끝날 때 최종 검증한다" 는 함정이다. Stop 은 응답이 끝날 때마다 실행된다. 세션 끝은 SessionEnd 이고, SessionEnd 는 막는 힘이 없다
  • "PostToolUse 로 시크릿 커밋을 막는다" 는 함정이다. 도구는 이미 실행됐다. 막으려면 PreToolUse 를 쓴다
  • "exit 1 로 막는다" 는 함정이다. exit 2 만 막는다
  • "규칙을 SessionStart 훅으로 매 세션 주입하면 강제된다" 는 함정이다. SessionStart 는 맥락만 넣고 막는 힘이 없다
  • "Claude Code 의 pre-commit 훅 이벤트에 건다" 는 함정이다. 그런 이벤트는 없다
  • "더 큰 컨텍스트 창이나 더 큰 모델로 규칙을 더 잘 지키게 한다" 는 함정이다. 강제와 무관하다 업계 일반
  • 반대쪽 함정도 있다. "모든 규칙을 훅으로 만든다" 는 함정이다. 코드 스타일과 관례는 CLAUDE.md 가 공식 자리다

신호

"Claude treats them as context, not enforced configuration. To block an action regardless of what Claude decides, use a PreToolUse hook instead."

"If the instruction is something that must run at a specific point, such as before every commit or after each file edit, write it as a hook instead."

"Hooks execute as shell commands at fixed lifecycle events and apply regardless of what Claude decides to do."

"Settings rules are enforced by the client regardless of what Claude decides to do. CLAUDE.md instructions shape Claude’s behavior but are not a hard enforcement layer."

"Shows stderr to Claude; the tool already ran" (PostToolUse)

"SessionEnd hooks have no decision control. They can’t block session termination but can perform cleanup tasks."

"A hard rule like that belongs in a pre-tool-use hook instead." (Skilljar)

막을 일은 보통 PreToolUse 와 exit 2 지만, 포맷터만 돌리면 PostToolUse, 팀원이 끌 수 있으면 관리형 hook, git -C 우회엔 내용 보는 hook 이나 샌드박스가 필요하다.
그림으로 보기 (AI 생성 · Codex · 누르면 크게) — 자세한 조건은 아래 '더 깊이'에 있어요
더 깊이 : 뒤집히는 때 · 오답 재료 (설명)

뒤집히는 때

1. PostToolUse 가 정답인 때

  • 조건 : "Claude 가 파일을 고칠 때마다 포맷터를 돌려라" 라는 요구다. 막을 필요는 없고 매번 돌기만 하면 된다.
  • 판단 : PostToolUse 가 맞는 자리다. "PostToolUse = 늘 오답" 이 아니다. 막으려 할 때만 오답이다. 결과를 보고 Claude 에게 알릴 것이 있으면 exit 2 로 stderr 를 Claude 에게 보낸다.
  • 근거 : hooks · Skilljar 486933 "This is usually where auto-formatting or an auto-lint goes."

2. 팀 훅을 커밋했는데 안 도는 때

  • 조건 : 개발자 45명 저장소에 PreToolUse 시크릿 검사 훅을 커밋했다. 한 팀원 설정에 disableAllHooks: true 가 있다. 또는 조직이 allowManagedHooksOnly 를 켰다.
  • 판단 : 프로젝트 훅은 팀원이 끌 수 있다. allowManagedHooksOnly 면 사용자·프로젝트·로컬 훅이 아예 실행되지 않는다. 조직 차원의 "반드시" 면 훅을 관리형으로 올린다. 관리형 훅은 관리형 밖의 disableAllHooks 로 끄지 못한다.
  • 근거 : hooks

3. Stop 훅이 "항상" 붙잡지는 못하는 때

  • 조건 : Stop 훅이 "테스트가 초록이 될 때까지 계속" 을 exit 2 로 강제한다. 테스트가 환경 문제로 영영 안 풀린다.
  • 판단 : 연속 8번 계속시키면 Claude Code 가 다음 막기를 무시하고 턴을 끝낸다. 훅은 stop_hook_active 를 보고 스스로 풀어 줘야 한다. Stop 은 "끝내기 전 검사" 이지 무한 강제가 아니다.
  • 등급 : (상한값은 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP 로 바뀐다)
  • 근거 : hooks

4. 권한 규칙이 훅을 이기는 때

  • 조건 : PreToolUse 훅이 git push 에 "allow" 를 돌려준다. 그런데 관리형 settings 에 Bash(git push *) ask 가 있다.
  • 판단 : 훅의 allow 는 deny·ask 규칙을 넘지 못한다. 그래서 여전히 확인창이 뜬다. 반대로 훅의 exit 2 는 allow 규칙보다 먼저 막는다. "훅이 최종 결정권자" 가 아니다. 훅의 판정은 막는 쪽으로만 효력이 있다.
  • 근거 : permissions

5. 이름 규칙만으론 못 막는 때

  • 조건 : permissions.deny 에 Bash(git push *) 가 있다. Claude 가 git -C . push 로 실행한다.
  • 판단 : Bash 규칙은 글자 매칭이라 걸리지 않는다. 내용을 보는 PreToolUse 훅이나 샌드박스가 필요하다. "deny 한 줄이면 끝" 이 뒤집힌다.
  • 근거 : permissions

오답 재료

오답왜 끌리나왜 틀리나등급근거
"CLAUDE.md 에 '커밋 전 반드시 시크릿 검사'를 굵게"가장 쉬운 수정이다맥락일 뿐 강제가 아니다. 매 커밋 전이면 훅을 쓴다memory
"Stop 훅에 걸어 세션이 끝날 때 최종 검증"이름이 '멈춤' 이다Stop 은 응답이 끝날 때마다 실행된다. 세션 끝은 SessionEnd 이고 막는 힘이 없다hooks
"PostToolUse 로 위험 명령 차단"결과를 보고 판단할 수 있어 보인다도구는 이미 실행됐다hooks
"exit 1 로 막는다"1 이 '오류' 같다막는 것은 exit 2 뿐이다hooks · Skilljar 486933
"Claude Code 의 pre-commit 훅 이벤트에 건다"git 훅과 이름이 겹친다이벤트 목록에 없다. PreToolUse + if 를 쓴다hooks
"더 큰 모델·더 큰 창이면 규칙을 더 잘 지킨다"성능이 오르면 다 나아질 것 같다확률을 올릴 뿐 강제가 아니다업계 일반—
"모든 팀 규칙을 훅으로"강제가 늘 더 안전해 보인다스타일·관례는 공식이 CLAUDE.md 에 둔다. 훅은 유지비가 든다memory
"훅이 allow 를 주면 확인창이 사라진다"훅이 권한을 정하는 것 같다deny·ask 규칙은 그대로 적용된다permissions

참고

더 깊이 : CCA-F · 출처 · 상태 · 미해결 (참고)

CCA-F

겹침 (1.4 "반드시 지킬 순서는 프롬프트가 아니라 hook·게이트" · 1.5 PreToolUse = 막기·입력 바꾸기, PostToolUse = 이미 실행 뒤 결과 다루기). 여기서는 같은 원리를 팀 개발 환경에 옮겨 묻는다. 시크릿·린트·테스트 검사를 어느 이벤트에 거는지, 팀과 조직 중 어디에 싣는지를 묻는다. 에이전트 앱 설계는 D5 ◆ 안내(프롬프트) vs 강제(구성·코드) 에서 다룬다

출처

상태

  • 업계 일반 2줄

미해결

  1. 목록 7.1② 에 "Part 24 [08:15] 'pre-commit 또는 pre-tool use'" 가 있다. Claude Code 이벤트에는 pre-commit 이 없다(확인). git 자체 pre-commit 훅은 Claude Code 문서 밖이다. 그래서 카드에는 업계 일반으로만 둔다.
  2. D5 ◆ 안내(프롬프트) vs 강제(구성·코드) 와의 경계 : 이 카드는 Claude Code 팀 설정(CLAUDE.md·settings·훅)만 다룬다. 에이전트 앱의 system prompt vs 코드 게이트는 D5 쪽이다. 그 카드가 나오면 겹치는 문장을 확인해야 한다.
  3. hooks-guide(code.claude.com/docs/en/hooks-guide)는 받지 않았다. 이벤트와 exit 코드는 hooks 레퍼런스(en-claude-code-hooks.md)로 대조했다.