하네스 기본기로 내 저장소의 검증 장치 점검하기
캐시 · Claude Code MVP 공장 · · 좋아요 0 · 답글 0
연재 Claude Code MVP 공장 시즌 9 3/12편
소개
1주차 강의의 하네스 기본기로 제 전역 설정과 저장소 8곳을 세어 보니, 규율은 CLAUDE.md와 rules에 많이 적어 두었는데 Claude Code 안에서 검사하는 hook은 0개였습니다. 적어 둔 규칙을 실제로 확인하는 장치가 있는지 점검해 보고 싶은 분이 읽으면 좋겠습니다.
CTO 스터디 1주차 지식 공유는 "여러분은 지금 전혀 하네스를 하고 있지 않다"는 짤로 시작했습니다. 개발자F 님은 하네스를 두 가지 센서로 나눴습니다. 추론적 센서는 모델이 읽고 따르는 규칙(CLAUDE.md, rules, 서브에이전트, 프롬프트)이고, 연산적 센서는 프로그램이 기계적으로 검사하고 막는 장치(hook, CI, 린트, 빌드, 테스트)입니다. 규칙만 있으면 "지침을 읽었지만 이번엔 넘어갔다"가 생기고, 검사만 있으면 "규칙에 없어서 통과시켰다"가 생긴다는 표가 슬라이드에 있었습니다.
강의 내용 자체는 기본적이었습니다. 그런데 기본이라서 오히려 제 상태를 물어볼 만했습니다. 저는 Claude Code로 연구용 파이프라인과 해커톤 출품작을 만들고, 전역 CLAUDE.md와 rules에 규율을 꽤 많이 적어 두었습니다. 그 규율이 어느 센서에 들어 있는지는 따로 세어 본 적이 없습니다.
그래서 이번 주는 강의가 든 기본기를 항목표로 만들고, 제 전역 설정과 ~/projects 아래 제가 직접 개발한 저장소 8곳을 항목마다 명령으로 셌습니다. 이 스터디의 주제가 "알아서 개발하는" MVP 공장이니, 사람이 매번 시키지 않아도 돌아가는 검증 장치가 얼마나 있는지가 관심사였습니다.
진행 방법
사용 도구: Claude Code, git, Python 3
Step 1. 강의 기준을 항목표로
슬라이드 19장과 Q&A에서 나온 기준만 골랐습니다.
센서
강의 기준
잴 것
추론적
CLAUDE.md는 200줄 이내, 매 세션 필요한 사실만, 파일 트리는 넣지 않음
줄 수, 트리 문자(├──, └──) 수
추론적
rules는 주제별로 나누고 paths:를 단다. paths가 없으면 항상 로딩
rules 수, paths 있는 rules 수
추론적
리뷰는 별도 컨텍스트, 도구를 Read, Grep, Glob으로 제한한 읽기 전용 리뷰어
쓰기 도구가 없는 에이전트 수
연산적
반드시 지킬 규칙은 hook으로. 린트, 빌드, 줄 수 검사를 hook이 대신
프로젝트 hook, 그중 검사하는 hook
연산적
CI, 린트, 테스트
워크플로 내용, 린트 설정 파일, 테스트 파일 수, 코드 커밋 중 테스트 동반 비율
문서 기준
Markdown은 사람이 읽고, 작업 상태는 JSON처럼 도구가 바꾸는 형식으로
작업 상태 파일의 형식, md 체크박스 수
예시
"코드는 300줄 이내"는 CLAUDE.md에 쓰면 부탁이고 hook으로 막으면 강제
지금 300줄을 넘는 코드 파일 수
Step 2. 전역 설정 세기
cd ~/.claude
wc -l CLAUDE.md rules/*.md | tail -1 # 673 total
ls rules/*.md | wc -l; grep -l '^paths:' rules/*.md | wc -l # 10, 0
python3 -c "import json; h=json.load(open('settings.json'))['hooks'] ..." # 이벤트별 hook 명령
항목
값
전역 CLAUDE.md
81줄. rules 9개를 @로 가져옴
~/.claude/rules/
10개, 592줄. paths:가 있는 것 0개
세션마다 항상 들어오는 줄 수
673줄 (CLAUDE.md 81 + rules 592)
전역 hook
18개. 설치 팩(~/.cys/pack)에서 들어온 것 17개, 제가 만든 것 1개(Bash 실행 전 git 스냅샷)
그중 린트, 테스트, 줄 수를 검사하는 hook
0개. 막는 hook 2개(appbuild-gate, grill-gate)는 설치 팩의 작업 순서 관문
설치 팩 hook은 제가 만든 것이 아니어서 따로 세었습니다. 지난 기수에 이것을 자작으로 셀 뻔한 일이 있었습니다.
Step 3. 저장소 8곳 세기
~/projects 아래 git 저장소 18개 중 제가 개발한 8개를 골랐습니다. 팀 저장소(autobiox), 포크(quartz), 남의 저장소는 뺐습니다. 클라우드 루틴이 원격에 커밋하는 저장소가 있어 먼저 git fetch를 했습니다. econ-radar는 로컬이 원격보다 120커밋, paper-radar는 17커밋 뒤처져 있었고, 커밋은 --all로 원격 추적 브랜치까지 합쳐 셌습니다.
files = git(r, "ls-files").splitlines()
CODE = re.compile(r"\.(py|ts|tsx|js|jsx|mjs|sh|R|r)$")
TEST = re.compile(r"(^|/)(tests?/|test_[^/]*\.py$|[^/]*_test\.py$|[^/]*\.(test|spec)\.[jt]sx?$|conftest\.py$)")
rules_paths = sum(1 for p in rules if re.search(r"^paths:", p.read_text()[:400], re.M))
log = git(r, "log", "--all", "--no-merges", "--name-only", "--format=@@%H\t%an")
code_c = [c for c in commits if any(CODE.search(f) and not TEST.search(f) for f in c.files)]
with_t = [c for c in code_c if any(TEST.search(f) for f in c.files)]
over300 = sum(1 for f in code if line_count(f) > 300)
git 훅은 .git/hooks만 보면 놓칩니다. git config core.hooksPath로 다른 폴더를 쓰는 저장소가 하나 있었습니다.
저장소
CLAUDE.md
rules (paths)
Claude hook
git 훅
CI
테스트 파일
코드 커밋 중 테스트 동반
300줄 넘는 코드
econ-radar
55줄
0
0
없음
발송 3
0
0 / 37
2 / 9
VeriVar
122줄
0
1 (세션 기록 안내)
없음
pytest 1
25
6 / 9
9 / 90
paper-production-harness
없음
0
0
없음
없음
0
0 / 3
0 / 2
paper-radar
60줄
0
0
없음
발송 1
0
0 / 8
1 / 3
paper-analysis-harness
39줄
0
0
없음
구조 검사 1
0
0 / 2
12 / 20
KoreaAgenticAIhackathon
85줄
0
0
없음
없음
16
12 / 43
14 / 55
AgentForgeAI
없음
0
0
없음
없음
1
6 / 13
1 / 24
healthcareai
없음
0
0
pre-commit
없음
6
16 / 23
9 / 46
합계
5 / 8곳
0
검사 hook 0
1곳
테스트 CI 1곳
48 (4곳)
40 / 138 (29%)
48 / 249 (19%)
Step 4. 표에서 따로 본 것
CLAUDE.md는 기준을 지킵니다. 다섯 개 모두 200줄 이내이고 트리 문자는 0개였습니다. 다만 paper-analysis-harness의 AGENTS.md는 461줄에 트리 문자 24개가 있었습니다. 이 저장소의 CLAUDE.md는 AGENTS.md를 @로 가져오지 않고 링크로만 가리킵니다. 슬라이드에 "AGENTS.md는 CLAUDE.md가 없을 때만 읽는다"고 적혀 있었으니, 461줄은 에이전트가 링크를 따라갈 때만 읽힙니다.
hook은 하나뿐이고, 그것도 검사가 아닙니다. VeriVar의 SessionStart hook은 그날 세션 로그 파일을 만들고 "작업 내용을 여기 적으라"고 안내하는 문장을 출력합니다. 규칙을 전하는 hook이라 오히려 추론적 센서에 가깝습니다. 편집 뒤 린트나 테스트를 돌리는 PostToolUse, 끝내기 전에 검증하는 Stop hook은 8곳 모두 0개였습니다.
연산적 센서가 있는 곳은 Claude 바깥이었습니다. healthcareai의 pre-commit은 반출 금지 파일과 결과의 지위를 잘못 적은 문장("사전등록" 같은 말)을 커밋 단계에서 막습니다. VeriVar의 CI는 push 때 pytest를 돌립니다. 둘 다 사람이 커밋하거나 push할 때 걸리고, 에이전트가 파일을 고치는 순간에는 걸리지 않습니다. CI 워크플로 6개 중 4개는 텔레그램과 이메일 발송이었습니다.
린트 설정 파일은 8곳 모두 0개였습니다. ruff, flake8, eslint, biome 설정 파일도 pyproject.toml의 해당 절도 없었고, 이 맥에는 ruff가 설치되어 있지 않았습니다. 강의의 hook 예시 첫 줄이 "린트 체크, 빌드 체크"였는데 걸 대상부터 없었습니다.
작업 상태는 전부 Markdown이었습니다. TODO.md 2개, HANDOFF.md 3개, PLAN.md 2개가 상태를 들고 있고 JSON이나 YAML로 된 작업 상태 파일은 0개였습니다. econ-radar TODO.md 19개, paper-radar 13개 등 체크박스가 33개입니다. 강의가 "md에 체크박스를 넣고 끝날 때마다 체크하라고 하면 누락이나 임의 수정이 생긴다"고 한 그 형태입니다.
읽기 전용 리뷰어는 1개였습니다. 프로젝트 6곳에 정의된 에이전트 56개 가운데 도구 목록에 Write, Edit, Bash가 없는 것은 AgentForgeAI의 domain-critic 하나였습니다. 전역 에이전트에는 없었습니다.
결과와 배운 점
측정 결과 (2026-10-04, 전역 설정과 ~/projects 저장소 8곳)
항목
값
Claude Code 검사 hook (린트, 테스트, 줄 수)
0개. 프로젝트 hook은 VeriVar SessionStart 1개
paths가 달린 rules
0개. 전역 rules 10개는 모두 상시 로딩
세션마다 항상 들어오는 전역 지침
673줄 (강의 기준 200줄)
코드를 고친 커밋 중 테스트 파일도 고친 커밋
40 / 138 (29%). healthcareai 16/23, KoreaAgentic 12/43, econ-radar 0/37
테스트 파일이 있는 저장소
4 / 8곳 (48개)
300줄을 넘는 코드 파일
48 / 249개 (19%). 가장 긴 파일 1,576줄
린트 설정 파일
0 / 8곳
작업 상태 파일
Markdown 7개, JSON 0개
Claude 바깥의 검사
git pre-commit 1곳, pytest CI 1곳
배운 점
저는 강의가 권한 순서를 거꾸로 쌓았습니다. 개발자F 님은 새 프로젝트에서 hook부터 만들고, hook으로 못 막는 것을 rules로, 전체를 아우르는 것을 CLAUDE.md로 올린다고 했습니다. 가장 좁은 것부터입니다. 제 저장소는 CLAUDE.md가 5곳, paths 달린 rules가 0곳, 검사 hook이 0곳입니다. 가장 넓은 층만 있고 좁은 층은 시작하지 않았습니다.
규율은 많은데 전부 추론적 센서에 있습니다. 전역
testing-discipline.md는 "눈으로 확인할 수 없는 숫자를 내는 코드는 검사를 먼저 쓴다"고 적고 있고 114줄입니다. 그 규칙을 지키는지 확인하는 장치는 없습니다. 테스트 동반 비율이 70%(healthcareai)에서 0%(econ-radar)까지 갈린 것은 그 저장소에서 제가 얼마나 신경 썼는지의 차이로 보입니다. 강의 표현으로는 "지침을 읽었지만 이번엔 넘어갔다"입니다.연산적 센서가 있는 저장소에서도 그 센서는 사람 쪽에 걸려 있습니다. healthcareai의 pre-commit은 10월 3일에 유출 검사로 시작했고, 외부 검수 4차 뒤 문구 검사가 더해졌습니다. 커밋 단계라 막는 시점이 늦고, 에이전트가 파일을 고친 직후에는 아무것도 돌지 않습니다. 강의가 말한 hook은 그 앞, 에이전트가 쓰는 순간에 종료 코드 2로 에러를 돌려줘 사람에게 오기 전에 고치게 하는 장치입니다.
제 CLAUDE.md에 틀린 문장이 있었습니다. 전역 CLAUDE.md 81번째 줄에 "환경 설정은 자동 로드하지 않는다, 필요할 때
rules/environment.md를 읽는다"고 적혀 있습니다. 그런데 슬라이드대로라면~/.claude/rules/에 있고 paths가 없는 파일은 세션 시작 때 항상 로딩됩니다. 이 측정을 한 세션의 시작 컨텍스트에도 environment.md 164줄이 들어와 있었습니다. 제가 직접 쓰고 읽은 Markdown인데도 실제 동작과 어긋나 있었고, 강의가 "CLAUDE.md는 코드처럼 검토한다"고 한 이유를 여기서 확인했습니다."300줄 넘으면 다시" hook을 지금 걸면 파일 48개가 바로 걸립니다. 1,576줄짜리 파일도 있습니다. 기존 파일에 일괄 차단을 걸면 아무 작업도 못 하게 되니, 새 파일과 새로 늘어난 줄부터 거는 식으로 시작점을 정해야 합니다.
시행착오
처음에 git 훅을
.git/hooks에서만 찾아 8곳 모두 0으로 나왔습니다. healthcareai는core.hooksPath=.githooks를 쓰고 있었습니다. 다시 세어 1곳으로 고쳤습니다.에이전트의 읽기 전용 여부를
tools:줄로 판정했더니 전역 에이전트 9개가 읽기 전용으로 나왔습니다. 그 9개는tools:줄이 없어 오히려 모든 도구를 갖는 경우였습니다. 줄이 있고 쓰기 도구가 없는 경우만 세니 0개였습니다.econ-radar를 로컬만 보면 마지막 커밋이 8/7입니다.
git fetch뒤 원격은 10/3이었고 120커밋 차이가 났습니다. 원격 커밋 대부분은 클라우드 루틴(작성자 Claude 253커밋)이 만든 발행물이라 코드 커밋 수에는 거의 영향이 없었습니다.테스트 판정은 파일 이름 규칙(
tests/,test_*.py,*.test.ts등)에 의존합니다. 이름 규칙 밖의 검사 스크립트(healthcareai의scripts/check_*.py)는 테스트로 세지 않았습니다.
이 측정은 2026년 10월 4일 ~/.claude의 전역 설정과 ~/projects 아래 제가 개발한 git 저장소 8곳(원격이 있는 곳은 git fetch 뒤 모든 브랜치)의 추적 파일과 병합을 뺀 커밋 기록을 Python과 git으로 센 결과입니다. 팀 저장소와 포크, 다른 기기의 설정은 보지 않았고, 테스트 여부는 파일 이름 규칙으로만 판정했습니다.
도움 받은 글 (옵션)
CTO 1주차 지식 공유 (개발자F): 추론적 센서와 연산적 센서의 구분, CLAUDE.md 200줄과 파일 트리 금지, paths 달린 rules, 읽기 전용 적대적 리뷰어, Codex 플러그인 교차 검증, 종료 코드 2로 돌려주는 hook, hook에서 rules, CLAUDE.md로 가는 순서
CTO 1주차 사례 발표 (댕댕이멍멍): Claude Code와 Unity CLI로 2.5D 뱀서류 게임 만들기. 그릴링 스킬로 구체화하고 마일스톤 7단계로 나눠 하나씩 확인한 과정
Claude Code 공식 문서: How Claude remembers your project, Organize rules with .claude/rules/, Automate actions with hooks (강의 슬라이드의 출처 줄에서)
태그: #CTO