본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 05. 23:46

Harness Debt (하네스 부채)

요약

AI 에이전트용 지침 문서(Harness)에서 발생하는 '하네스 부채(Harness Debt)'의 개념과 유형을 설명합니다. 규칙 간의 모순, 고아 참조, 동기 없는 규칙 등이 어떻게 비용을 발생시키고 에이전트의 성능을 저해하는지 다룹니다.

핵심 포인트

  • 하네스 부채는 문서 성장 속도가 유지 관리 속도를 앞지를 때 발생함
  • 모순, 고아 규칙, 동기 없는 규칙, 시대착오적 규칙이 주요 형태임
  • 부채는 토큰 비용과 리뷰 비용을 발생시키며 에이전트의 오류를 유발함
  • 지표나 테스트가 없어 부채가 눈에 보이지 않는 것이 가장 큰 문제임

Harness Debt

지난달에 지난 3개월 만에 처음으로 우리의 CLAUDE.md 파일을 처음부터 끝까지 정독하기 위해 자리에 앉았습니다. 그 과정에서 두 개의 규칙이 서로 충돌하고 있다는 것을 발견했습니다. 하나는 4월에 추가되었고, 다른 하나는 1월에 추가되었습니다. 당시에는 두 리뷰어 모두 옳았습니다. 하지만 아무도 충돌을 알아채지 못했는데, 규칙을 추가할 때 파일 전체를 읽는 사람은 아무도 없기 때문입니다. 사람들은 규칙이 속한 섹션을 읽고, 적절한 위치를 찾아 작성할 뿐입니다.

에이전트 (Agent)는 파일에서 먼저 나타나는 규칙을 묵묵히 따르고 있었습니다. 다른 규칙은 사실상 죽은 상태였습니다. 팀은 두 규칙을 모두 작성하는 리뷰 비용을 지불했고, 두 규칙을 모두 유지하는 토큰 비용을 지불했지만, 결과적으로는 하나의 규칙에 해당하는 동작만을 얻었습니다.

이것이 바로 하네스 부채 (Harness Debt)입니다. 비대함 (Bloat)도 아니고, 노후화 (Staleness)도 아니며, 심지어 잘못된 규칙도 아닙니다. 문서를 유지 관리하는 규율보다 문서가 더 빠르게 성장하면서 누적된 비용입니다.

부채가 나타나는 형태

가장 명백한 형태는 모순 (Contradiction)입니다. 몇 달 간격으로 작성되었고, 원래의 맥락에서는 둘 다 중요한 역할을 하지만, 서로를 인지하지 못하는 채 정반대 방향을 가리키는 두 규칙입니다. 에이전트는 그중 하나를 선택하고, 팀은 다른 규칙이 작동하고 있다고 생각합니다.

두 번째 형태는 고아 (Orphans)입니다. 규칙이 더 이상 존재하지 않는 파일 경로, 이름이 변경된 함수, 제거된 훅 (Hook), 또는 팀이 더 이상 사용하지 않는 도구를 참조하는 경우입니다. 규칙은 여전히 조언처럼 읽히지만, 그 조언은 이제 일관성이 없습니다. 에이전트는 이를 해석하기 위해 최선을 다하지만, 그 결과는 에이전트가 망가진 지도 위에서 즉흥적으로 행동할 때 나타나는 결과물일 뿐입니다.

세 번째 형태는 동기가 없는 규칙 (Unmotivated rules)입니다. 모든 규칙 뒤에는 특정 사건 (Incident)이 있었습니다. 하지만 그 사건들은 파일에 기록되어 있지 않습니다. 6개월이 지난 후, 왜 "여기서는 항상 구조화된 로거 (Structured logger)를 사용하라"는 규칙이 하네스에 있는지 기억하는 사람은 아무도 없습니다. 단지 그 규칙이 항상 거기에 있었을 뿐이며, 그것을 제거하는 것이 누구도 설명할 수 없는 방식으로 위험하게 느껴질 뿐입니다. 규칙은 관성으로 살아남습니다. 절반의 경우 그 규칙은 여전히 옳습니다. 하지만 나머지 절반의 경우, 원래의 제약 조건은 사라졌고 규칙은 아무런 이득 없이 세금(비용)만 치르고 있는 상태입니다.

