Claude × Codex 하네스 구축기

들어가며

최근 작업하면서 가장 크게 느낀 문제는 “AI를 쓰고 있는데도 작업 흐름이 오히려 더 산만해질 수 있다”는 점이었다.

단순히 AI가 코드를 잘 짜느냐의 문제가 아니었다. 실제로는 아래 같은 불편이 더 컸다.

  • 지금 무슨 작업을 해야 하는지 매번 다시 설명해야 한다
  • 계획과 구현, 리뷰와 정리가 한 흐름으로 이어지지 않는다
  • 도중에 상태가 꼬이면 사람이 직접 복구해야 한다
  • 작은 작업도 문맥을 많이 먹고 불필요한 질문이 반복된다
  • “자동화된 것 같지만” 실제로는 사람이 계속 붙들고 있어야 한다

나는 결국 “AI를 더 똑똑하게 쓰는 것”보다 작업 흐름 자체를 정리하는 것이 먼저라고 판단했다. 그래서 Claude와 Codex를 같이 쓰되 사람의 부담을 줄이는 방향으로 하네스를 하나 만들기 시작했다.

이 글은 그 하네스를 v0로 구축하면서 어떤 pain point가 있었고, 어떤 방향을 선택했고, 어떻게 구현했고, 무엇이 남았는지를 정리한 기록이다.

---

시작하게 된 Pain Point

1. AI를 써도 작업은 여전히 파편적이었다

처음에는 단순히 “Claude에게 계획을 세우고 Codex로 구현하면 되지 않을까?”라고 생각했다. 그런데 실제로 해보면 작업이 자연스럽게 이어지지 않았다.

예를 들면 이런 식이다.

  • Claude에게 작업 맥락을 설명한다
  • Codex에게 다시 같은 내용을 설명한다
  • 구현 후 리뷰를 받는다
  • 커밋, PR, 정리 단계는 또 사람이 직접 이어 붙인다

즉, 도구는 여러 개인데 상태를 이어주는 레이어가 없었다.

2. 계획과 구현이 쉽게 어긋났다

AI에게 계획을 맡기고 구현을 맡기면 그럴듯해 보이지만 실제로는 아래 문제가 자주 생긴다.

  • 계획서에는 있는데 구현에는 빠진 항목
  • 구현은 했지만 검증 조건이 약한 경우
  • 리뷰는 받았지만 상태가 문서에 남지 않는 경우
  • 커밋/PR 단계에서 작업 범위가 흐려지는 경우

이런 문제는 “모델 성능”보다는 프로세스와 상태 관리 부재에 더 가까웠다.

3. 사람의 피로가 생각보다 컸다

특히 내가 크게 느낀 건 이 부분이었다.

  • 질문이 너무 많아도 피곤하다
  • 반대로 너무 자동화되면 통제감을 잃는다
  • 어떤 시점에 사람이 결정해야 하는지가 불명확하면 더 피곤하다

즉, 좋은 하네스는 “자동화”만 잘하면 되는 게 아니라, 사람이 어디서 개입하고 어디서 안 해도 되는지 분명해야 한다고 느꼈다.

---

방향 결정

이 문제를 풀기 위해 몇 가지 원칙을 먼저 정했다.

1. 도구보다 흐름을 먼저 만든다

처음부터 “어떤 프롬프트가 좋은가”보다는 “작업이 어떤 단계로 흘러야 하는가”를 먼저 정의했다.

결국 하네스 흐름은 3단계로 정리됐다.

  • /plan: 계획 수립과 리뷰
  • /work: 구현과 diff 리뷰
  • /ship: 커밋, 푸시, PR 생성, 마무리

즉, 작업을 계획 → 구현 → 출하의 명확한 상태 전이로 다루기로 했다.

2. 문서와 상태를 남긴다

AI 작업에서 자주 생기는 문제 중 하나는 “지금 어디까지 됐는지”가 세션이 지나면 흐려진다는 점이다.

그래서 각 task마다 상태 파일을 두고 아래 정보를 남기도록 했다.

  • 현재 stage
  • session id
  • review runs
  • 마지막 diff 경로
  • commit plan
  • created commits
  • push / PR 상태

이걸 기반으로 재진입과 복구가 가능하도록 설계했다.

3. 설계 먼저, 구현은 그 뒤

