콘텐츠로 건너뛰기

[AI 코딩] 클로드 코드 테스트, 검사기가 막았는데 파일이 써진 일

훅의 종료 코드 2와 셸 파이프의 함정 클로드 코드 테스트용 검사기가 분명히 “막음” 을 외쳤는데, 빈 폴더에서 다시 돌려 보니 AI 는 파일을 그대로 써 버렸습니다. 검사기가 끝나며 남긴 숫자가 1이면 지나가고 2일 때만 멈췄습니다. 앞 글 클로드 코드 백그라운드, 남의 글이 붙고 잠금이 남았다에서는 여러 작업이 잠금 파일을 같이 쓸 때 생긴 일을 적었습니다.

1. 클로드 코드 테스트 게이트에서 무슨 일이 있었나요?

블로그 대표 이미지 기준이 두 번 롤백됐습니다. 2026-09-17~18 에는 남색 템플릿이, 2026-09-27 에는 숫자 강조 템플릿이 다시 나왔습니다. 그래서 규칙을 지시문에서 빼내 검사기(정해진 기준과 다르면 막는 작은 프로그램)로 옮겼습니다.
이 글 다음에 읽을 글
그 검사기를 셸과 클로드 코드 훅(도구를 쓰기 직전에 끼어드는 스크립트) 두 곳에 걸었습니다. 2026-10-01 빈 폴더에서 같은 훅을 마지막 숫자만 바꿔 돌렸더니, 종료 코드(프로그램이 끝나며 남기는 성공, 실패 숫자) 1일 때는 hello.txt 가 생겼고 2일 때만 쓰기가 멈췄습니다.

2. 무슨 문제가 생겼나요?

검사기가 맞는 숫자를 내도, 그 숫자를 읽는 쪽이 막음으로 받아 주지 않으면 막히지 않습니다. 화면에는 “막음” 이 찍혀 있으니 사람은 막힌 줄 압니다. 이런 자리가 두 군데 있었습니다. 클로드 코드 2.1.281 의 PreToolUse 훅은 exit 2 만 막음으로 읽었습니다. 셸에서는 검사 출력을 남기려고 tee 파이프를 붙이자, 검사기의 1이 파이프 끝 tee 의 0에 덮여 올리기가 실행됐습니다. 클로드 코드 테스트 게이트에서 PreToolUse 훅이 exit 1 은 통과시키고 exit 2 만 막는다는 것을 좌우로 비교한 다이어그램
훅 종료 코드클로드 코드의 마지막 출력(로그 그대로)hello.txt
exit 1완료했습니다. hello.txt 파일이 생성되었고 “hi”가 한 줄 들어있습니다.생김(hi)
exit 2Write 도구가 gate.sh 훅에 의해 차단됨: 대표 이미지 기록이 기준과 다르다.안 생김

3. 클로드 코드 테스트 게이트, 어떻게 풀었나요?

검사기를 고치기보다 숫자를 읽는 자리를 하나씩 맞췄습니다.
  1. 규칙을 지시문 밖으로 뺍니다. 정의 안의 “수치형이면 숫자 템플릿” 분기와 “실패하면 임시로 옛 방식” 문장을 지우고, 검사기가 이미지 기록(manifest) 첫 칸의 생성 도구와 배경을 직접 읽어 막게 했습니다(검사 항목 G07b)
  2. 검사기 종료 코드를 0, 1, 2 로 나눕니다. 기준과 같으면 0, 다르면 1, 파일을 못 열거나 JSON 이 깨졌으면 2입니다. 판정 불가를 통과로 두지 않는 것이 가장 먼저 정한 줄입니다
  3. 클로드 코드 훅에서는 막을 경우를 전부 exit 2 로 냅니다. Claude Code 훅 문서도 “Exit 2 means a blocking error.” 라고 적습니다
  4. 셸 파이프에 tee 를 쓰면 pipefail 을 켭니다. 켠 서브셸에서는 같은 줄이 “멈춤(종료 코드 1)” 로 돌아왔습니다
  5. 막히면 기준을 낮추지 않고 산출물을 고칩니다. bad.json 을 기준에 맞게 다시 쓰자 같은 검사기에서 통과였습니다
거는 자리막음으로 읽는 코드새어 나간 경우맞춘 방법
셸 검사 && 올리기0 이 아닌 전부없음그대로 둔다
셸 파이프 끝에 tee맨 끝 tee 의 코드막음 1 이 통과로 바뀜set -o pipefail
클로드 코드 PreToolUse 훅exit 2 만exit 1 로 끝난 훅막을 경우를 exit 2 로
검사기가 낸 1 이 파이프 끝 tee 의 종료 코드 0 으로 덮여 올리기가 실행되는 경로와 set -o pipefail 뒤 1 이 그대로 올라와 멈추는 경로를 비교한 다이어그램(로그를 다시 그린 그림) 허용 값을 하나 더 넣는 것이 가장 빠른 길이지만, 그러면 지운 분기가 검사기 안에 다시 생깁니다. 규칙을 알려 줘도 안 지켜진 일은 AI에게 규칙을 알려줬는데 안 지켜졌습니다에서 다뤘습니다.