네 번째 형태는 한때는 옳았으나 지금은 틀린 규칙입니다. 코드베이스는 이동했지만, 규칙은 이동하지 않았습니다. 에이전트(Agent)는 규칙을 읽고 적용하며, 현재의 아키텍처(Architecture)와 충돌하는 디프(diff)를 생성합니다. 리뷰어(Reviewer)는 반대하고, 에이전트는 하네스(Harness)가 이렇게 하라고 되어 있다고 주장하며, 이제는 한 릴리스 전에 삭제되었어야 할 규칙을 두고 작은 싸움이 벌어집니다.

부채(Debt)는 이러한 것들의 합입니다. 이는 복리로 쌓입니다. 각각의 모순, 각각의 고아(Orphan) 규칙, 각각의 동기 없는 규칙은 다음에 규칙을 추가하는 사람이 자신이 충돌하고 있는 규칙을 알아차리지 못할 확률을 높입니다.

부채가 보이지 않는 이유

하네스에는 실패하는 테스트가 없습니다. 고아 참조(Orphan reference)를 표시하는 CI 작업도 없습니다. "이 규칙은 6개월 동안 실행되지 않았습니다"라고 말해주는 지표(Metric)도 없습니다. 부채는 아무런 신호 없이, 팀이 신뢰하는 문서 안에서 축적되며, 그 신뢰가 바로 부채를 비싸게 만드는 원인입니다.

부채가 계속 보이지 않는 또 다른 이유는 다음과 같습니다. 각 규칙은 개별적인 가치에 따라 승인되었습니다. 규칙을 승인한 팀에게는 "이것이 파일 내의 다른 것과 충돌합니까?"라고 묻지 않았습니다. 그들에게는 "이 규칙이 좋은가요?"라고 물었습니다. 규칙에 대한 리뷰 프로세스는 로컬(Local)이지만, 규칙의 비용은 글로벌(Global)합니다. 이 불일치가 부채를 생성하는 메커니즘입니다.

세 번째 이유는 순환(Rotation)입니다. 초기 규칙을 추가했던 사람들은 팀을 떠났습니다. 사건들에 대한 조직적 기억(Institutional memory)은 사라졌습니다. 새로운 유지보수자(Maintainer)들은 하네스를 결정의 기록이 아닌 완성된 결과물(Artifact)로 읽으며, 완성된 결과물은 질문을 유도하지 않습니다.

감사 (The audit)

분기에 한 번, 나는 하네스를 열어두고 체크리스트를 든 채 앉아 있습니다. 체크리스트는 짧으며 감사는 약 2시간 정도 소요됩니다.

위에서 아래로 읽으십시오. 훑어보는 것이 아니라 읽는 것입니다. 모순은 두 번째 읽을 때 드러납니다. 첫 번째 읽기는 전체 내용을 머릿속에 담는 과정일 뿐입니다. 대부분의 분기에 나는 한두 개의 실제 충돌과 세네 개의 준충돌(Near-conflicts)을 발견합니다. 준충돌이란 두 규칙이 엄격하게 모순되지는 않지만, 에이전트가 하나를 선택해야 할 정도로 서로 반대되는 방향으로 끌어당기는 경우를 말합니다.

모든 파일 경로, 함수 이름, 그리고 도구 참조(tool reference)를 확인하십시오. 코드베이스에 대한 grep을 수행합니다. 고아(orphans)들이 즉시 드러날 것입니다. 그중 일부는 수정하기 쉽습니다. 규칙은 여전히 유효하지만 이름만 바뀐 경우입니다. 일부는 해당 규칙이 참조하던 대상이 더 이상 존재하지 않기 때문에 규칙 자체가 쓸모없어졌음을 나타내는 신호입니다.

각 규칙에 대해, 마지막으로 언제 실행(fired)되었는지 물으십시오. 팀 리뷰 노트, 사후 분석(post-mortems), 누군가 해당 규칙을 인용한 PR 코멘트, 에이전트의 중단 메시지 등을 확인하십시오. 만약 규칙이 6개월 동안 이 중 어디에도 나타나지 않았다면, 삭제 후보가 됩니다. 확정된 삭제가 아니라, 후보가 되는 것입니다. 어떤 규칙들은 에이전트가 이제 그 규칙을 준수하기 때문에 조용한 것이며, 이를 제거하면 실패 모드(failure mode)가 다시 유입될 수 있습니다. 다른 규칙들은 다른 이유로 인해 실패 모드가 사라졌기 때문에 조용한 것입니다.

