저장소마다 CLAUDE.md를 두고 AI 에이전트에게 작업을 맡깁니다. 처음에는 이 파일을 신입 개발자용 온보딩 문서처럼 썼습니다. 프로젝트 소개, 기술 스택, 폴더 설명, 코딩 컨벤션 — 친절하고 빠짐없이.

그런데 에이전트는 그중 절반쯤을 무시했습니다. 그래서 규칙을 더 적었고, 문서는 길어졌고, 준수율은 오히려 떨어졌습니다.

문제는 문서의 이 아니라 종류였습니다. 우리가 쓴 건 안내문이었는데, 필요한 건 계약서였습니다.

1. 에이전트가 이미 아는 것은 적지 않는다

초기 문서에는 이런 문장이 있었습니다.

- 함수는 한 가지 일만 하도록 작게 유지한다 - 변수명은 의미가 드러나게 짓는다 - 매직 넘버 대신 상수를 쓴다 - 커밋 메시지는 무엇을 왜 바꿨는지 설명한다

전부 맞는 말이고, 전부 없어도 되는 말이었습니다. 이런 건 에이전트가 시키지 않아도 합니다. 일반적인 좋은 관행이라 모델 안에 이미 들어 있습니다.

그런데 이 문장들이 공짜가 아닙니다. 문서가 길어지면 정말 중요한 규칙이 그 사이에 묻힙니다. 30줄짜리 목록에서 27줄이 당연한 말이면, 나머지 3줄도 당연한 말처럼 읽힙니다.

기준: 이 규칙을 안 적으면 반대로 할 것 같은가?

"아니오"면 지웁니다. 남는 건 이 저장소에서만 다르게 하는 것들입니다. 그게 문서가 존재하는 이유입니다.

2. 판단이 갈리는 지점만 남긴다

정리 후 남은 규칙들은 대체로 이런 모양이었습니다.

11ty 는 .njk 만 템플릿으로 처리한다. 나머지 .html 은 바이트 그대로 통과 복사된다 — 그래서 인라인 스타일과 딥링크 스크립트는 빌드의 영향을 받지 않는다. 랜딩·lab 페이지는 페이지 안 인라인 <style> 로 자기완결적으로 유지한다. 기존 방식이므로 굳이 외부 CSS 로 빼지 않는다. 글(posts)은 공유 posts.css 를 쓴다. 글마다 스타일을 새로 만들지 않는다.

두 번째 규칙이 중요합니다. 일반적인 좋은 관행은 "인라인 스타일을 외부 CSS로 빼라"입니다. 이 저장소에서는 반대입니다. 적어두지 않으면 에이전트는 선의로 리팩터링을 시작합니다. 그리고 통과 복사되는 페이지의 인라인 스타일을 뜯어내면서 조용히 뭔가를 깨뜨립니다.

세 번째 규칙은 정반대 방향입니다. 같은 저장소 안에서 페이지 종류에 따라 정책이 갈립니다. 이런 건 코드만 봐서는 의도인지 사고인지 알 수 없습니다.

정리하면 적을 가치가 있는 건 세 종류입니다.

  • 일반적 관행과 반대되는 것 — 안 적으면 에이전트가 "고쳐줍니다"
  • 같은 저장소 안에서 갈리는 것 — 한 사례만 보고 전체에 적용해버립니다
  • 코드에 흔적이 안 남는 것 — 외부 시스템, 배포 절차, 다른 저장소와의 약속

3. 금지에는 반드시 이유를 붙인다

이유 없는 금지는 잘 지켜지지 않습니다. 이유가 붙으면 비슷한 상황까지 일반화됩니다.

이유 없음 — 이 파일만 피하고 끝난다 검색엔진 소유권 확인 파일은 건드리지 않는다. 이유 있음 — 왜 위험한지 알면 판단할 수 있다 검색엔진 소유권 확인 파일(google*.html, naver*.html)은 이름과 내용을 건드리지 않는다. 파일 이름 자체가 인증 토큰이라, 이름을 바꾸면 사이트 소유권 확인이 풀린다.

후자를 읽은 에이전트는 나중에 app-ads.txt나 도메인 확인용 .well-known 파일을 만나도 같은 판단을 합니다. 앞의 문장은 그 파일들에 대해서는 아무것도 알려주지 않습니다.

같은 이유로 "~하지 마라" 대신 "~해라" 쪽이 낫습니다. 금지는 대안이 없으면 회피할 방법을 찾게 만듭니다. "React를 쓰지 마라"보다 "바닐라 JS로 작성한다. 클라이언트 프레임워크를 새로 끌어들이지 않는다"가 실제로 더 잘 지켜졌습니다.

4. 검증 방법을 명시한다