작업을 하면서 설계를 바꾸기 시작하면 결국 흐름이 깨진다. 그래서 문서 원칙도 같이 정리했다.

  • 설계 설명은 한 문서에만 둔다
  • 실행 상태는 한 문서에만 둔다
  • 세션 메모는 짧게 유지한다
  • 설계 미결정이 있으면 구현보다 설계 갱신이 먼저다

이 원칙은 실제로 작업을 진행하면서 꽤 중요했다.

---

구현 과정에서 했던 고민

1. /sync를 독립 명령으로 둘 것인가

처음에는 /sync, /next, /done 같은 보조 명령도 별도로 두려고 했다. 그런데 실제 검증 과정에서 nested slash 구조가 깔끔하게 맞지 않았고, 오히려 명령 수가 늘면서 흐름이 복잡해질 수 있었다.

그래서 방향을 바꿨다.

  • /sync는 독립 명령으로 밀지 않는다
  • 대신 공용 로직으로 흡수한다
  • /plan, /work, /ship 내부에서 필요한 문맥 수집만 수행한다

결과적으로 사용자 입장에서는 명령 수가 줄었고 구조도 더 단순해졌다.

2. 얼마나 상태를 엄격하게 관리할 것인가

상태를 느슨하게 잡으면 구현은 편하다. 하지만 실제 작업에서 가장 위험한 건 “state와 실제 git 상태가 어긋나는 것”이었다.

실제로 smoke 검증 중에 이런 문제가 발생했다.

  • work.done 상태는 남아 있는데
  • 실제 변경은 이미 커밋되어 git history에 흡수된 상태
  • /ship --execute를 돌리면 Step 4에서 nothing to commit

이 문제를 겪고 나서 /ship에는 stale state guard를 추가했다.

  • drift detector
  • GS-0
  • Step 4 fail-fast
  • archive 처리 규칙

이건 v0에서 가장 중요한 안정성 개선 중 하나였다.

3. 얼마나 많이 AI에게 보여줄 것인가

초기에는 sync처럼 원문을 많이 덤프했다. 그런데 실제로는 문맥이 많다고 항상 좋은 게 아니었다.

  • TASKS.md
  • ADR 인덱스 전체
  • 긴 git log
  • 큰 diff 원문

이런 건 토큰만 많이 먹고 꼭 추론 품질을 높이지는 않았다.

그래서 나중에는 이렇게 바꿨다.

  • sync/context는 구조화 요약
  • /plan 전에 계획서 lint
  • /work diff는 메타데이터 요약 추가

중요한 건 “정보를 줄인다”가 아니라 의미를 잃지 않고 정리해서 준다는 방향이었다.

---

구현 내용

1. 문서 구조 정리

문서가 가장 먼저 정리 대상이었다. 초기에는 상태 설명, 단계 요약, handoff가 서로 겹치고 있었다.

그래서 최종적으로 구조를 아래처럼 단순화했다.

활성 문서

  • README.md
  • TASKS.md
  • SESSION-HANDOFF.md
  • V1-ROADMAP.md

아카이브

  • archive/v0/
    • 설계 원문
    • phase0 검증
    • baseline
    • 보조 스크립트
    • v0 handoff / task 기록

즉, 루트에는 현재 작업에 필요한 문서만 두고, 과거 문서는 전부 archive/v0/로 내렸다.

2. 핵심 명령 흐름

하네스의 기본 흐름은 아래와 같다.

/plan <task-id>

  • 계획서 점검
  • 형식 lint
  • Codex 리뷰
  • 설계/검증 누락 확인
  • plan.done 상태 기록

/work <task-id>

  • 구현
  • diff 캡처
  • 필요 시 split review
  • Codex diff 리뷰
  • work.done 상태 기록

/ship <task-id> --execute

  • stale state 검사
  • commit partition 생성
  • 파일 단위 커밋
  • push
  • PR 생성
  • archive 이동
  • 필요 시 /done 반영

3. 상태 파일과 재진입 모델

각 task는 docs/plans/<task>.state.json을 가진다. 여기에 stage와 review 이력, commit plan, PR 상태 등이 남는다.

덕분에 아래가 가능해졌다.

  • interrupted run finalize
  • 재호출 시 재진입
  • PR 실패 후 재시도
  • ship/archive 상태 추적

4. Phase 4a smoke 검증

