진행 기간: 2026.06 Claude Code로 한 레포를 오래 다루다 보면 "매번 같은 걸 다시 설명하는" 순간이 온다. PR 본문은 이렇게 써라, Dooray 업무 제목은 이 형식이다, 한국어로 풀어 써라. 이걸 어디에 적어둬야 Claude가 실제로 지키는지 — 그게 이 글의 주제다. 나는 그동안 이런 규칙을 프로젝트 안 .claude/skills/s...
진행 기간: 2026.06
Claude Code로 한 레포를 오래 다루다 보면 "매번 같은 걸 다시 설명하는" 순간이 온다. PR 본문은 이렇게 써라, Dooray 업무 제목은 이 형식이다, 한국어로 풀어 써라. 이걸 어디에 적어둬야 Claude가 실제로 지키는지 — 그게 이 글의 주제다.
나는 그동안 이런 규칙을 프로젝트 안 .claude/skills/_shared/ 같은 폴더에 마크다운으로 두고 CLAUDE.md에서 링크만 걸어왔다.
그런데 어느 순간 깨달았다. 링크만 걸어두면 Claude가 그 파일을 잘 안 본다. 규칙을 적어놨는데 안 지켜지는 경험이 반복됐다.
이번에 그 구조를 제대로 정리하면서, Claude Code의 메모리 시스템이 정확히 무엇을 언제 읽는지 공식 문서까지 뒤져 확인했다.
관련해서 스킬·CLAUDE.md를 키워온 과정은 Claude Code를 5주 더 쓴 결과에 정리해뒀고, 이 글은 그중 로딩 메커니즘을 깊이 판다.
Claude Code가 세션 시작 시 자동으로 읽는 것은 정해져 있다. 내가 헷갈렸던 부분을 표로 정리하면:
| 위치 | 로드 시점 |
|---|---|
CLAUDE.md (레포 루트 + 상위 디렉터리들 + ~/.claude/CLAUDE.md) | 모든 세션 시작 시 항상 |
CLAUDE.md 안의 @경로 import | CLAUDE.md를 읽을 때 그 파일도 펼쳐서 함께 (최대 4홉) |
.claude/rules/*.md — frontmatter 없음 | 모든 세션 시작 시 자동 |
.claude/rules/*.md — paths: frontmatter 있음 | 그 glob에 맞는 파일을 읽을 때만 |
~/.claude/rules/*.md (개인) | 모든 프로젝트에 자동, 프로젝트 규칙보다 먼저 |
[텍스트](경로) 마크다운 링크 | 자동 아님 — 그 작업을 할 때 Read로 직접 열 때만 |
여기서 내가 오래 착각한 게 마지막 줄이다.
CLAUDE.md에 [PR 컨벤션](.claude/skills/_shared/pr-conventions.md) 식으로 링크를 걸어두면, 그건 "필요하면 열어봐라" 수준이지 자동 로드가 아니다.
Claude는 CLAUDE.md 본문은 항상 읽지만, 링크된 파일은 그 작업을 할 때 직접 열어야 본다. 안 열면 모른다.
.claude/rules는 그냥 폴더가 아니다처음엔 나도 .claude/rules/를 "우리가 만든 폴더 이름" 정도로 생각했다.
그래서 누가 "rules 폴더의 규칙은 언제 트리거되냐"고 물었을 때, 나는 자신 있게 **"그건 특별한 폴더가 아니라서 자동 트리거가 없다"**고 답했다.
틀렸다.
공식 문서를 직접 열어보니 .claude/rules/는 Claude Code가 인식하는 특별 폴더였다.
paths frontmatter가 없는 규칙 파일은 .claude/CLAUDE.md와 동일한 우선순위로 모든 세션에 자동 로드된다.
하위 디렉터리(rules/frontend/)도 재귀적으로 발견되고, 심볼릭 링크로 레포 간 공유도 된다.
추측을 사실처럼 말하면 안 된다는 걸 다시 배웠다. "특별한 폴더가 아닐 것이다"는 그럴듯한 추측이었지만, 1분이면 공식 문서로 확인할 수 있는 거였다.
확인하고 나니 해법이 단순해졌다.
규칙을 링크로 거는 대신 .claude/rules/에 파일로 두면, 그 자체로 매 세션 자동 로드된다.
"링크만 걸면 안 본다" 문제가 폴더 위치만 바꿔도 해결된다.
규칙이 항상 필요하진 않다. API 코드에만 해당하는 규칙을 매 세션 로드하면 컨텍스트만 잡아먹는다.
paths frontmatter로 특정 파일을 읽을 때만 로드되게 좁힐 수 있다.
---
paths:
- "src/api/**/*.ts"
---
# 이 규칙은 Claude가 src/api 아래 .ts를 읽을 때만 로드된다paths가 없으면 무조건 로드. 트리거는 "그 패턴 파일을 읽을 때"지 "모든 도구 호출마다"가 아니다.
나는 PR·Dooray 컨벤션은 paths를 안 붙였다. "PR 만들 때"는 특정 파일 편집이 아니라 glob으로 잡히지 않는 시점이라, 차라리 짧게 만들어 항상 로드하는 편이 맞았다.
여기가 이 글에서 가장 중요한 부분이다.
CLAUDE.md든 .claude/rules든, 이건 시스템 프롬프트가 아니라 사용자 메시지로 전달되는 컨텍스트다.
Claude는 읽고 따르려 하지만 엄격하게 보장하지 않는다. 공식 문서도 이 점을 명시한다.
나는 이걸 머리로는 알았는데, 이번에 직접 데였다.
PR 컨벤션 규칙 파일 안에 "PR 생성 직전 자가 점검" 체크리스트를 적어뒀다.
1번 항목이 "이슈 트래커 딥링크가 클릭되는 웹 URL인가?"였다.
그런데 정작 내가 PR을 만들 때, 그 체크리스트를 형식적으로 통과시키고 깨진 링크(task/None/...)를 그대로 박았다.
규칙 파일에 점검 항목이 있었는데도, 그걸 실제로 실행하지 않은 거다. 사용자가 "이 링크 왜 None이냐"고 짚어서야 발견했다.
원인을 파보니 두 겹이었다.
projectId가 None이고 실제 값은 d['project']['id']에 있었는데, 규칙 파일의 예제 코드가 d.get('projectId')로 잘못 짜여 있었다. 규칙 자체가 버그였다.# 잘못된 버전 — projectId는 최상위에 없다
print(f"https://.../task/{d.get('projectId', 'UNKNOWN')}/{d['id']}") # → task/None/...
# 실측 후 수정 — d['project']['id']
print(f"https://.../task/{d['project']['id']}/{d['id']}")교훈은 명확했다. "자가 점검하라"를 문서에 적는 것과, 그게 실제로 실행되는 것은 다르다. 특정 시점에 반드시 실행돼야 하는 검증이라면 — 공식 문서가 정확히 이 경우를 위해 답을 준다 — 문서가 아니라 PreToolUse hook으로 박아야 한다. Hook은 셸 명령으로 실행되고, Claude가 무엇을 하기로 결정하든 무관하게 강제된다. 문서는 "지키려고 노력"이고, hook은 "안 지키면 막힘"이다.
규칙을 정리하면서 또 하나 분명해진 건 어디에 두느냐가 곧 누가 쓰느냐라는 점이다.
처음에 나는 PR 양식 같은 공통 규칙을 개인 글로벌(~/.claude/rules/)에 두고, 레포 문서에서 그 개인 경로를 참조하게 만들었다.
그런데 이러면 팀원이 레포를 clone했을 때 ~/.claude/... 파일이 없어서 참조가 깨진다.
애초에 "한국어로 풀어 써라" 같은 건 내 개인 취향이지 팀 강제 규칙이 아닌데, 레포 문서가 그걸 가리키는 것 자체가 잘못된 결합이었다.
그래서 출처 기준으로 갈랐다. (이 "출처 기준 분리"는 5주 회고에서 한 번 정리했던 원칙인데, 이번에 위치까지 못 박았다.)
| 규칙 성격 | 위치 | 이유 |
|---|---|---|
| 팀 공유 (PR 본문·이슈 트래커 컨벤션) | 레포 .claude/rules/ | clone하면 팀원도 자동으로 가짐 |
| 개인 취향 (글쓰기 스타일·가독성) | 개인 ~/.claude/rules/ | 내 모든 레포에 자동 적용, 팀엔 강제 안 함 |
핵심 규율 하나: 레포에 커밋되는 문서가 개인 글로벌 경로(~/.claude/...)를 참조하지 않게 한다.
팀원에겐 그 파일이 없다. 개인 룰은 개인 글로벌에서만 살아야 하고, 레포는 그 룰을 몰라도 동작해야 한다.
여러 레포가 공유할 규칙이라면 ~/shared-rules/ 같은 곳에 원본을 두고 각 레포 .claude/rules/에서 심볼릭 링크를 거는 방법도 있다. 공식 문서가 순환 링크까지 처리한다고 한다.
이 구조를 새 레포에 적용할 때 내가 따르는 순서는 이렇다.
.claude/rules/<주제>.md에 파일로 둔다. 커밋하면 끝 — 팀원도 매 세션 자동 로드된다.~/.claude/rules/에만 둔다./memory — 현재 세션에 실제로 로드된 CLAUDE.md·rules 파일 목록을 보여준다. 목록에 없으면 Claude가 못 본 거다. "규칙을 적었는데 안 지킨다" 싶을 때 제일 먼저 여기를 본다.paths 규칙으로 쪼개거나 그냥 정리한다.규칙을 "문서로 적어두면 지켜진다"고 믿었던 게 가장 큰 착각이었다. 이번에 깨진 링크를 직접 만들고 나서야, 문서는 컨텍스트일 뿐이고 강제가 필요하면 hook이라는 경계가 손에 잡혔다. 그리고 "rules 폴더는 특별하지 않을 것"이라는 추측을 사실처럼 말했다가 공식 문서에서 정반대를 확인한 것도 — 1분이면 검증할 수 있는 걸 추측으로 때우려 한 내 습관을 다시 보게 했다.
남은 숙제는 자가 점검을 hook으로 옮기는 일이다. 지금은 규칙 파일에 체크리스트만 있어서, 이번처럼 내가(또는 Claude가) 형식적으로 통과시키면 또 빠져나간다. gh pr create 시점에 PreToolUse hook으로 링크 검증을 박으면 그제야 "안 지키면 막힘"이 된다.