
Claude Code의 worktree 격리를 신뢰하지 마라 — 1주일에 13건의 인시던트와 PreToolUse 후크를 통한 해결
요약
Claude Code의 worktree 격리 기능이 절대 경로 사용 시 부모 리포지토리를 오염시키는 보안 및 안정성 문제를 분석합니다. 에이전트가 격리된 환경을 벗어나 실제 소스 코드를 수정하는 인시던트 사례와 그 원인을 다룹니다.
핵심 포인트
- Claude Code의 worktree 격리는 절대 경로 입력 시 부모 리포지토리를 오염시킬 수 있음
- 에이전트가 작업 중 부모 디렉토리의 파일을 직접 수정하는 인시던트가 빈번히 발생
- 격리 개념의 취약성으로 인해 에이전트의 작업 범위가 의도치 않게 확장됨
- PreToolUse 후크 등을 통한 추가적인 경로 검증 및 제어 필요성 시사
「안전한 전사(Safe Transcription)」 개발에서는 6체의 Claude Code 에이전트가 동시에 실행되고 있습니다. lead, dev, PO, webmaster, qa, claude-code-guide — 각각이 독립된 태스크를 병렬로 처리하고 있습니다.
동일한 리포지토리(Repository)에서 여러 에이전트가 동시에 쓰기 작업을 하면 컨플릭트(Conflict)나 의도하지 않은 덮어쓰기가 발생합니다. 이를 방지하기 위해 Agent({ isolation: "worktree" })를 사용하고 있었습니다.
물리적으로 분리된 git worktree 상에서 작업하게 함으로써, "최악의 경우 worktree를 버리면 되돌릴 수 있다"는 전제하에 에이전트에게 넓은 권한을 부여했습니다.
그 전제가 1주일 만에 13번 무너졌습니다.
무슨 일이 일어났는가
2026년 6월 첫째 주, 다음과 같은 현상들이 쌓였습니다.
| # | 날짜 | 현상 | 영향 |
|---|---|---|---|
| 1 | 6/2 | dev가 worktree 내에서 작업 중, API 파일을 부모 리포지토리에서 직접 편집 | 로컬 main 오염 |
| ... | 로컬 main 1 commit ahead | ||
| 12 | 6/8 | dev의 worktree 완료 후, cwd가 부모 세션으로 인계됨 | 다음 태스크에서 잘못된 push |
| 13 | 6/9 | dev가 기동 직후 부모 리포지토리의 절대 경로를 Edit에 전달하여 API 파일 3개 오염 | PR로 복구 |
실시간 배율 13x로 사고를 생산하고 있었습니다.
전형적인 패턴 3가지 예시
현상 #1 — dev가 gateway를 오염시키다
첫 번째 현상은 단순했습니다. dev 에이전트에게 "gateway/email_msg.py의 반환값을 수정해줘"라고 지시했더니, worktree 내부가 아니라 부모 리포지토리의 gateway/email_msg.py가 직접 수정되었습니다.
git status를 실행할 때까지 눈치채지 못했습니다. worktree 내에서 작업하고 있다고 믿고 있었기 때문입니다.
현상 #7 — 컴포넌트 9개 파일을 직접 수정
PR #647의 코드 리뷰를 dev에게 위임했을 때 발생했습니다. 리뷰 과정에서 dev가 수정도 실시했고, 쓰기 대상이 모두 부모 리포지토리의 frontend/app/ 하위였습니다. 9개 파일입니다. 스테이징(Staging) 환경의 빌드가 깨졌고, 원인 파악에 30분이 걸렸습니다.
이 시점에서는 "왜 worktree 내에 머물지 않았는가"를 이해하지 못했습니다.
현상 #10 — lead가 스스로 격리를 깨뜨리다
이것이 가장 힘들었습니다.
worktree 격리를 감시하고 관리하는 측인 lead 에이전트가, PO의 브랜치 위에 실수로 commit을 쌓았습니다. lead는 애초에 worktree 격리로 기동되지 않았습니다. 그런데도 발생했습니다.
"에이전트가 격리를 지키지 않는다"는 문제라고 생각했는데, "격리 개념 자체가 취약했다"는 문제였다는 것을 깨달은 순간이었습니다.
근본 원인 특정
첫 번째 가설: 절대 경로 문제 (가설 B)
조사를 시작하자 우선 Claude Code 공식의 cwd 상속 문제(Issue #57847)를 발견했습니다.
"Worktree-isolated subagents leak Edit/Write into parent checkout"
isolation: "worktree"로 기동한 에이전트가 절대 경로를 포함한 도구 인자(Tool argument)를 받으면, worktree의 루트가 아니라 CLAUDE_PROJECT_DIR(부모 리포지토리의 루트)을 기준으로 경로를 해결(Resolve)해 버린다는 내용입니다.
# 기대하는 동작
Edit({ file_path: "/absolute/path/to/file.py" })
→ <worktree>/absolute/path/to/file.py 로 해결
...
확실히 현상 #1이나 #13은 절대 경로가 원인이었습니다. 하지만 현상 #10(lead의 오기 commit)에 대한 설명은 되지 않습니다. 가설 B는 부분적으로만 맞았습니다.
git reflog가 뒤집은 것: Bash cwd 상속 (가설 A)
현상 #10 직후, git reflog를 파헤쳤습니다.
c41a9c5 HEAD@{0}: commit: chore: governance 更新 — worktree 第12編
ffccbb4 HEAD@{1}: merge pr/po-branch: Merge pull request #653 ...
lead의 커밋이 PO 브랜치의 커밋 직후에 쌓여 있었습니다. 타임스탬프를 확인해보니, lead가 PO 브랜치의 PR 머지 (Merge)를 확인하기 위해 git checkout을 실행한 후, cwd (현재 작업 디렉토리)를 그대로 둔 채 다음 작업을 시작했다는 것을 알 수 있었습니다.
이것 역시 Claude Code 공식의 cwd 상속 문제였습니다. 서브 에이전트 (subagent) 완료 후, 부모 세션의 cwd가 worktree 내에 남겨지는 현상입니다. 절대 경로의 문제가 아니라, 현재 작업 디렉토리 (cwd)의 상속이 원인이었습니다.
cwd 상속 문제는 복합적이었습니다. 절대 경로를 통해 뚫리는 케이스와, cwd가 인계되어 뚫리는 케이스 모두 isolation: "worktree"는 막아내지 못했습니다.
해결책: PreToolUse 후크 (hook)를 통한 이중 방어
PR #679에서 채택한 해결책은 isolation: "worktree"를 주 방어벽으로 삼는 것을 그만두고, PreToolUse 후크 (hook)로 물리적으로 차단하는 것이었습니다.
후크 설계는 간단합니다. subagent가 Bash/Edit/Write를 호출할 때마다, 조작 대상 경로가 worktree 외를 가리키고 있지 않은지 체크합니다. worktree 외라면 exit 2로 즉시 차단합니다.
.claude/settings.json에 등록:
{
"hooks": {
"PreToolUse": [
...
후크 스모크 테스트 (smoke test) (5/5 PASS)
| # | 상황 | 기대 결과 | 실제 결과 |
|---|---|---|---|
| 1 | lead가 main에서 Edit | 통과 | exit 0 |
| ... |
전체 5/5 PASS.
13건의 소동 끝에 해결책이 "settings.json 몇 줄"이었다는 사실은 솔직히 조금 웃음이 났습니다.
배운 점
isolation: "worktree"는 "완전한 격리"가 아니라, "기본값을 worktree 내부로 향하게 하는 보조 기능"이었습니다. 절대 경로를 전달하면 뚫리고, cwd가 부모로 돌아가면 효력을 잃습니다.
에이전트의 격리는 에이전트에 대한 지시만으로는 담보할 수 없습니다.
프롬프트에 "worktree 외를 편집하지 말 것"이라고 써도, LLM은 확률적으로만 따릅니다. 13건의 인시던트는 그 확률이 현실이 된 것입니다. 후크는 그것을 결정론적으로 방지합니다.
에이전트가 잘못된 것이 아니라, 인프라가 설계상의 전제를 충족하지 못했던 것입니다. 그것이 솔직한 심정입니다.
Claude Code 공식의 cwd 상속 문제가 수정되면 후크의 일부는 불필요해질지도 모릅니다. 하지만 "후크로 담보한다"라는 사고방식 자체는 남겨둘 생각입니다. 에이전트에게 기대하는 것보다, 환경이 지켜주는 것이 더 확실합니다.
안전한 녹취라는 서비스를 만들고 있습니다. 취재나 회의 음성을 저희 전용 서버에서 처리하며, Google이나 OpenAI 같은 외부 AI 기업에는 전송하지 않는 설계의 SaaS입니다. 사적인 대화를 외부 AI 서비스에 가볍게 넘겨도 괜찮을까? 라는 불안함에서 탄생한 프로젝트입니다. 여러 Claude Code 에이전트와 함께 개발하고 있습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기