하네스란 AI 코딩 도구를 둘러싼 규칙·훅·에이전트 묶음, 곧 작업 틀이다. 그 하네스를 하루 동안 절반 가까이 줄인 기록이다. Opus 5.5 이후 모델이 스스로 잘하게 된 일을 하네스가 한 번 더 하면서 작업이 느려졌다. 그래서 커스텀 에이전트(역할별로 따로 띄우던 보조 모델)와 자동 워크플로를 걷어내고, 그 절차는 스킬(모델이 읽고 따르는 절차 문서)로 옮겨 모델이 직접 수행하게 했다. 남긴 훅은 QA 증거 게이트(검사에 걸리면 push 를 막는 자동 검문)와 비가역 작업 안전장치가 중심이고, 응답 언어처럼 세션의 바탕을 맞추는 훅 몇 개가 함께 남았다. 밤에는 같은 기준을 저장소 안쪽(프로젝트 스코프)까지 넓혀, 저장소마다 따로 정의돼 있던 에이전트와 워크트리의 훅도 걷어냈다.
Opus 5.5 이후의 모델은 계획을 세우고 일을 나누고 결과를 검증하는 일을 스스로 해낸다. 그런데 하네스는 그 일을 에이전트 위임과 훅 검사로 한 번 더 했다. 같은 판단이 두 곳에서 일어나니 작업은 느려지고, 틀릴 수 있는 자리도 두 배가 됐다. 그래서 중간 층을 걷어내고 판단은 모델에, 강제는 게이트에 두는 구조로 바꿨다.
“모델이 이미 하는 판단을 하네스가 한 번 더 한다”
“판단은 모델에, 강제는 게이트에”
general-purpose)에 프롬프트를 인라인으로 넘긴다. 브라우저 QA 도 기본은 리드가 절차를 직접 수행하는 것이고, 얇은 셸로 남긴 web-qa-tester 는 출력이 너무 클 때의 선택지다보관 기준은 "모델이 지금 혼자서도 하는 일인가"였다. 계획을 세우는 planner, 코드를 고치는 executor 와 bug-fixer, 결과를 검토하는 code-reviewer 는 모델이 이미 직접 하는 일이라 에이전트 파일을 보관하고, 필요한 절차만 스킬·규칙으로 옮겼다(executor 본문처럼 모델이 따로 절차 없이 하는 일은 옮기지 않았다). 반대로 외부 지식을 격리해서 소비하는 trend-harvester 나 자기 채점을 막기 위해 생산자와 분리해야 하는 harsh-critic 처럼 격리 자체가 목적인 것은 남겼다. 아래 막대는 최근 30일 동안 각 에이전트가 호출된 횟수다.
harness-phase-runner 는 30일에 2회라 막대를 생략했다), 회색 막대는 보관한 에이전트다. 호출이 많았던 executor 와 qa-functional-runner 도 보관 대상이었다. 기준이 호출 횟수였다면 남았겠지만, 기준은 위의 물음 하나였다. 모델이 혼자서도 하는 일이면 따로 띄워 격리할 이유가 없다.자가개선·수확 루프를 돌리는 5종(self-improve-analyst·trend-harvester·harness-phase-runner·harsh-critic·exhaustive-auditor)과 브라우저 출력이 클 때 쓸 수 있게 남긴 web-qa-tester 다. web-qa-tester 는 926행 절차를 스킬로 옮기고, 절차 없이 스킬을 가리키기만 하는 48행짜리 얇은 셸만 남겼다.
planner·executor·bug-fixer·code-reviewer·qa-orchestrator 등 26종과, 에이전트로 잘못 노출되던 안내 문서 1개를 보관했다. 의도적으로 안 옮긴 3종을 빼면, 절차는 team·plan-design·qa-functional 등 스킬 26개의 문서 37건에 옮겨 적었고, 복사본은 두지 않았다.
team-implement·team-deliver·init-project-bootstrap 등 Workflow 스크립트 6개와 병렬 디스패치 스킬 1개를 보관했다. 30일 동안 Workflow 를 쓴 세션은 4,189개 중 8개였다.
훅은 도구 호출 앞뒤에 끼어 들어 명령을 검사하거나 막는 작은 프로그램이다. 홈 폴더의 사용자 전역 설정(.claude/settings.json)에는 59개가 등록돼 있었다. 그중 15개는 Slack 연결 도구의 것이라 이 글의 셈에서는 빼고, 남은 하네스 훅 44개를 다뤘다. 프로젝트마다 복사해 설치하는 템플릿도 32개 있었다. 둘 다 같은 기준으로 걸렀다. 증거 없는 완료·push 를 막는 QA 게이트와 되돌릴 수 없는 사고를 막는 안전 가드를 중심으로 남기고, "모델이 일을 이렇게 하도록 알려 주는" 종류의 훅은 보관했다. 예외는 user 스코프의 세션 환경 훅 4개다. 응답 언어·권한 설정처럼 일하는 방법이 아니라 세션의 바탕을 맞추는 것이라 남겼다(아래 표 마지막 행). 아래 막대는 항목별로 이전 값을 전체 폭으로 두고 남은 비율을 채운 것이다.
| 남긴 훅의 역할 | user 스코프 (스크립트 18) | 프로젝트 템플릿 (10) |
|---|---|---|
| QA 증거·하네스 무결 게이트 — 증거 없는 완료 선언과 하네스 파일 훼손 차단 | qa-inventory-gate(QA 재고 없이 완료 선언 차단) · settings-hook-target-exists-lint(등록된 훅 파일이 실제로 있는지) · rules-appendix-ban(규칙 파일 뒤에 부록 덧붙이기 금지) · rules-prose-after-structure-gate(규칙 본문의 형식) 4 |
qa-gate-before-push(push 전 QA 증거 — universal·ui-qa 두 벌) · task-quality-gate · claim-done-gate · deploy-verify-marker · codex-review-gate 6 |
| 비가역 안전 가드 — 되돌릴 수 없는 사고 차단 | mass-deletion-guard(대량 삭제) · no-env-commit(비밀 파일 커밋) · trace-tamper-guard(관측 기록 변조) · sandbox-boundary-warn · agent-browser-security(브라우저 세션 전체 종료·셸 주입) 5 |
no-env-commit · secret-content-scan(커밋 내용의 비밀값) · ai-commit-msg-ban(커밋 메시지의 AI 서명) 3 |
| 사용자 결정·완료 위장 차단 | codex-off-guard(Codex 토글이 꺼져 있으면 호출 차단) · requirements-lock-guard(요구 기능 삭제로 "해결" 금지) · test-skip-monotonicity-guard(건너뛴 테스트 증가 금지) · si-round-budget-guard(자가개선 라운드 예산) · agent-model-1m-gate(에이전트 호출에 모델 지정 금지) 5 |
validate-before-commit(web-ts 전용 — 타입·빌드 검사 뒤에만 커밋) 1 |
| 세션 환경 | auto-apply-project-permissions(프로젝트 권한 설정 자동 적용) · korean-response-reminder(한글 응답) · feedback-detector(사용자 지적 감지) · team-session-marker(/team 세션 표식 — QA 재고 게이트 보조) 4 |
해당 없음 — 세션 환경은 user 스코프의 몫이다 |
규칙은 세션이 시작될 때마다 모델에 함께 읽히는 지시 문서다. 그래서 규칙 안에 "이 일은 저 에이전트를 불러서 하라"는 문장이 남아 있으면, 에이전트를 보관해도 모델은 계속 없는 에이전트를 찾는다. 규칙 52개를 전부 훑어 에이전트 위임 전용 규칙 4개는 은퇴시키고, 특정 도구를 쓸 때만 필요한 4개는 필요할 때 읽는 폴더로 옮겼으며, 15개는 "에이전트가 한다"를 "리드가 직접 한다"로 다시 썼다. 보관한 에이전트의 절차는 스킬 26개의 문서 37건에 옮겨 적었다.
Agent(·subagent_type·Workflow 같은 호출 문자열로 훑어 참조 위치를 파일과 행 번호로 목록화했다SKILL.md(진입 문서) 나 PROCEDURE.md(긴 절차서) 에 전문으로 넣고 "리드가 직접 수행" 으로 주체를 바꿨다agents-inactive 의 은퇴 목록에 적고 archive 로, 규칙은 rules-inactive 로, 훅은 archive/2026-10 으로 옮겼다. 동기화 스크립트가 이 목록을 읽어 설정 백업 저장소(미러)에서도 같은 상태를 유지한다trader-hugh 프로젝트의 문서 2곳을 잡아내 고쳤다하네스를 줄이면 그 하네스를 재던 측정기도 함께 낡는다. 은퇴한 에이전트를 기준점으로 삼던 검사기, 보관한 훅을 찔러 보던 생존 점검기가 그대로면 "검사기가 깨진 것"을 "하네스가 깨진 것"으로 읽게 된다. 그래서 측정기 일곱 종을 이 페이지를 쓰는 시점에 새 구성에서 전부 다시 돌렸고, 그중 네 종은 새 구성에 맞춰 고쳤다. 두 종은 고칠 것 없이 통과했고, 한 종은 기대 목록 갱신이 남은 일로 남았다. 아래 수치는 모두 글을 쓰던 2026-10-03 밤에 실행한 결과다.
| 검사기 | 무엇을 재나 | 지금 결과 | 고친 것 |
|---|---|---|---|
keynote-conformance-check.sh |
등록된 차단 훅이 위반 입력에서 실제로 exit 2 를 내는지 |
강제 확인 8/8 user 차단 게이트 전건 | 기대 목록은 그대로 — 보관한 프로젝트 템플릿 3종(scaffold-violation-check 등)이 "빠진 것" 으로 표시되므로 기대 목록 갱신이 남은 일이다 |
gate-liveness-probe.sh |
차단 훅 7종에 위반 입력을 넣어 살아 있는지 | 7/7 통과 프로브가 없는 6종은 표시만 | Agent 호출을 검사하는 agent-model-1m-gate 행을 되살렸다 — 유지 에이전트 6종이 아직 이 길을 쓴다 |
measurement-liveness-watchdog.sh |
측정 기록(원장 — 수치를 시간순으로 쌓는 파일)이 멈추거나 같은 값만 흡수하거나 비었는지, 세 상태를 가려내는지 | selftest 6/6 | 변경 없음 — 새 구성에서도 통과를 확인했다 |
validate-hard-process-contract.py |
규칙·스킬·훅이 서로 가리키는 경로와 마커가 실제로 있는지 | 25/25 user·프로젝트 양쪽 | 은퇴한 team-orchestrator 에이전트를 기준점으로 삼던 항목을 지웠다 |
settings-hook-target-exists-lint.sh |
설정 파일에 등록된 훅의 대상 파일이 디스크에 있는지 | 등록 34 · 부재 0 | 변경 없음 — 보관으로 사라진 파일을 가리키는 등록이 0건임을 확인했다 |
install-project-hooks.sh 스모크 |
새 프로젝트에 설치하면 허용 목록 10개만 깔리고, 은퇴 훅은 지워지며, 증거 없는 push 가 막히는지 | rc=2 설치본 11파일(게이트 9 + 보조 2) | 필수 목록을 universal 7 로, web-ts 는 validate-before-commit 1개로 줄였고 비어 버린 backend·flutter·supabase 분류는 지웠다 |
prune-project-hooks.py |
33개 프로젝트의 설치본과 git 워크트리 47곳에서 허용 목록 밖 훅을 등록·파일 모두 제거 | 잔존 0 33 repo · 47 워크트리 재스캔 | 처음엔 git rm 이 수정된 파일을 거부해 8개 repo 에 51개 파일이 조용히 남았다. 실패를 숨기지 않도록 고치고(-f + 실패 시 중단) 다시 적용했다. 밤의 전수 재고에서는 깊이 3 저장소 4곳과 워크트리가 처음 목록에서 빠져 있던 것을 찾아 같은 절차로 마쳤다(아래 Project Scope 절) |
① 다른 Mac(Mac Studio)에는 보관 훅의 라이브 제거가 아직 전파되지 않았다 — 설정 백업 저장소에서 되돌려 적용하는 스크립트(apply.sh)를 한 번 돌려야 한다. ② 33개 프로젝트·워크트리 46곳의 훅 정리와 프로젝트 에이전트 41종 보관은 각 저장소에 로컬 커밋으로만 있고 push 하지 않았다(push 여부는 저장소마다 따로 정할 몫이고, 원격보다 크게 뒤처진 저장소 1곳은 push 전에 합쳐야 한다). ③ 발표 기준표(keynote)의 기대 목록에 보관 템플릿 3종이 남아 "빠진 것" 으로 표시된다. ④ 전부터 있던 상태 그대로인 것 — self-improve-trigger 훅 미등록, 규칙 효과 측정 6일 정체. 상시 로드 규칙(지금 101,784 바이트)은 더 증류할 여지가 있다. ⑤ 부수 발견 — rules/ 아래에 8월 19일 자동 동기화가 만든 공백 이름 디렉터리 qa-evidence-format.md skills/ 가 라이브·미러 양쪽에 남아 있다(이번 작업 범위 밖, 삭제 후보). ⑥ 두꺼운 진입점 가운데 init-project/SKILL.md(44KB)는 이번 축소로 바뀐 파일이 아니라 아직 가르지 않았다(아래 Audit & Relocation 절의 같은 방식이 적용 후보). ⑦ 설정 백업 저장소(미러)가 brandkit 스킬을 추적하지 않아 그 스킬의 분리는 라이브에만 있다. ⑧ 남긴 에이전트 4종(harsh-critic 등)의 정의가 보관한 스킬 읽기 게이트를 아직 자기 강제자로 적고 있다. 정의 문구를 고치거나 게이트를 다시 등록해야 그 주장이 사실이 된다.
낮의 축소가 끝난 뒤 "잘 옮긴 게 맞나"를 디스크에서 다시 확인했다. 보관한 에이전트 26종의 본문을 살아 있는 스킬·규칙 전체와 줄 단위로 대조하고, 줄로 잡히지 않는 것(영어 원문을 한글로 바꿔 적은 경우)은 출력 형식·판정 규칙·체크리스트 같은 산출 계약이 목적지에 있는지 항목별로 확인했다. 결과는 "대부분 옮겨졌지만 네 곳은 손봐야 했다"였다. 셋은 빠진 것을 채웠고, 하나는 남아 있던 복창을 걷어냈다. 그리고 옮겨 둔 자리가 문제였다. 규칙은 세션마다, SKILL.md 는 스킬을 부를 때마다 통째로 모델에 실리므로, 절차를 그 두 자리에 두면 읽기도 전에 컨텍스트(모델이 한 번에 볼 수 있는 분량)를 차지한다. 그래서 절차를 PROCEDURE.md 와 references/ 로 옮기고 진입점에는 개요와 포인터만 남겼다.
PROCEDURE.md·references/·원문 문서)로 옮겨 가서 실행 단계에서만 읽힌다.| 이식 판정 (보관 26종 = 6 + 17 + 3) | 에이전트 → 목적지 | 근거 |
|---|---|---|
| 전문 이식 6 | hugh-clone→hugh-clone/PROCEDURE.md 94% · bug-fixer→error-recovery 89% · payments-specialist→payments 88% · code-reviewer→fowler-refactoring 78% · qa-scenario-writer→qa-scenario-gen · qa-orchestrator→qa-cycle 63%. 유지한 web-qa-tester 도 926행 절차의 93% 가 webapp-testing/PROCEDURE.md 에 있다 |
원문 줄 대부분(63~94%)이 그대로 남아 있음 (줄 단위 대조) |
| 계약 단위 이식 17 | planner→team 계획 계약 · critic→product-planning 계획 시뮬레이션 통과/반려 판정 · verifier→work-recheck 완료 주장 분류·판정 규칙 · figma-designer→plan-design Figma 빌드 플레이북 · product-manager·designer·information-architect·ux-researcher·analyst→product-planning 산출 계약 11곳 · brand-strategist→brandkit · marketing-lead→marketing-plan · frontend-specialist·backend-specialist→*-patterns 규칙 · vision→plan-design 블라인드 검수 · qa-functional-runner·webapp-test-runner·user-proxy→각 스킬 + QA 검증 단계 규칙 |
문장은 한글로 바뀌었지만 출력 형식·판정 규칙·완료 검사의 토큰이 목적지에 전부 있음 |
| 의도적으로 안 옮김 3 | explore(내장 Explore 와 중복) · writer · executor 본문 — 셋 다 축소 전 기준선에서 이 이름으로 띄우라는 문장(호출처)이 스킬·규칙·훅에 0곳이었다. executor 막대의 143회는 그런 고정 호출 없이 실제로 띄운 횟수다. executor 의 증거 계약(rc 분리 캡처·not_verified)은 error-recovery·*-patterns·completion-verification 규칙에 이미 있다 |
기준선 커밋에서 호출처 0, 모델이 직접 하는 일 |
| 손본 곳 4 (에이전트 수가 아님) | ① 정보 구조(IA) 범용 템플릿 4종(구조 맵·분류 체계·명명 규칙·찾기 쉬움 평가) → product-planning/references/ia-artifacts.md ② UX 리서치 템플릿 4종(발견 매트릭스·리서치 계획·휴리스틱 평가·인터뷰 가이드) → references/ux-research-artifacts.md, 둘 다 단독 요청이 닿도록 스킬 설명에 라우팅 추가 ③ 백엔드 보안 체크리스트의 전역 예외 필터 항목 복원 ④ 스킬 안에 남아 있던 Workflow 정책 복창 3줄 제거(정책은 CLAUDE.md 한 곳) |
30일 직접 호출 — ux-researcher 14회 · information-architect 5회가 쓰던 산출 형식 |
여기까지는 사용자 전역 설정(홈 폴더의 .claude/) 이야기였다. 그런데 하네스는 저장소마다 하나씩 더 있다. 각 저장소의 .claude/ 폴더가 자기 에이전트·훅·스킬을 따로 들고 있고, 이것을 프로젝트 스코프라고 부른다. "프로젝트 스코프도 정리된 건가"라는 물음에 답하려고 이 폴더 152곳을 전부 다시 셌다. 답은 "아니오"였다. 낮의 훅 정리는 폴더 깊이 2까지만 훑어서 깊이 3 저장소 4곳이 빠졌다. 워크트리(한 저장소를 다른 폴더에 하나 더 꺼내 둔 작업 사본) 49곳은 아예 집계 밖이었다. 저장소가 직접 정의한 에이전트 43종에는 손대지 않은 상태였다. 그래서 같은 기준을 저장소 안쪽까지 적용했다. 에이전트가 있는 저장소 8곳 가운데 7곳은 사용자가 병렬 처리를 요청해 Workflow 로 한 번에 돌렸고, 1곳은 직접 고쳤다. 워크트리는 결정론 스크립트(같은 입력에 늘 같은 결과를 내는 스크립트)로 처리했다.
_installed-variants 는 설치본에만 있던 옛 판 훅 7개를 내용 해시를 이름으로 삼아 보관한 곳이다.| 찾은 것 | 한 것 | 근거·판단 |
|---|---|---|
| 훅 정리에서 빠진 저장소 4 | 저장소 묶음 폴더 하나 아래 3곳 + 다른 저장소 안에 들어 있는 하위 저장소 1곳 — 은퇴 훅 파일 105·등록 109 제거, 로컬 커밋 4건. 커밋된 상태(git show HEAD:)에서 잔존 0·등록 대상 부재 0 확인 |
낮의 29개 목록이 폴더 깊이 2까지만 훑었다. 전수 감사기를 project-scope-harness-audit.py 로 남겨 다음에는 깊이와 무관하게 센다 |
| git 워크트리 49 | 46곳 로컬 커밋(8월 자동 이슈 처리가 만든 것 37 · 에이전트 작업용 워크트리 9) · 1곳은 .claude/ 가 gitignore 라 디스크만 · 2곳은 할 일 없음 — 파일 1,092·등록 1,105 제거. 커밋에 든 파일은 전부 .claude/hooks/·settings.json 이고 작업 중인 소스는 섞이지 않았다 |
워크트리는 그 폴더에서 세션이 열릴 때만 훅이 발화하므로 휴면 상태였지만, 남겨 두면 다음 자동 이슈 처리가 옛 훅을 그대로 물려받는다. 더티 작업물이 있어 워크트리 자체는 지우지 않았다 |
| 저장소가 정의한 에이전트 43 → 보관 41 · 유지 2 | 8개 저장소 + 폴더 1곳, 30일 호출 0건(밤에 다시 센 트랜스크립트 4,267개 전수). 호출부가 살아 있던 5종은 그 스킬의 references/ 로 절차를 이식(한 저장소의 채점 스킬 3 · idea-intake 1 · agent-pr-review 1), 36종은 보관한 원문이 그대로 절차 문서 역할을 한다. 호출부 15개 파일(스킬 5 · 운용 문서 10)의 지시를 "리드가 직접 수행"으로 바꿨고, 과거 보고서·코드 문자열 속 언급은 역사 기록이라 그대로 뒀다. 한 저장소는 테스트용 고정 보고서(픽스처)의 줄 해시를 검사하는 게이트가 에이전트 경로를 읽고 있어, 픽스처는 두고 검증기에 경로 재배치 표를 넣었다 |
남긴 2종(관문 판정·자료 수집을 맡은 채점용 에이전트)은 그 저장소의 요구 잠금(.requirements-lock.md — 지켜야 할 문장이 특정 파일에 있는지 세션 종료 때마다 확인하는 장치)이 에이전트 정의의 tools: 행을 "읽기 전용 경계는 말이 아니라 도구 행"이라며 잠가 두었다. 절차 문서로 옮기면 그 저장소가 네 번 폐기한 "말에 건 잠금"이 되므로, 하네스 축소 정책이 예외로 둔 "격리가 꼭 필요한 독립 채점"으로 보고 유지했다 |
| 은퇴 에이전트를 가리키던 문서 4 | 저장소 4곳의 스킬·메모 — bug-fixer 호출 → error-recovery 절차 · code-reviewer·QA 서브에이전트 서술 → 직접 수행 + 교차 리뷰 켜기·끄기 설정(/codex-gate)에 맞춤 · 서브에이전트 메모에 보관 사실 명시 |
서드파티 플러그인이 품은 에이전트 5종(impeccable 4 · ui-ux-pro-max 1)과 과거 보고서·코드 문자열의 언급은 우리 것이 아니거나 역사 기록이라 두었다 |
① 밤 작업의 저장소 15곳 15커밋과 워크트리 46커밋도 낮의 훅 정리처럼 전부 로컬에만 있다. push 여부는 저장소마다 따로 정할 몫이다. ② 로컬 브랜치가 원격보다 크게 뒤처진 저장소가 1곳 있어 push 전에 합쳐야 한다. ③ 남긴 채점용 2종을 유지 에이전트로 바꾸려면 요구 잠금 4행의 경로, 감사 스크립트 1곳, 테스트 픽스처를 함께 고쳐야 한다. 그 절차는 보관 폴더의 안내 문서(README.md)에 적어 두었다. ④ 다음 재고는 project-scope-harness-audit.py 한 번으로 깊이와 무관하게 센다.
"모델이 이미 하는 판단을 하네스가 한 번 더 하면, 작업은 느려지고 틀릴 자리는 두 배가 된다."