v0가 단순 설계가 아니라 실제로 돌아가는지 보기 위해, fresh smoke task를 따로 만들어 /plan → /work → /ship --execute 전체를 검증했다.

결과:

  • commit partition 생성 성공
  • PR 생성 성공
  • archive 이동 성공
  • PR close → revert → archive 보존까지 완료

즉, 최소한의 end-to-end mechanics는 실제로 검증됐다.

---

결과

1. v0는 “구축 완료” 상태까지 왔다

현재 기준으로 보면 v0에서는 아래가 끝났다.

  • 설계 정리
  • 문서 구조 정리
  • /plan, /work, /ship 구현
  • stale state 대응
  • smoke end-to-end 검증
  • v0 문서 아카이빙
  • v1 활성 문서 분리

즉, 이제는 “하네스가 있긴 한데 아직 구조만 있다” 수준은 아니다. 실제로 다음 실 task에 적용할 수 있는 상태다.

2. 가장 큰 성과는 “흐름이 생겼다”는 점이다

개인적으로 v0의 핵심 성과는 모델 품질보다 이쪽이라고 본다.

  • 지금 어디까지 왔는지 안다
  • 다음에 뭘 해야 하는지 안다
  • 작업이 끊겨도 다시 들어갈 수 있다
  • plan / work / ship의 책임이 명확하다

즉, AI를 “그때그때 쓰는 도구”에서 한 흐름 안에서 쓰는 작업 시스템으로 바꾸기 시작한 것이다.

3. 하지만 아직 완성은 아니다

v0를 하면서 명확해진 것도 있다.

  • 긴 문맥 dump는 줄여야 한다
  • 형식 검사는 AI가 아니라 로직으로 처리하는 게 낫다
  • PR 본문 같은 정형 정보는 더 자동화할 수 있다
  • 실제 실 task에서 써봐야 정말 편한지 알 수 있다

그래서 이 하네스는 지금부터가 더 중요하다.

---

앞으로의 계획

1. v1: 실사용 개선

지금부터는 v1로 넘어간다. v1의 초점은 새 기능을 많이 붙이는 게 아니라 실제로 써서 불편한 점을 줄이는 것이다.

현재 정리된 v1 우선순위는 대략 이렇다.

  • task-hpa-manifest 실사용 적용
  • sync/context 출력 더 정리
  • /plan lint 강화
  • /work diff 메타데이터 개선
  • PR 본문 정형 부분 자동화
  • state 요약 출력 추가

2. 정량 측정은 선택으로 내렸다

처음에는 baseline과 KPI 측정을 꽤 강하게 가져가려 했다. 그런데 작업을 하면서 스스로 느낀 건, 이 하네스의 1차 성공 기준은 “정말 편한가”이지 “숫자가 얼마나 예쁜가”가 아니라는 점이었다.

그래서 현재는 정량 측정을 필수에서 선택으로 내렸다.

즉,

  • 쓰면서 편한지
  • 질문이 과하지 않은지
  • 다시 쓰고 싶은지

이런 체감이 우선이다.

3. prestage 브랜치에서 먼저 쓴다

아직은 테스트 단계라서 바로 main에 넣고 싶지 않았다. 그래서 하네스는 prestage/harness-v0 브랜치로 먼저 통합했다.

즉 앞으로는

  • main 직행이 아니라
  • prestage에서 실사용 검증
  • 충분히 안정되면 나중에 main으로 승격

이 흐름으로 가져갈 생각이다.

---

마무리

이 작업을 하면서 가장 크게 느낀 건, AI 활용의 핵심은 “모델 하나를 잘 쓰는 법”보다 작업 흐름을 어떻게 설계하느냐에 훨씬 더 가깝다는 점이었다.

Claude와 Codex를 각각 잘 쓰는 것만으로는 부족했다. 상태, 문서, 재진입, 정리, 사람의 판단 지점을 함께 묶는 구조가 필요했다.

v0는 그 구조를 만드는 단계였다. 아직 거칠고, 앞으로 손봐야 할 부분도 많다. 하지만 적어도 이제는 “왜 불편한지 모르겠는 상태”는 아니다.

무엇을 줄여야 하는지, 어디를 자동화해야 하는지, 어디는 사람이 직접 봐야 하는지

그 윤곽은 꽤 분명해졌다.

이제 남은 건 하나다. 실제로 써보면서 정말 편해지는 방향으로 계속 다듬는 것.