AI

Claude Code 설정을 맥 4대에 나눠 담기 — 계층, 플러그인, 상시 로드 비용

시작은 규칙 파일 하나였다

Claude Code 는 CLAUDE.md 라는 파일에 적어둔 규칙을 매 대화에 실어 보낸다. “테이블 행은
| 로 시작하고 끝낸다” 같은 걸 적어두면 매번 말하지 않아도 지켜진다.

처음엔 이 파일 하나였다. 지금은 이렇게 나뉘어 있다.

계층 줄 수 적용 범위
전역 CLAUDE.md 182 맥 4대 전부
CLAUDE-omc.md 73 전역 + 플러그인이 자동 갱신
프로파일 CLAUDE.md 9~48 이 머신만
회사 공통 108 회사 머신 2대만
프로젝트별 가변 그 레포 안에서만

나누게 된 계기는 취향이 아니라 사고였다. 회사 서버 SSH 설정이 개인 레포로 올라갈 뻔했다.

  • 머신 4대: 회사 2 · 개인 2
  • 같은 dotfiles 저장소를 심링크(원본을 가리키는 바로가기 파일)로 공유
  • 그래서 한쪽에 적은 게 다른 쪽에도 그대로 간다

회사 규칙 파일 첫 문단에 그때 정한 원칙이 그대로 적혀 있다.

개인 머신에는 심링크되지 않으므로, 여기에는
회사 머신에서만 성립하는 규칙만 적는다.

프로파일은 호스트명으로 갈린다

머신 이름(scutil --get ComputerName)을 읽어 매핑 파일에서 프로파일을 찾는다. install.sh
609줄이 그 프로파일에 맞는 것만 심링크한다.

회사 머신이면 회사 규칙을 걸고, 개인 머신이면 걸지 않는 게 아니라 지운다.

# company-* 가 아니면 남아 있던 회사 규칙을 제거한다
rm -f ~/.claude/CLAUDE.company.md
  • 이유: 프로파일을 바꿔 달았을 때 이전 설정이 남으면 조용히 틀린 상태가 된다
  • 심링크는 pull 로 전파되지 않는다 — 파일 내용만 간다

이 구분이 계속 발목을 잡았던 부분인데, 별도 글에서 다뤘다:
pull 은 됐는데 설정이 반만 적용된다

빈 계층을 미리 파둔다

회사 머신 두 대는 규칙이 같다. 그런데 각자의 프로파일 파일은 따로 있다. 회사 노트북 쪽
내용은 9줄이고 본문이 이게 전부다.

## 이 머신 전용

(없음 — company-pro 와 다른 규칙이 생기면 여기에 적는다)

빈 파일을 왜 두냐면, 나중에 한쪽에만 필요한 규칙이 생겼을 때 어디에 적을지 고민하지
않기 위해서
다. 자리가 없으면 공용 파일에 넣게 되고, 그러면 다른 머신에도 실린다.

플러그인 — 셋을 함께 쓰는 이유

플러그인 6개를 쓰는데, 그중 셋이 역할이 겹쳐 보인다. 실제로는 층이 다르다.

도구 하는 일
superpowers 프로세스 절차 규율 — 브레인스토밍 → 계획 → 구현
oh-my-claudecode 오케스트레이션 여러 에이전트에 일을 나눠 실행
ECC rules 지식 언어별 코딩 규칙

겹치는 상황이 생기면 전역 규칙에 적어둔 라우팅 표를 따른다. 예를 들어 완료 검증은
superpowers 것을 1회만 쓰고, OMC 검증기는 자율 실행 모드 안에서만 돈다. 둘 다 돌리면
같은 일을 두 번 한다.

ECC 는 플러그인으로 깔지 않았다

everything-claude-code 는 플러그인으로 설치할 수 있지만 rules 만 가져왔다.

  • 이유: 훅(자동 포맷·커밋 차단)과 에이전트 67개가 앞의 두 도구와 겹치거나 충돌한다
  • 필요한 건 “언어별 코딩 규칙”이라는 지식뿐이었다

그리고 가져온 rules 중에서도 common 팩은 뺐다. 이게 이 글에서 가장 중요한 결정이다.

상시 로드 비용이라는 개념

CLAUDE.md 에 적은 내용은 모든 대화에 실린다. 브라우저를 안 쓰는 대화에도 브라우저
규칙이 실린다.

