이 글의 순서 훅은 실행 경계에 붙는 검사다
사고는 보통 경계에서 난다.
파일을 읽기만 하다가 바꾸거나, 내 컴퓨터에만 두던 것을 밖으로 보내거나, 초안을 공개하는 지점이다. 단순 확인이 삭제, 권한 변경, 배포처럼 되돌리기 어려운 작업으로 넘어갈 때도 마찬가지다.
훅(Hook)을 처음 보면 자동화처럼 보인다. 어떤 시점에 스크립트를 붙이고, 조건에 맞으면 무언가 실행한다. 그래서 “에이전트가 알아서 더 많이 하게 만드는 장치”처럼 느끼기 쉽다.
하지만 좋은 훅은 에이전트가 더 많은 일을 하게 만들지 않는다. 아무 일도 아닌 척 지나가던 순간을 위험한 경계로 다시 표시한다.
무엇을 자동화할지가 아니라, 어디에서 멈추고 무엇을 보여줘야 사고가 줄어드는지를 정하는 장치다. 이 글에서는 훅을 실행 경계 검사(execution-boundary check)로 보고, Codex의 이벤트 이름은 그 뒤에 예시로만 붙인다.

hook은 작업을 대신 끝내는 장치가 아니라, 실행 전 차단, 승인 전 설명, 종료 전 검증을 통과하게 만드는 경계 장치다.
훅은 실행 경계에 붙는 검사다
Hook은 말 그대로 어떤 흐름의 특정 지점에 걸어두는 동작이다. AI 에이전트 작업에서는 그 지점이 대부분 실행 경계다.
실행 경계 검사는 에이전트가 위험한 행동으로 넘어가기 전후에 “지금 무엇을 하려는지”를 드러낸다. 읽기에서 쓰기로 넘어갈 때, 로컬 변경에서 원격 반영(push)으로 넘어갈 때, 초안에서 공개 발행으로 넘어갈 때가 여기에 맞다.
중요한 점은 hook이 일반 지시문과 다르다는 것이다.
저장소 규칙 문서는 에이전트가 읽고 따라야 할 기준이다. Codex 환경에서는 그 예가 AGENTS.md다. “새 문서는 명시적 공개 플래그가 켜지기 전까지 비공개로 둔다”, “생성 산출물 디렉터리는 직접 수정하지 않는다”, “원격 반영(push)과 배포(deploy)는 확인 후 한다” 같은 기준이 여기에 맞다.
반복 절차 파일은 특정 작업의 순서를 적는다. Codex에서는 Skill이 이 역할을 맡는다. 문서 검수, git 변경 분리, UI 확인, 배포 준비처럼 “이 작업을 할 때는 이 순서로 본다”를 담는다.
Hook은 더 기계적이다. 특정 이벤트가 발생했을 때 실제 스크립트를 실행한다. 예를 들어 Bash 명령을 실행하기 전에 명령 문자열을 검사하고, 작업 종료 직전에 빠진 검증 명령을 찾고, prompt 안에서 secret처럼 보이는 문자열을 확인한다.
그래서 hook에는 “기억해 줘”가 아니라 “이 순간에는 확인해”라고 쓴다.
Codex의 이벤트 이름은 이 역할 위에 붙는 제품별 이름이다. 도구 실행 전 이벤트(PreToolUse), 도구 실행 뒤 이벤트(PostToolUse), 종료 시점 이벤트처럼 이름은 구체적이지만, 먼저 볼 것은 “어느 실행 경계를 검사하는가”다.
사고는 보통 경계에서 난다
프롬프트나 AGENTS.md는 이 경계를 설명한다. 하지만 설명만으로는 매번 충분하지 않다. 긴 세션에서 context가 길어지고, 사용자가 짧게 “그냥 배포해줘”라고 말하고, 에이전트가 앞 단계 검증을 이미 했다고 착각하면 사고가 난다.
이때 hook이 맡는 역할은 명확하다.
- 위험한 명령을 실행하기 전에 멈춘다.
- 승인이 필요한 작업인지 다시 분류한다.
- 작업이 끝나기 전에 빠진 검증을 알려준다.
- 공개하면 안 되는 문자열이나 내부 경로를 발견하면 경고한다.
- 에이전트가 보고한 “완료”와 실제 git 상태가 맞는지 확인한다.
여기서 핵심은 hook이 에이전트의 판단을 대체하지 않는다는 점이다. Hook은 판단해야 할 순간을 더 또렷하게 만든다. 사람이나 에이전트가 놓치기 쉬운 경계를 기계적으로 다시 보여준다.
어떤 훅이 사고를 줄이는가
내가 hook을 설계한다면 먼저 세 종류로 나눈다.
첫째, 실행 전 차단이다.
제품마다 이름은 다르지만, Codex라면 도구 실행 전 이벤트(PreToolUse)가 여기에 맞다. 에이전트가 Bash, 파일 수정, MCP tool 같은 도구를 쓰기 전에 입력을 검사한다. 삭제, 대량 overwrite, secret 파일 접근, public remote push처럼 위험한 패턴을 발견하면 실행 전에 막는다.
이 방식은 사고방지 효과가 크다. 이미 실행된 명령을 되돌리는 것보다 실행 전 멈추는 편이 낫기 때문이다.
둘째, 승인 요청 보강이다.
승인이 필요한 명령 앞에서는 “이 요청은 왜 위험한가”를 더 자세히 보여준다. 예를 들어 단순 build와 공개 배포는 같은 shell 명령처럼 보여도 영향 범위가 다르다. Hook은 approval prompt가 올라오기 전에 작업 종류, 대상 remote, branch, 되돌림 경로를 검사한다.
셋째, 종료 전 검증이다.
작업이 끝났다고 말하기 전에 git status, git diff --check, test/build 결과, 공개 URL 확인 같은 항목이 빠졌는지 본다. 특히 에이전트는 “수정했다”와 “검증됐다”를 혼동하기 쉽다. 종료 시점 hook은 이 둘을 나누는 데 도움이 된다.
이 세 가지를 한 문장으로 줄이면 이렇다.
실행 전에는 막고, 승인 전에는 설명하고, 종료 전에는 검증한다.
이 정도면 hook의 첫 목적은 충분하다.
훅은 완전한 보안 경계가 아니다
여기서 조심해야 할 점이 있다.
Hook을 만들었다고 모든 위험이 사라지는 것은 아니다. Codex 공식 문서도 PreToolUse를 가드레일로 설명하면서, 모든 작업 경로를 완전히 가로채는 강제 경계로 보지는 않는다. 지원되는 tool call은 검사하지만, 도구 종류나 실행 방식에 따라 경로가 빠지기도 한다.
도구 실행 뒤 이벤트(PostToolUse)도 마찬가지다. 실행 결과에 피드백을 붙여도 이미 일어난 side effect를 되돌리지는 못한다. 삭제 명령이 이미 실행된 뒤라면 hook이 “문제 있음”을 알려도 파일은 자동으로 돌아오지 않는다.
그래서 hook을 보안의 전부로 보면 위험하다.
예를 들어 git push를 막아야 한다면 hook은 push하려는 remote와 branch를 보여준다. 하지만 branch protection이나 CI가 없다면 remote에 들어간 뒤의 검증은 비어 있다. 공개 deploy 앞에서는 hook이 스크립트 경로를 확인한다. 그래도 배포 권한 자체가 열려 있으면 우회 경로가 남는다.
Hook은 문 앞의 표지판이다. 문이 열리는지, 통과한 뒤 무엇을 검증할지는 permission, sandbox, branch protection, CI, protected environment, 리뷰 요구, 배포 스크립트 같은 더 강한 경계와 같이 봐야 한다.
좋은 훅은 작고 설명 가능하다
Hook을 만들 때 가장 위험한 유혹은 “좋아 보이는 자동화”를 계속 붙이는 것이다.
예를 들어 작업이 끝날 때마다 자동으로 commit하고 push하고 deploy하게 만들기 쉽다. 하지만 이건 사고방지와 거리가 멀다. 오히려 되돌리기 어려운 작업을 사람의 확인 밖으로 밀어낸다.
또 하나 봐야 할 점은 hook 자체도 실행 코드라는 것이다. Codex는 관리되지 않는 command hook을 실행하기 전에 사용자가 현재 hook 정의를 검토하고 신뢰하도록 요구한다. 이 흐름은 귀찮은 절차가 아니라 안전 장치다. Hook이 사고를 막는다고 해도, 신뢰하지 않은 hook을 조용히 실행하면 그 hook 자체가 새로운 사고 지점이 된다.
좋은 hook은 작다.
예를 들어 이런 기준이 낫다.
rm -rf,git reset --hard, 대량 삭제, 권한 변경은 실행 전 멈춘다.git push는 remote, branch, commit hash를 보여주고 별도 확인을 요구한다.- 공개 배포 전에는 비공개 소스 변경이 승인된 원격에 반영됐는지 확인한다.
.env, key, token, private repo명처럼 보이는 문자열이 공개 문서에 들어오면 경고한다.- 완료 보고 전에는 검증 명령을 실제로 실행했는지 확인한다.
이런 hook은 화려하지 않다. 대신 실패 모드가 분명하다. 무엇을 막는지, 왜 막는지, 사람이 어떻게 푸는지 설명한다.
반대로 나쁜 hook은 넓고 조용하다. 언제 실행되는지 모르고, 실패했을 때 이유가 불분명하고, 자동으로 상태를 바꾸며, 사람이 검토할 정보를 줄여버린다. 이런 hook은 안전 장치가 아니라 숨은 자동화가 된다.
처음에는 경고만으로도 충분하다
처음부터 강하게 막는 hook을 만들 필요는 없다.
처음에는 warning만 남겨도 얻는 것이 많다. 자주 위험 경계에 닿는 명령, 검증을 빼먹는 작업, 공개 안전성 문제를 만드는 문구가 드러난다.
내가 권하는 순서는 이렇다.
- 자주 반복되는 사고 후보를 적는다.
- 그 사고가 어느 이벤트에서 잡히는지 본다.
- 처음에는 경고로 시작한다.
- false positive를 줄인다.
- 되돌리기 어려운 작업만 차단으로 올린다.
예를 들어 “공개 산출물에 비공개 소스 파일이 섞이면 안 된다”는 사고 후보가 있다고 하자. 처음에는 배포 전 산출물 목록에 금지 경로가 있는지 경고한다. 그다음 실제 배포 경로에서 통과해야 하는 검사로 올린다. 마지막으로 direct push까지 막아야 한다면 pre-push hook, branch protection, 배포 스크립트 검사를 함께 둔다.
이 순서가 중요한 이유는 간단하다. 너무 넓은 차단은 작업을 멈추게 만들고, 사람은 결국 우회 방법을 찾는다. 작게 시작해서 실제 실패 모드에 맞춘 hook만 남기는 편이 오래 간다.
사고 목록부터 쓴다
다음에 hook을 만들 일이 생기면 기능 목록부터 쓰지 않는다.
먼저 사고 목록을 쓴다. 공개 산출물에 비공개 소스가 섞이는 사고, secret이 고객 문서에 남는 사고, 삭제 명령이 승인 없이 지나가는 사고처럼 되돌리기 어려운 장면을 적는다.
그다음 그 사고가 실행 전, 승인 전, 종료 전 중 어디서 가장 잘 잡히는지 본다. 실행 전에 멈춰야 하는지, 승인 직전에 정보를 보여줘야 하는지, 종료 전에 검증 누락을 확인해야 하는지 나눈다.
처음에는 이렇게 작게 나누면 된다.
- 삭제나 권한 변경은 실행 전에 잡고, 차단 후보로 둔다.
- 원격 반영이나 배포는 승인 전에 잡고, 대상과 영향 범위를 표시한다.
- secret이나 내부 경로는 종료 전에 잡고, 경고로 먼저 드러낸다.
- 검증 누락은 종료 전에 잡고, 완료 보고를 보류하게 만든다.
Hook이 할 일은 여기까지다. 위험한 경계를 기계적으로 다시 표시하고, 사람이 볼 정보를 남긴다. 그 이상을 자동으로 처리하기 시작하면 hook은 안전 장치가 아니라 또 하나의 숨은 자동화가 된다.
참고
- OpenAI Developers, Hooks
- OpenAI Developers, Permissions
- OpenAI Developers, Rules
- 이전 글, Codex Skill을 반복 절차 파일로 보는 이유
- 이전 글, MCP는 AI가 현재 상태를 가져오는 통로다
반응
댓글은 제출 즉시 공개되며, 작성 때 정한 비밀번호로 삭제할 수 있습니다.
댓글을 불러오는 중입니다.