4. 누구에게 도움이 되나요?

에이전트가 만든 산출물을 검사기로 거르고, 그 검사기를 셸과 클로드 코드 훅에 같이 거는 분이라면 읽어 보세요. 막는 분기 하나와 파이프 한 줄만 보면 됩니다. 셸에서 검사 뒤에 바로 이어 붙이기만 하고 파이프를 쓰지 않는다면 굳이 손볼 필요는 없습니다. 그 자리에서는 1이든 2든 멈췄습니다. 검증까지가 일이라는 이야기는 AI 에이전트로 혼자 일하기, 늘어난 건 산출물이 아니라 검증이었습니다에, 되돌릴 수 있다는 믿음의 비용은 AI 에이전트 권한 설계와 되돌리기 비용에 적었습니다.

5. 한 줄 정리

필자의 결론

클로드 코드 테스트 게이트는 검사기가 맞는 숫자를 내는 것만으로는 막지 못하고, 그 숫자를 읽는 자리가 막음으로 받아 줘야 막습니다. 그래서 검사기는 0, 1, 2 로 고정하고 셸에서는 pipefail, 훅에서는 막을 경우를 전부 exit 2 로 냅니다. 남은 구멍도 있습니다. 검사기는 기록만 보고 이미지 실물은 보지 않으며, 누군가 기준 값을 바꾸면 바뀐 기준으로 충실히 통과시킵니다.
그래서 당신은 이것만 하면 됩니다. 지금 걸어 둔 훅 스크립트 하나를 열어 막는 분기가 exit 2 로 끝나는지, tee 를 쓰는 줄에 pipefail 이 켜져 있는지 확인해 보세요.
여러분은 검사 로그를 어디에 남기고 계신가요? 댓글로 들려주세요. 셸 &&, tee 파이프, 클로드 코드 테스트 PreToolUse 훅 세 자리에서 각각 어떤 종료 코드를 막음으로 읽는지와 새어 나간 경우를 대조한 다이어그램(로그를 다시 그린 그림)
이 글 다음에 읽을 글

부록: 재현 명령과 출력

2026-10-01 macOS 의 /tmp 빈 폴더에서 Python 3.14.7, 클로드 코드 2.1.281 로 돌렸습니다. 각 폴더의 .claude/settings.json 에는 {"hooks":{"PreToolUse":[{"matcher":"Write","hooks":[{"type":"command","command":"<작업 폴더>/gate.sh"}]}]}} 한 줄을 두었고, gate.sh 는 아래와 같습니다(exit 1 판은 마지막 숫자만 다름).
#!/bin/bash
echo "막음: 대표 이미지 기록이 기준과 다르다" >&2
exit 2
클로드 코드에는 claude -p --model haiku --setting-sources project --allowedTools "Write" 로 “hello.txt 파일을 만들고 hi 한 줄을 써. 막히면 막힌 이유를 한 줄로 적고 다른 방법은 쓰지 마.” 를 넘겼습니다. exit 1 폴더의 실제 출력입니다.
== 훅이 exit 1 로 끝날 때 (/tmp/s5h-wzAd)
완료했습니다. hello.txt 파일이 생성되었고 "hi"가 한 줄 들어있습니다.
hello.txt: 생김(hi)
검사기 checkhero.py 는 ok.json 에 “통과”(0), bad.json 에 “막음: generator=stat-template, background=solid”(1), broken.json 에 “판정 불가: JSONDecodeError”(2), missing.json 에 “판정 불가: FileNotFoundError”(2) 를 냈습니다. 셸 실험은 python3 checkhero.py "$f" && publish 로 돌렸고 publish 는 “올리기 실행됨” 만 찍는 셸 함수라 실제 글은 건드리지 않았습니다. tee 를 붙인 줄의 출력입니다.
[bad.json] python3 check_hero.py bad.json | tee gate.log && publish
막음: generator=stat-template, background=solid
  -> 올리기 실행됨
haiku 로 한 번씩 돌린 결과라 다른 이벤트와 도구는 미확인이고, 훅 안에서 tee 를 쓰는 경우도 재현하지 않았습니다. bash 버전은 로그에 남기지 않아 미확인이고, exit 1 판에서 훅이 불린 흔적(표준 오류 문구)은 출력에 보이지 않아 같은 구성의 exit 2 판으로 미뤄 볼 뿐입니다.

이 글을 쓴 사람

인프라와 DevOps를 실무로 다루면서 겪은 것을 기록합니다. Docker, Kubernetes, AWS, 그리고 AI 도구를 실제로 써 보고 남기는 로그입니다.

Threads·X

새 글이 올라오면 Threads @wonizz.ai 에도 올립니다. 팔로우해 두면 피드에서 바로 볼 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다