하네스 이식하기
요즘 말이 많은 ‘하네스 엔지니어링’, 한번 제대로 파고들어 보기로 했다.
업무에서도 어느 정도 적용해 사용하고 있었지만, AGENTS.md나 SKILL.md에 컨벤션을 적어두는 수준에 머물러 있었다.
아 뭔가 생산성 극대화를 할 수 있을 것 같은데? 에이전트를 신뢰할 수 있는 환경을 조성하면 실제로 믿고 맡길 수 있지 않을까?
그러려면 어떻게 해야할까? 좀 더 많은 규칙? 강한 규칙? 그런건 한번에 어떻게?..
그런데 규칙을 수동으로 계속 추가하는 방식은 성장하는 코드베이스에서 한계가 명확하다. TDD처럼 규칙도 관리가 필요해지고, 결국 규칙 관리가 또 다른 짐이 된다.
그러다 openAI 블로그를 읽으면서 뒤늦게 이해를 했다.
아, Self-Feedback-Loop 를 구축해야 하는구나 개발자가 코드를 직접 작성하지 않아도 될 수 있을 정도로 에이전트가 동작할 수 있는 환경을 만들어야 하는구나 …유레카
강력한 하네스를 혼자서 구축하는건 사실상 실패했다. 그렇다면 잘 만들어진 사례부터 찾아보자.
일단 하네스 구축을 잘해놓은 사례를 찾고 싶어서 무작정 GitHub 트렌드를 뒤져봤다. 거기서 유독 눈에 띄는 레포를 발견했다. Oh-My-ClaudeCode(OMC), 개발팀이 그렇게 크지도 않은 것 같고 생성된지 얼마 안된 레포인데 굉장히 빠르게 업데이트가 되고 있었다.
옳거니, 포크 떠서 바로 해체쇼에 들어갔다.
분석 결과, OMC 에서 적용된 하네스는 "지식의 자동 추출과 재사용"가 핵심이였다. 에이전트가 복잡한 작업을 해결하거나 실수를 수정했을 때 그 과정을 SKILL로 박제하고, 다음번 유사한 상황에서 병목 없이 꺼내 쓸 수 있도록 시스템을 만드는 것이었다.
OMC 의 하네스 핵심 개념들을 그대로 문서화해서 그대로 내 레포에 이식했다.
1. skills/ (Domain-Driven Knowledge): 지식을 원자적(Atomic)으로 파편화하여 관리하라.
2. hooks/ (Action-Centric Scripts): AI 생명주기에 반응하는 모듈형 스크립트.
3. memory/ (Persistence Layer): 에이전트의 기억 장치.
4. agents/ (Persona Definitions): 특정 역할에 최적화된 프롬프트 지침서.
5. AGENTS.md (Master Map): 하네스 전체의 작동 원리를 정의한 중앙 관제 문서.
이식 작업을 마치고 검증에 들어갔다.
실험
하네스가 잘 적용되었는지 확인하려면, 하네스가 적용된 레포 vs 하네스가 없는 레포 각각 같은 프롬프트를 입력해서 코드베이스의 컨벤션 ( 내 의도대로 작업하는지 ) 위반 사항을 비교하는 것이다.
실험 후 검증용 md 파일을 레포에 추가하고 작업 결과를 검증하라고 시켰다.
| 항목 | 하네스 브랜치 | 하네스 없는 브랜치 |
|---|---|---|
| 최종 판정 | CONDITIONAL PASS | FAIL |
| L3 위반 | 0건 | 1건 (RHF+Zod) |
| L2 위반 | 2건 | — |
| 아키텍처 경고 | 0건 | 3건 (섹션분리·훅분리·단일책임) |
| 에러 핸들링 | 문제없음 | ErrorBoundary 누락 |
| Memory 업데이트 | ✅ | ❌ |
| 컴포넌트 구조 | 227줄 + sections/ 분리 | 308줄 단일 파일에 혼재 |
첫 실험 결과는 예상대로 나온 것 같다. 현재 하네스가 있으면 의미있는 결과는 나오는 것 같다.
그 후 남은 위반사항을 교정하고 다시 같은 프롬프트로 작업을 시켰는데 이상하게 하나씩 틀리는 기분이였다.
교정 후 첫 번째 실험
1. 최종 판정: ❌ FAIL
| 위반 등급 | 항목 | 상태 |
|---|---|---|
| L3 Hard-Rule | rhf-zod — RHF + Zod 미사용 | ❌ FAIL |
| L2 Pattern | custom-hook-extraction — 비즈니스 로직 인라인 | ⚠️ WARN |
| Meta | ARCH-TRIGGER 프로토콜 미준수 | ❌ FAIL |
| Meta | LOG-BEFORE-ACT 미준수 | ⚠️ WARN |
L3 에 위반사항이 생겼다. 이 규칙은 SKILL.md에 적혀 있었는데 에이전트가 따르지 않았다. 이건 규칙이 없어서가 아니라, 규칙이 있어도 에이전트가 컨텍스트 과부하된 상황에서 무시할 수 있는 것 같다.
교정 후 두 번째 실험
1. 최종 판정: ❌ FAIL
| 위반 등급 | 항목 | 상태 |
|---|---|---|
| L3 Hard-Rule | standard-validation — RHF + Zod 미사용 (isDisabled 인라인 로직) | ❌ FAIL |
| L2 Pattern | custom-hook-extraction — state + mutation + 핸들러 10 LOC 이상 인라인 | ⚠️ WARN |
| Meta | ARCH-TRIGGER — 신규 파일 생성 시 Deliberation 기록 누락 | ❌ FAIL |
| L1 UI | mui-tailwind-mix — twMerge 미사용 및 템플릿 리터럴 조건부 클래스 조합 | ⚠️ WARN |
이번엔 패턴이 달랐다. isDisabled라는 커스텀 변수로 검증 로직을 대체하는 방식이었는데, SKILL.md에는 useForm을 쓰라고만 되어 있었지 이런 우회 패턴을 명시적으로 금지하지 않았다.
규칙이 구체적이지 않아서 교묘하게 틀어서 작업한 것 같다.
useForm 기반 검증으로 교체했다.
교정 후 세 번째 실험
1. 최종 판정: ❌ FAIL
| 위반 등급 | 항목 | 상태 |
|---|---|---|
| L3 Hard-Rule | api-error-handling — 에러 발생 시 console.error만 사용 (사용자 알림 부재) | ❌ FAIL |
| Meta | memory-update — rounds.json 내 ARCH-TRIGGER 합의 기록 누락 | ❌ FAIL |
| Meta | post-task-readiness — SLL 제안([SLL-PROPOSE]) 미발행 | ⚠️ WARN |
| L1 UI | mui-tailwind-mix — 공용 Input 대신 native 사용 | ⚠️ WARN |
코드 품질은 개선됐지만 새로운 위반이 등장했다.
API 실패 시 console.error만 호출하고 사용자에게 아무 알림도 주지 않는 패턴이었다.
이 규칙은 SKILL.md에 있었다. 그런데 에이전트가 따르지 않았다.
교정 후 네 번째 실험
1. 최종 판정: ❌ FAIL
| 위반 등급 | 항목 | 상태 |
|---|---|---|
| L3 Hard-Rule | standard-validation — RHF + Zod 미적용 및 인라인 validation | ❌ FAIL |
| L3 Hard-Rule | api-error-handling — onError 내 console.error 방치 | ❌ FAIL |
| L1 UI | mui-tailwind-mix — native , 직접 사용 | ⚠️ WARN |
| Architecture | single-responsibility — 단일 컴포넌트에 과도한 책임 집중 | ⚠️ WARN |
이전 교정 사항이 다시 무너졌다. 뭔가 이상했다. 이젠 SKILL 을 제대로 안읽는 것 같다고 느꼈다.
이러면 안된다. 더 강력한 하네스가 필요하다. 이번엔 hooks 차원에서 검증하고, L3 위반 시 파일 쓰기 자체를 deny 되게 처리했다.
교정 후 다섯 번째 실험
1. 최종 판정: ⚠️ CONDITIONAL PASS
| 위반 등급 | 항목 | 상태 |
|---|---|---|
| L3 Hard-Rule | 전 항목 규격 준수 확인 | ✅ PASS |
| Architecture | section-decomposition — Wizard 전용 Props 의존성 존재 | ⚠️ DEBT |
| Architecture | technical-debt — 향후 마이그레이션 태스크 등록 조건부 승인 | ⚠️ DEBT |
| Meta | harness-integrity — Hook 시스템 및 JSON 규약 준수 | ✅ PASS |
경고는 있었지만, L3 위반이 처음으로 0건이 됐다. 경고는 향후 개선 과제로 미뤘다.
교정 후 여섯 번째 실험
최종 판정: ✅ PASS
| 위반 등급 | 항목 | 상태 |
|---|---|---|
| L3 Hard-Rule | 전 항목(No-Any, API Isolation, Validation) 준수 확인 | ✅ PASS |
| L3 Hard-Rule | onError-Console — 전역 에러 핸들러 및 피드백 로직 적용 | ✅ PASS |
| Meta | ARCH-TRIGGER — rounds.json 내 합의 레코드 및 절차 준수 | ✅ PASS |
| Architecture | section-decomposition — 준수 확인 | ✅ PASS |
단순 교정만 하면 끝나겠거니 했는데, 그게 아니였다.
4번째 교정후 실험을 할 때까지만 해도 ‘위반사항에 대한 하네스 교정’ 만 수행하다가
현재 적용된 하네스가 ‘단순 권고 시스템’에 가깝다는걸 알았다. SKILL.md는 가르치는 도구고, hook은 강제하는 도구다. 나는 가르치는 도구만 쓰고 있었다 그러니 SKILL 을 확인하고도 컨텍스트가 너무 많을 경우 가끔 위반하는 경우가 생긴다.
강력하게 deny 처리를 추가했더니 5,6 실험에서 경고하고 넘어가는 사항은 생겨도 위반사항은 나오지 않았다.
성공인가?
성공적이지만, 완벽하지는 않다. 현재 실험을 위해 수동 검증을 하고 있는데 작업 완료 시점에 자동 검증을 추가하고 경고 사항도 추가 교정이 필요하다.
그럼에도 사이클은 구축됐다. SKILL.md가 가르치고, hook이 강제하고, memory가 기억하고, post-task가 학습한다. 이 루프가 돌아가고 있다.
하네스가 ‘완벽’하게 될지는 솔직히 잘 모르겠다. 하지만 하네스로 강력한 운영은 분명 가능하고 지속적으로 관리가 된다면 완벽에 수렴하지 않을까
"분명해진 것은, 소프트웨어를 구축하는 데는 여전히 규율이 필요하지만, 그 규율은 코드보다 스캐폴딩에서 더 많이 드러난다는 점입니다. 코드베이스의 일관성을 유지하는 툴링, 추상화, 피드백 루프는 점점 더 중요해지고 있습니다."
— OpenAI, Harness engineering: leveraging Codex in an agent-first world
이제 걸음마를 떼었다. 다음은 더 대규모 코드베이스에서 적용해보면 어떨까.