훅(hooks)은 누가 실행하나 — 모델이 아니라 harness가 돌리는 결정론적 셸 명령¶
한 줄 요약: 에이전트 훅은 LLM이 "판단해서 하는 일"이 아니라, 하네스(CLI)가 특정 이벤트에 무조건 실행하는 평범한 셸 명령이다. 그래서 모델이 무시·변경할 수 없는 하드(결정론) 규칙이다. 반대로 규칙 파일(
CLAUDE.md등)·메모리는 모델이 읽고 따를지 판단하는 소프트 규칙. "반드시 강제"가 필요하면 훅으로, "권장"이면 규칙 파일로.
훅 = 이벤트 → 셸 명령 (모델 무관)¶
훅은 하네스와 stdin / stdout / stderr / exit code 로 통신한다. 이벤트가 발생하면 하네스가 이벤트 데이터를 JSON으로 스크립트의 stdin에 넘기고, 스크립트의 출력·종료코드로 흐름에 개입한다. 여기에 모델(LLM)은 관여하지 않는다 — 순수 결정론적 실행이다. (하네스 노트의 "하드 vs 소프트" 와 직결)
주요 이벤트¶
| 이벤트 | 시점 | 흔한 용도 |
|---|---|---|
SessionStart |
세션 시작 | 컨텍스트 주입, 인덱스 재생성 |
UserPromptSubmit |
사용자 입력 제출 직후 | 매 턴 리마인더 주입, 입력 검사 |
PreToolUse |
도구 실행 전 | 위험 명령 차단 / 승인 |
PostToolUse |
도구 실행 후 | 포맷터 · 린트 자동 실행 |
Stop / SubagentStop |
(서브)에이전트 응답 종료 | 후처리 |
PreCompact |
컨텍스트 요약 전 | 보존 처리 |
SessionEnd |
세션 종료 | 정리 · 백업 등 |
하드 vs 소프트 — 어디에 박을까¶
"X 할 때마다 반드시 Y 해라" 같은 자동 동작은 모델 설득으로는 보장되지 않는다.
규칙 파일(CLAUDE.md) · 메모리 |
훅 (설정의 hook) | |
|---|---|---|
| 실행 주체 | 모델 (읽고 판단) | 하네스 (무조건 실행) |
| 성격 | 소프트 — 확률적, 무시 가능 | 하드 — 결정론, 무시 불가 |
| 적합 | 권장 · 맥락 · 스타일 가이드 | 강제 자동화 · 게이트 · 검증 |
→ "반드시 / 매번 / 자동" 류 요구는 훅이 정답. 규칙 파일에 적어두면 대체로 따르지만 샐 수 있다.
⚠️ SessionEnd 함정 — graceful 종료만 보장¶
종료 훅으로 "자동 백업 / 커밋"을 거는 건 흔한 발상이지만 함정이 있다:
SessionEnd는 정상(graceful) 종료일 때만 발화한다. reason 값 예:clear,resume,logout,prompt_input_exit,bypass_permissions_disabled,other.- 크래시 · 정전 · 프로세스 강제 kill · 터미널 강제 종료면 죽은 프로세스가 훅을 못 돌린다 → 실행 보장 없음.
- 즉 "컴퓨터 고장 대비 백업"을 종료 훅에 의존하면, 정작 고장 순간엔 안 돈다.
방어선: 재난 백업은 종료 훅이 아니라 평소에 미리 커밋·푸시해 둔 상태 그 자체다. 종료 훅은 "평소 변경을 흘리지 않게 줍는 안전망"으로만 쓰고, "변경 있을 때만 / 조용히 실패 로깅" 가드를 단다.
글로벌 훅의 사정거리¶
사용자 전역 설정에 건 훅은 작업 디렉토리와 무관하게 모든 프로젝트의 모든 세션에서 발화한다. 편하지만 매 세션마다 도는 만큼, 무의미한 빈 동작을 막는 가드(예: 변경 없으면 커밋 생략)가 필요할 수 있다.
발표 시 한 줄¶
"훅은 모델이 판단해 실행하는 게 아니라, 하네스가 이벤트에 무조건 돌리는 결정론적 셸 명령입니다. 그래서 '반드시 강제'가 필요한 동작은 규칙 파일(소프트)이 아니라 훅(하드)에 박아야 합니다. 단 종료 훅은 정상 종료만 보장하므로 재난 백업용으론 부적합합니다."
FAQ¶
Q: 훅은 백그라운드에서 모델이 알아서 돌리는 건가? → 아니다. 모델은 전혀 관여하지 않는다. 하네스(CLI 프로세스)가 이벤트에 셸 명령을 1회 실행할 뿐이고, 상주 데몬도 아니다.
Q: "세션 종료"가 세션 파일 삭제 시점인가? → 아니다. 세션이 끝나는 시점(대화 종료 / clear 등)이지 트랜스크립트 파일 삭제와는 무관하다.
Q: 규칙 파일에 "종료되면 커밋해라" 적으면 되지 않나? → 안 된다. 종료 순간엔 모델이 호출되지 않아 그 규칙을 읽어줄 주체가 없다. 종료 자동화는 구조적으로 훅(하드)만 가능하다.