각 규칙에 대해, 그 규칙이 만들어진 발생 사건(origin incident)이 무엇이었는지 물으십시오. 팀원 중 누구도 답할 수 없다면, 그 규칙은 수습 기간(probation)에 들어갑니다. 누군가 그 논리적 근거를 재구성할 수 있다면, 다음 유지보수자를 위해 규칙에 한 줄의 주석(annotation)을 추가합니다. 만약 아무도 재구성할 수 없다면, 다음 감사(audit) 시 삭제를 고려해야 합니다.

감사를 통해 삭제, 통합, 범위 조정, 주석 추가와 같은 소규모 변경 사항 세트가 도출됩니다. 패치(patches)는 같은 주에 적용됩니다.

주석 규칙 (The annotation rule)

가장 지속적인 배당금을 지급하는 변화는 가장 비용이 적게 드는 변화입니다. 즉, 모든 규칙이 추가될 때 어떤 사건이나 실수 유형을 방지하는지를 명시하는 한 줄의 주석을 갖도록 하는 것입니다.

세 단락의 논리적 근거가 아닙니다. PR로 연결되는 링크도 아닙니다 (링크는 깨지기 마련입니다). 단 한 줄이면 충분합니다. "두 번 실행된 마이그레이션 이후 추가됨." "분석 모듈의 임포트 경로(import path) 실수 이후 추가됨." 정도면 충분합니다. 다음 유지보수자가 "그 사건이 여전히 발생할 가능성이 있는가?"라고 물었을 때 답을 얻을 수 있을 정도면 됩니다.

비용은 규칙당 한 줄입니다. 이점은 다음 감사(audit) 시 규칙의 절반을 추측하는 대신, 모든 규칙에 대해 기원(origin) 질문에 실제로 답할 수 있다는 것입니다. 주석(annotation)은 하네스(harness) 내에서 가장 저렴한 부채 방지 조치입니다. 이 비용은 규칙에서 추론(reasoning) 과정을 분리하여 필요할 때만 로드되는 참조(reference)로 처리함으로써 완화할 수 있습니다. 이것이 Keystone이 최소한의 비용을 지불하면서 이러한 이점을 얻는 방식입니다.

우리는 이를 규칙에 관한 규칙(rule about rules)으로 추가했습니다. 이는 우리의 CLAUDE.md에 있는 유일한 메타 규칙(meta-rule)이며, 이미 그 가치를 수없이 증명해 왔습니다.

정원 (The garden)

내가 계속해서 되돌아오게 되는 비유는 엔지니어링(engineering)이 아니라 정원 가꾸기(gardening)입니다. 하네스는 한 번 설계하고 그대로 유지하는 시스템이 아닙니다. 그것은 작고 살아있는 규칙들의 집합이며, 각 규칙은 시들 수도 있고, 서로를 압도할 수도 있으며, 때때로 가지치기(pruning)가 필요합니다.

가꾸지 않는 정원은 덤불(thicket)이 됩니다. 엄밀히 말하면 덤불 안에도 식물은 있습니다. 하지만 그 식물들은 생산적이지 않습니다.

분기별 관리가 이루어지지 않는 하네스는 덤불이 됩니다. 엄밀히 말하면 그 안에 규칙들이 있습니다. 하지만 모순, 고아(orphans) 규칙, 동기 없는 규칙들이 신호(signal)를 가로막기 때문에, 규칙들은 예전과 같은 동작을 수행하지 못합니다.

규율이란 정원을 가꾸는 것입니다. 재설계하는 것이 아닙니다. 마이그레이션(migrate)하는 것도 아닙니다. 그저 줄 사이를 걸으며, 그곳에 있어서는 안 될 것들을 뽑아내고, 있어야 할 것들에게 영양을 공급하는 것입니다.

가장 어려운 삭제 (The hardest deletion)

내가 삭제하기 가장 힘들어하는 규칙은, 어떤 사건을 겪은 후 내가 직접 추가한 규칙입니다. 그 규칙을 삭제하는 것은 마치 교훈을 지워버리는 것처럼 느껴집니다.

나에게 도움이 되는 사고방식은 다음과 같습니다. 규칙을 삭제한다고 해서 교훈이 사라지는 것은 아닙니다. 교훈은 코드베이스(codebase)에, 테스트 스위트(test suite)에, 그리고 팀의 관행(practice) 속에 남아 있습니다. 규칙은 교훈을 가르쳐준 비계(scaffolding)였을 뿐이며, 이제 교훈은 그 자체로 하중을 견딜 수 있게 되었습니다. 그러니 비계는 철거해도 됩니다.

