교차 검증 도구의 구현 — 자체 검증에서 실전까지
교차 검증 체계를 프롬프트-only 플러그인으로 구현하고, 자체 검증과 실전 검증을 거친 기록입니다. 도구가 자신의 한계를 보여주고, 실전에서 실제 이슈를 잡았습니다.
TL;DR — 교차 검증 체계를 코드 없는 프롬프트-only 플러그인으로 구현했습니다. 자체 검증에서 “아키텍처 인식 부재”를 발견하고, 48개 파일의 실전 검증에서 타임존 일관성·페이지네이션 비대칭 등 실제 이슈를 잡았습니다.
들어가며
이전 글에서 “왜 교차 검증인가”를 정리했습니다. 이번 글은 그 체계를 도구로 만들고, 도구로 도구 자신을 검증하고, 실제 코드에 적용한 기록입니다.
도구를 만드는 것보다 어려운 것은, 그 도구가 진짜 쓸모 있는지 확인하는 일입니다. 교차 검증 체계를 Claude Code 플러그인으로 구현한 뒤, 두 번의 검증을 거쳤습니다. 하나는 도구 자신에 대한 자체 검증이고, 다른 하나는 실제 피처 브랜치에 대한 실전 검증입니다.
1. 구현: 프롬프트-only 플러그인
왜 코드가 없는가
교차 검증 플러그인에는 실행 가능한 코드가 한 줄도 없습니다. 전체 “구현”이 마크다운으로 작성된 프롬프트입니다.
claude-cross-verify-plugin/
├── agents/
│ └── cross-verifier.md # 에이전트 정의 (70줄)
└── skills/
├── verify/SKILL.md # 4축 검증 지침 (259줄)
└── setup/SKILL.md # 프로젝트 설정 초기화
이 선택에는 트레이드오프가 있습니다.
| 장점 | 단점 |
|---|---|
| 구조가 단순 — 마크다운만 수정하면 동작 변경 | 출력 품질을 프로그래밍적으로 강제할 수 없음 |
| 설치와 배포가 즉시 | 동일 입력에 대한 일관성 보장이 어려움 |
| 플러그인 구조 자체가 설계 문서 역할 | 테스트 자동화가 불가능 |
프롬프트-only 구현은 “도구”라기보다 “구조화된 체크리스트”에 가깝습니다. 이것이 한계인 동시에 교차 검증의 본질과 맞닿아 있습니다. 자동화가 아닌, 개발자가 AI와 소통하며 확인하는 행위이기 때문입니다.
프로젝트 맞춤 설정
.claude/cross-verify.json으로 프로젝트별 컨벤션, 설계문서, 중점 축을 지정합니다.
{
"version": "1.0",
"conventions": "docs/CONVENTIONS.md",
"focusAxes": ["설계", "구현"],
"customChecks": {
"설계": ["UseCase는 WHAT만 표현하는가"],
"구현": ["Repository CUD는 단일 도메인 원칙을 준수하는가"]
}
}
범용 4축 검증도 가능하지만, 설정이 있으면 검증이 프로젝트의 아키텍처를 기준선으로 삼습니다.
2. 자체 검증 — 도구가 자신을 검증하다
도구를 만들었다고 바로 “만들었습니다” 포스팅을 쓸 수는 없습니다. 플러그인 레포 자체에 /verify를 실행했습니다. 도구의 검증 능력을 시험한 것이 아니라, 플러그인의 설계와 문서 품질을 4축으로 점검한 것입니다.
발견한 것
| 축 | 발견 |
|---|---|
| 의사결정 | “왜 4축인가”, “왜 sonnet인가”에 대한 대안 검토 기록이 없음 |
| 설계 | 아키텍처 인식 부재 — 대상 레포의 구조를 파악하는 단계가 없음 |
| 문서 | 구조 명확, CHANGELOG 부재 |
| 구현 | 자기 자신에 cross-verify.json이 없음 (dogfooding 미완) |
가장 큰 발견은 설계 축에서 나왔습니다. 플러그인이 코드를 검증할 때, 그 코드가 시스템 안에서 어디에 위치하는지를 모른 채 검증을 시작한다는 것입니다.
지도 없이 건물을 검사하는 것과 같습니다. 파일 하나를 읽을 수는 있지만, 그 파일이 어떤 모듈에 속하고, 어떤 레이어에 있고, 누가 의존하는지를 모릅니다.
이 시점에서 두 가지가 명확해졌습니다.
- 플러그인에는 문서 철학만 있고 코드 철학이 없다
- 코드 철학을 검증하려면 실제 코드 레포에서 돌려봐야 한다
3. 실전 검증 — 미터링 시스템 피처 브랜치
검증 대상
| 항목 | 값 |
|---|---|
| 브랜치 | 피처 브랜치 (릴리스 브랜치 대비) |
| 규모 | 48개 파일, +1,061/-163줄 |
| 도메인 | 미터링 — 멀티 노드 환경의 일일 집계 |
| 아키텍처 | 헥사고날 (UseCase=WHAT, 인프라=WHO/HOW) |
프로젝트에 .claude/cross-verify.json이 설정되어 있어, 헥사고날 아키텍처의 커스텀 체크가 포함된 상태에서 검증을 실행했습니다.
결과 요약
| 축 | 핵심 발견 |
|---|---|
| 의사결정 | 근거 명시 양호, 대안 기록 누락 (구조적 귀결이라 리스크 낮음) |
| 설계 | 헥사고날 완전 준수, 엣지 케이스 대부분 처리 |
| 문서 | 문서-코드 용어 일치, 서사-선언 분리 준수 |
| 구현 | 설계-구현 갭 없음, 테스트 커버리지 양호 |
도구가 발견한 실제 이슈
타임존 일관성 문제: LocalDate.now() + ZoneId.systemDefault() 사용. 멀티 노드 환경에서 서버 타임존이 UTC가 아니면 “당일” 경계가 달라져 데이터 누락/중복 가능. 정적 분석이나 단위 테스트로는 드러나지 않는, 런타임 환경 의존적인 이슈입니다.
페이지네이션 비대칭: 당일 실시간 데이터가 첫 페이지에만 병합되어, totalElements가 페이지마다 달라지는 구조적 한계 감지. 프론트엔드와의 API 계약 확인을 권고. 코드 자체에는 버그가 없어 기존 테스트를 통과하지만, 설계 관점에서 보면 API 소비자에게 혼란을 줄 수 있는 지점입니다.
트랜잭션 경계: DELETE+INSERT에 @Transactional이 없으나, 멱등성 + 백필 복구가 트랜잭션의 역할을 대체하는 설계임을 확인. 문제가 아닌 의도적 설계였음을 검증으로 확인한 사례.
세 번째 이슈가 교차 검증의 가치를 잘 보여줍니다. 자동화된 도구라면 “
@Transactional누락”으로 경고를 띄웠을 것입니다. 교차 검증은 “왜 없는지”를 개발자와 함께 확인하고, 의도적 설계임을 기록으로 남겼습니다.
커스텀 체크의 효과
프로젝트 설정에 포함된 헥사고날 아키텍처 체크가 실제로 작동했습니다.
| 커스텀 체크 | 결과 |
|---|---|
| UseCase WHAT만 표현 | 준수 |
| 메서드 오버로드 패턴 | 준수 |
| Repository CUD 단일 도메인 | 준수 |
범용 4축 검증만으로는 확인하기 어려운, 프로젝트 고유의 아키텍처 원칙을 검증할 수 있었습니다.
4. 두 검증이 보여준 것
| 자체 검증 (플러그인 레포) | 실전 검증 (미터링 시스템) | |
|---|---|---|
| 대상 특성 | 프롬프트-only, 코드 없음 | 헥사고날, 48파일 피처 브랜치 |
| 강점 축 | 문서(축 3) — 문서 품질 판단에 유효 | 설계(축 2) + 구현(축 4) — 코드 판단에 유효 |
| 약점 | 코드 철학 검증 불가 | 아키텍처 인식이 cross-verify.json에 의존 |
| 핵심 교훈 | 도구의 한계를 도구 자신이 보여줌 | 프로젝트 설정이 있으면 코드 철학도 작동 |
자체 검증에서 “코드 철학이 없다”고 판단했지만, 실전 검증에서는 cross-verify.json의 커스텀 체크가 채웠습니다. 완전하지는 않습니다. 아키텍처 인식이 수동 설정에 의존한다는 것은 여전히 한계입니다.
5. 아직 해결하지 못한 것
아키텍처 자동 인식
현재는 개발자가 cross-verify.json에 아키텍처 원칙을 수동으로 기술해야 합니다. 레포의 디렉토리 구조, 의존성 방향, 모듈 경계를 자동으로 파악하는 단계가 없습니다.
이상적으로는 검증 전에 레포를 프로파일링하여:
- 프로젝트 유형과 기술 스택을 감지하고
- 모듈 경계와 레이어 구조를 파악하고
- 이 정보를 기반으로 4축 질문을 구체화해야 합니다
운영 컨텍스트
같은 코드라도 팀 규모, 서비스 특성, 트래픽 패턴에 따라 판단이 달라집니다.
| 상황 | 2명 / 내부 API | 20명 / 커머스 |
|---|---|---|
| 모놀리스 | 적절 | 리스크 |
| 추상화 3단 | 과잉 | 필요 |
| 테스트 30% | 감내 가능 | 위험 |
“확장성을 고려했는가?”라는 질문은 팀이 2명이면 과한 요구이고, 20명이면 당연한 요구입니다. 검증 도구가 이 맥락을 모르면 부적절한 권고를 하게 됩니다.
6. AI 도구로서의 위치
교차 검증은 AI에게 판단을 맡기는 도구가 아닙니다. AI를 또 하나의 시선으로 활용하여, 개발자가 소통하며 최종 확인을 하는 구조입니다.
현재 대부분의 조직에서 AI는 자동화 주체가 아닌 의사결정 보조 역할입니다. 코드를 생성하고, 리뷰하고, 테스트를 돌리는 자동화는 이미 많습니다. 그러나 “이 설계가 왜 맞는지”를 개발자가 AI와 함께 확인하는 도구는 드뭅니다.
교차 검증 플러그인은 그 빈 자리를 채우려는 시도입니다. 실전 검증에서 트랜잭션 경계 이슈를 확인한 사례가 이를 보여줍니다 — @Transactional 누락을 기계적으로 경고하는 것이 아니라, 왜 의도적으로 없는지를 개발자와 함께 확인하고 기록했습니다.
마치며
| 항목 | 상태 |
|---|---|
| 문서 철학 | 검증됨 — 자체 검증에서 유효 |
| 코드 철학 | 부분 검증 — cross-verify.json 기반으로 작동, 자동 인식은 미구현 |
| 운영 컨텍스트 | 설계 단계 — 팀 규모·서비스 특성 반영 방안 구상 중 |
도구는 아직 완성되지 않았습니다. 그러나 “완성되지 않은 도구로 자기 자신을 검증하고, 그 결과로 다음 방향을 찾는 과정” 자체가 교차 검증의 작동 방식입니다.
교차 검증을 요청하는 행위는 나의 여러 생각들에 대해 다시 한번 체크시키는 것입니다. 이 글도 그 과정의 기록입니다.
이 글은 Claude와 함께 작업했습니다.