common 팩을 뺀 이유가 그거다.

  • 다른 4개 팩에는 paths 설정이 있다 — 예를 들어 **/*.java 를 건드릴 때만 로드된다
  • common 에는 그게 없어 모든 세션에 약 40K 가 상시로 실린다

즉 21개 파일 1,970줄을 들여놓고도 평소 비용은 0 이다. 자바 파일을 열 때만 자바 규칙이
온다.

같은 이유로 규칙을 두 번 덜어냈다

이 개념을 알고 나서 이미 부어놓은 규칙들을 다시 봤다.

한 번째 — 브라우저 규칙 (2026-07-31)

커밋 메시지에 이유를 적어뒀다.

전역 CLAUDE.md 30줄은 브라우저를 쓰지 않는 모든 대화에도 실려
토큰을 소모하고 다른 규칙의 주의를 분산시켰다.

- 전역 CLAUDE.md 는 한 줄 포인터만 유지 (183 -> 157줄)

내용을 지운 게 아니라 스킬로 옮겼다. 스킬은 필요할 때만 읽힌다. 전역에는 “브라우저를
쓰기 전에 이 스킬을 읽어라” 한 줄만 남겼다.

두 번째 — 동기화 트러블슈팅 (2026-08-20)

이번엔 dotfiles 레포 자체의 규칙 파일이었다.

상시 로드되는 CLAUDE.md 에서 두 종류를 덜어냈다.

- 심링크 표 2개: install.sh 의 link 호출이 원본이라 표는 중복이었고,
  스크립트가 바뀌면 문서만 조용히 낡는다. 포인터로 대체.
- 동기화 트러블슈팅 68줄: 평소엔 안 쓰는 내용이라 스킬로 옮겨
  필요할 때만 로드되게 했다.

11,237자 → 6,155자(45%)

심링크 표를 지운 근거가 따로 있다. 문서에 목록을 적어두면 스크립트가 바뀔 때 문서만
조용히 어긋난다.
그래서 “목록은 install.shlink 호출을 읽어라”로 바꿨다.

이름은 나중에 배웠다

두 번 다 “이건 평소엔 안 쓰는데 왜 매번 실리지”라는 감각으로 옮긴 것이었다. 정작 그 행동에
이름이 붙은 건 8월 22일, 에이전트용 문서 작성법을 다룬 외부 스킬을 가져오면서였다.

  • context load — 상시 로드되는 문서가 매 대화에 지불하는 비용
  • progressive disclosure — 필요할 때만 펼치는 구조

몸으로 먼저 알고 이름은 나중에 배운 순서였다. 이름을 알고 나니 남은 규칙들을 다시 볼 기준이
생겼다는 게 더 컸다.

훅 — 지금 실제로 도는 다섯 개

규칙이 “부탁”이라면 훅은 “차단”이다. 특정 시점에 스크립트가 끼어든다.

시점 하는 일
Bash 실행 전 모든 명령을 타임스탬프와 함께 기록
파일 저장 후 마이그레이션 파일이면 버전 중복 검사
세션 시작 7일 지난 세션 로그 삭제
세션 시작 플러그인 자동 업데이트
세션 종료 macOS 알림

두 번째가 실용적이다. 데이터베이스 마이그레이션은 버전 번호가 겹치면 안 되는데, 보통
합치고 나서야 터진다. 파일을 저장하는 순간 검사하면 그 자리에서 안다.

부탁과 차단은 다르다

이 구분이 중요하다는 걸 실험으로 알았다. 자동 동기화가 실패했을 때 Claude 를 무인으로
불러 해결하게 하는데, 그러려면 못 하게 할 것을 정해야 했다.

--allowedTools "Bash(git status:*)" 처럼 좁혀도
허용목록 밖 명령(cat 등)이 그대로 실행됐다.
반면 --disallowedTools 는 실제로 막혔다.

즉 범위를 좁히는 옵션은 모델에 대한 요청이지 기술적 차단이 아니었다. 반면 훅은
실제로 막혔다(whoami 차단 / echo 통과 확인).

그래서 도구 제한을 설정이 아니라 훅으로 걸었다. 실제로 스킬 24개 중 allowed-tools
쓰는 것이 하나도 없다.

정리

지금 상태를 숫자로 적으면 이렇다.

  • dotfiles 커밋 256개, install.sh 609줄
  • 규칙 계층 5단, 합쳐서 400줄 남짓
  • 플러그인 6개, 훅 5개, 스킬 24개
  • ECC rules 21파일 1,970줄 — 상시 비용은 0

그런데 이 글에서 실제로 배운 건 개수가 아니라 하나다. 모든 규칙에는 상시 로드 비용이
있고, 좋은 규칙도 잘못된 자리에 있으면 다른 규칙의 주의를 분산시킨다.

스킬 이야기는 다음 글에 썼다:
스킬 16개를 만들었더니 명령어 모음이 판단 문서가 됐다.
처음 만든 것은 16줄짜리 셸 래퍼였고 최근 것은 198줄짜리 판단 문서다.