🤖
4204 in / 2000 out / 6204 total tokens
설계 문서만 있고 실제 동작하는 .claude/ 파일이 없었다. 오늘 그걸 전부 구현했다. Hook 4개, 에이전트 4개, 오케스트레이터 진입점, /build 슬래시 커맨드까지 403줄을 한 커밋에 때려 넣었다.
커밋 메시지는 feat: 하네스 시스템 .claude 구현 (1~6단계). 11개 파일 추가, 삭제 없음. 깔끔하게 추가만 했다.
Hook 4개를 settings.의 PreToolUse에 물렸다. security-guard.sh는 🟢 block 레벨이라 서버 소켓 핸들러에 checkRateLimit() 호출이 없으면 아예 커밋을 차단한다. 나머지 셋은 🟡 warn이라 경고만 띄운다. fairness-guard.sh는 클라이언트 코드에서 Math.random() 같은 걸 감지하는데, 서버 측 파일이나 연출용(sprites, animation 등)은 제외 처리했다. 이거 안 하면 파티클 이펙트 코드에서 계속 걸린다.
bash
fairness-guard.sh 핵심 로직
서버 측 제외
if echo "$FILE" | grep -qE '(socket|routes|db|node_modules|tests|AutoTest)/'; then exit 0 fi
연출용 파일 제외
if echo "$FILE" | grep -qE '(sprites|commentary|tagline|gif-|animation|part'; then exit 0 fi
css-var-guard.sh는 CSS에서 색상을 #fff 같이 하드코딩하면 걸리게 했다. CSS 변수 쓰라는 거다. mobile-guard.sh는 viewport 메타 태그 누락, 고정 너비, 터치 타겟 44px 미만을 잡아낸다. 모바일 퍼스트 원칙을 강제하는 장치다.
에이전트 4개는 역할 분리를 명확히 했다. Scout은 읽기 전용으로 코드베이스를 정찰한다. 수정 대상 파일, 참조 파일, 기존 패턴, 불변조건을 보고서 형태로 뽑아낸다. allowed-tools를 Grep, Glob, Read, Bash(readonly)로 제한해서 절대 파일을 건드리지 못하게 막았다. Coder는 이더 지시서 기반으로 모바일 퍼스트 구현을 한다. Reviewer는 보안 + 패턴 준수 + 반응형 + UI/UX를 종합 리뷰하고 결론을 먼저 말한다(approve/request-changes). QA는 공정성 체크리스트 전항목, 멀티플레이어 동기화 시나리오, 엣지케이스 최소 3개를 강제한다.
이 분리가 중요한 이유는 게임 서버 개발에서 '역할 혼합'이 버그의 원인이 되기 때문이다. UE5에서도 GameMode, GameState, PlayerController를 분리하듯, AI 에이전트도 정찰-구현-리뷰-검증을 나눴다.
오케스트레이터인 SKILL.md가 이 에이전트들을 파이프라인으로 묶는다. 트리아지 판정이 먼저다. 수정 파일 1~2개면 SIMPLE, 3개 이상이면 STANDARD, 공정성/DB/멀티플레이어 건드리면 COMPLEX. STANDARD 이상이면 Scout→Coder→Reviewer→QA 순으로 실행한다. COMPLEX일 때만 QA가 들어간다. SIMPLE이면 Coder가 바로 구현한다.
/build 슬래시 커맨드는 이 오케스트레이터의 진입점이다. 사용자가 /build 새로운 주사위 게임 추가라고 치면, SKILL.md의 지시에 따라 트리아지 → 정찰 → 구현 → 리뷰 → 검증 → 보고가 자동으로 돈다.
Hook에서 잡는 것과 에이전트가 검증하는 것이 겹치지 않게 설계했다. Hook은 '코드를 쓰는 순간' 실시간으로 걸는 방어막이고, 에이전트는 '코드를 다 쓴 후' 구조적으로 검증하는 레이어다. 예를 들어 security-guard.sh는 파일 저장 시점에 Rate Limiting 누락을 차단하고, Reviewer 에이전트는 전체 보안 체크리스트를 리뷰 시점에 돌린다. 세분화된 방어 vs 통합 검증의 관계다.
settings.에 Hook 4개를 PreToolUse 이벤트에 연결하는 걸 까먹을 뻔했다. Hook 스크립트만 만들어놓고 settings.에 안 넣으면 아무 일도 안 일어난다. 이거 확인하느라 30분 날렸다.
Hook 스크립트가 stdin에서 JSON을 파싱하는 방식이 다 똑같다. node -e로 tool_input.file_path와 tool_input.content를 빼내는데, 이 패턴을 4개 파일에 복붙했다. 나중에 공통 함수로 빼든가 해야겠다.
403줄 추가에 삭제 0이라 리팩토링이 아니라 완전한 녹색 필드 구현이었다. 설계 문서(docs/harness/)가 있어서 수월했다. 문서 없이 이 정도 구조를 한 번에 짜면 아마 3번은 갈아엎었을 것이다.
Hook은 실시간 방어막, 에이전트는 구조적 검증 레이어. 둘이 합쳐서 '쓰는 순간'과 '다 쓴 후'를 모두 커버한다.