이게 가장 효과가 컸습니다. 에이전트가 "다 됐습니다"라고 말하는 기준을 문서가 정합니다.

## 검증 npm run build # 실패하면 배포도 실패한다. 반드시 통과시킨다. npm run dev # 로컬 서버로 실제 렌더 확인 빌드가 잡아주는 것: 로케일 대칭, 날짜 일치, 글 사이 링크, 템플릿 문법 오류, 참조 실패. 빌드가 잡아주지 않는 것 — 직접 확인한다: - 브라우저에서 레이아웃과 링크가 깨지지 않는지 - 통과 복사되는 .html 의 상대 경로가 디렉터리 깊이에 맞는지 - 딥링크 폴백 동작 (실기기 필요) - 링크 확인 없이 "검증했다"고 말하지 않는다.

앞 절반보다 뒤 절반이 훨씬 중요합니다. 빌드가 통과하면 다 된 줄 아는 게 기본값인데, 여기서 빌드가 무엇을 못 잡는지 명시적으로 알려주기 때문입니다.

마지막 줄은 특히 자주 걸립니다. 확인하지 않은 것을 확인했다고 말하지 않게 만드는, 문장 하나짜리 규칙입니다.

5. 문서가 못 지키는 규칙은 코드로 옮긴다

여기가 진짜 결론입니다. 중요한 규칙일수록 문서에 두면 안 됩니다.

이 사이트는 모든 글이 한국어·영어 한 쌍이어야 합니다. 처음에는 그냥 문서에 굵은 글씨로 적어뒀습니다. 그럼에도 한쪽만 올라가는 일이 생겼습니다. 문서는 읽히지 않을 수 있고, 읽혀도 긴 작업 도중에 밀려납니다.

그래서 빌드 훅으로 옮겼습니다. 이제 한쪽 로케일만 추가하면 빌드가 실패합니다.

Error: ko/en 포스트가 대칭이 아닙니다. en 누락: neat-daily-activity-guide

차이는 결정적입니다. 문서 규칙은 지키면 좋은 것이고, 빌드 규칙은 지키지 않으면 진행이 안 되는 것입니다. 에이전트는 실패한 빌드를 그냥 지나치지 못합니다.

문서에 굵은 글씨로 세 번 강조하고 싶어지면, 그건 코드로 옮길 때가 됐다는 신호입니다.

강조가 필요하다는 건 그 규칙이 자주 깨진다는 뜻이고, 자주 깨지는 규칙은 강조를 더 해도 깨집니다.

물론 전부 자동화할 수는 없습니다. "번역이 기계 번역처럼 읽히지 않게" 같은 건 검사할 방법이 없습니다. 그런 것만 문서에 남기고, 검사 가능한 건 전부 옮기는 게 좋습니다.

6. 보고 규칙 — 무엇을 말해야 하는지 적는다

마지막으로 넣은 절인데, 넣길 잘했습니다.

## 보고 규칙 - 페이지를 추가·이동·삭제했으면 sitemap 과 리다이렉트를 함께 처리했는지 명시한다. - 한 로케일만 작업했다면 반드시 그 사실과 남은 로케일을 보고한다. - 딥링크 스킴을 바꿨다면 iOS/Android 대응 필요를 별도로 명시한다.

에이전트 작업의 위험은 잘못한 걸 잘했다고 말하는 것보다, 절반만 하고 다 했다고 말하는 것에 있습니다. 앞은 리뷰에서 걸리는데 뒤는 안 걸립니다. 무엇을 반드시 언급해야 하는지 미리 정해두면 이 구멍이 상당히 메워집니다.

7. 정리

결과적으로 문서는 절반 이하로 줄었고, 준수율은 확실히 올라갔습니다. 정리하면 이렇습니다.

  • 안 적어도 할 일은 적지 않는다. 중요한 규칙이 묻힙니다.
  • 판단이 갈리는 지점만 남긴다. 일반 관행과 반대되는 것, 저장소 안에서 갈리는 것, 코드에 흔적이 없는 것.
  • 금지에는 이유를 붙인다. 이유가 있어야 비슷한 상황으로 일반화됩니다.
  • 검증 방법을, 특히 빌드가 못 잡는 것을 명시한다.
  • 검사 가능한 규칙은 코드로 옮긴다. 문서는 마지막 수단입니다.
  • 무엇을 보고해야 하는지 적는다. 절반만 한 작업을 드러냅니다.

CLAUDE.md를 사람용 README처럼 쓰고 있다면 한번 다시 보세요. 읽는 쪽은 프로젝트를 처음 보는 사람이 아니라, 일반적인 관행은 이미 다 아는데 이 저장소의 예외는 하나도 모르는 협업자입니다. 문서는 그 차이만 담으면 됩니다.