제가 실행하는 점검 방식은 다음과 같습니다: 만약 오늘 이 규칙을 삭제한다면, 다음 풀 리퀘스트 (Pull Request)에서 해당 실패 모드 (failure mode)가 다시 발생할 것인가? 만약 대답이 "아니요, 테스트가 이를 커버하니까요" 또는 "아니요, 린트 (lint) 규칙이 잡아낼 테니까요" 또는 "아니요, 팀원들이 리뷰 과정에서 잡아낼 테니까요"라면, 그 규칙은 비계 (scaffolding)이며 제거해도 됩니다. 만약 대답이 "예, 실패가 다시 발생할 것입니다"라면, 그 규칙은 하중을 견디는 (load-bearing) 규칙이며 유지되어야 합니다.

제가 집착하는 대부분의 규칙은 이 테스트를 통과하지 못합니다. 교훈은 남았지만, 규칙은 필요하지 않았던 것입니다.

Keystone에는 감사 휠 (audit wheel)이 있습니다

제가 설명한 감사는 수동적입니다. 분기당 2시간, 체크리스트, 그리고 파일을 처음부터 끝까지 읽는 사람 한 명. 이 규율은 실재하지만 취약합니다. 제가 한 분기를 건너뛰는 순간, 모순들이 발생합니다.

Keystone은 하네스 (harness)에 감사 휠 (audit wheel)을 제공함으로써 이 문제를 해결합니다. 가지치기 단계 (pruning pass)는 제 기억력이 아니라 일정한 주기 (cadence)에 따라 실행됩니다. 더 이상 적용되지 않는 규칙은 아카이브 (archive)됩니다. 각 규칙 뒤에 숨겨진 논리가 규칙 바로 옆에 살아있기 때문에, 감사는 추측 없이도 기원 (origin)에 대한 질문에 답할 수 있습니다.

이 메커니즘은 '망각'을 일급 시민 연산 (first-class operation)으로 취급합니다. 에이전트 (agent)는 단순히 가이드를 축적하기만 하는 것이 아니라, 그것들을 버릴 수도 있습니다. 오래된 가이드는 아카이브로 이동하며, 그 아카이브 사유가 기록됩니다. 모순되는 쌍이 발견되면 패스 (pass) 과정 중에 드러나며, 그중 하나는 생존자를 가리키는 메모와 함께 은퇴합니다.

에이전트는 정원사가 가지치기를 하는 방식으로 망각합니다. 즉, 의도적으로, 이유를 가지고, 그리고 나중에 질문이 다시 돌아올 경우를 대비해 잘라낸 부분을 어딘가에 보관하면서 말입니다.

이것은 제가 수동으로 해오던 작업이었습니다. Keystone은 여기에 형태와 주기를 부여합니다. 하네스가 작게 유지되는 이유는 휠이 돌아가기 때문이며, 휠이 돌아가는 이유는 그것이 제 의지력이 아니라 도구 안에 살아있기 때문입니다.

긴 CLAUDE.md를 마주한 사람에게 해주고 싶은 말

파일을 여세요. 편집하지 말고 처음부터 끝까지 한 번 읽으세요. 무엇이 당신을 놀라게 하는지 주목하세요. 그 놀라움들이 바로 부채 (debt)입니다.

모순되는 점들, 고아 (orphans) 코드, 기원을 재구성할 수 없는 규칙들, 그리고 에이전트 (agent)가 생성하지 않는 패턴에 반응하는 규칙들의 목록을 만드세요. 이 목록은 단 하나의 변경 사항도 작성하기 전, 당신의 감사 (audit) 결과물입니다.

그다음 10개의 규칙을 패치 (patch) 하세요. 전부 다 할 필요는 없습니다. 처음 10개만 하세요. 미미한 토큰 절약 효과가 눈에 띌 것이며, 미미한 일관성 (coherence) 개선 효과는 그보다 더 클 것입니다. 에이전트는 다음 주에 더 나은 방식으로 동작할 것이며, 당신은 그 변화를 특정 삭제 작업 덕분이라고 돌릴 수 있을 것입니다.

파일을 닫기 전에 다음 감사를 달력에 예약하세요. 부채 (debt)는 다시 돌아옵니다. 규율 (discipline)이란 역시 다시 돌아오는 것입니다.

하네스 (harness)는 문서입니다. 문서는 부식됩니다. 하네스를 가꾸는 (gardening) 팀은 시간이 지남에 따라 점점 더 나아지는 에이전트를 갖게 됩니다. 그렇지 않은 팀은 점점 더 나빠지는 에이전트를 갖게 됩니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0