AI가 짠 코드, 검증 루프 없이 병합하면 생기는 일

AI가 짠 코드, 검증 루프 없이 병합하면 생기는 일

Bun의 6,755커밋 무검증 병합이 실증한 것—'테스트 통과'와 '이해된 코드베이스'는 전혀 다른 말이다

AI 코드 검증 스펙 주도 개발 Claude Code Bun Rust 재작성 검증 루프 AI-First 워크플로우 코드 리뷰 자동화
광고

6일 만에 병합된 6,755개 커밋

Bun 팀이 Zig로 작성된 JS 런타임을 Rust로 재작성한 PR을 공개한 건 5월 8일이었다. 병합은 5월 14일. 브랜치명은 claude/phase-a-port. 6일 만에 프로덕션급 런타임 전체가 바뀌었다.

PR 리뷰어 목록을 보면 더 불편해진다. coderabbitai[bot], claude[bot]—그리고 유일한 인간 리뷰어 alii는 'Awaiting requested review' 상태였다. 한 줄로 요약하면 이렇다: Claude가 쓴 코드를 Claude가 리뷰했다. 폐쇄 루프다. 논리적으로 불가능한 일은 아니지만, 결과적으로 이 코드베이스를 인간이 끝까지 읽은 적이 없다는 뜻이 된다.

'테스트 통과'가 보장하지 못하는 것

여기서 가장 흔한 반론이 나온다. "테스트가 다 통과했잖아요." 맞다. 그런데 테스트 스위트는 알려진 경로의 올바름만 검증한다. 에러 경로가 올바르게 처리되는지, 동시성 상황에서 상태 일관성이 유지되는지, 극단적 메모리 조건에서 의도한 대로 동작하는지—이런 영역은 테스트가 충분히 커버하기 어렵다.

Bun 분석 글(geeknews)이 짚은 핵심이 바로 이 지점이다. AI의 코드 번역은 국소적 의미 동등성(local semantic equivalence)에 가깝다. 각 함수가 원본과 고립된 상태에서 동일하게 동작하도록 맞추는 것. 하지만 함수 사이의 전역 불변식, 테스트에 적히지 않고 원저자의 머릿속에만 있는 설계 제약은 AI 번역만으로 보장하기 어렵다. 이런 제약은 지금 당장은 드러나지 않다가 6개월 뒤 특정 프로덕션 부하에서 설명하기 어려운 충돌로 나타난다.

이번 재작성의 실제 기술적 베팅은 Zig 대 Rust가 아니다. AI가 생성하고 리뷰되지 않은 코드를 프로덕션 환경에서 장기 유지보수할 수 있는가—이것이 진짜 질문이다.

스펙-검증 루프: 엔지니어링 규율을 아티팩트로 만들기

그렇다면 대안은 무엇인가. dev.to의 'Grounded Code' 시리즈가 제안하는 5단계 루프는 이 질문에 구조적으로 답한다.

  1. Spec — 코드 변경 전 <feature>.spec.md 작성 또는 업데이트
  2. Plan — 플랜 모드 진입. 에이전트는 읽고 제안만 하고, 쓰지 않는다
  3. Implement — 승인된 플랜을 실행
  4. Verify — 스펙의 검증 블록을 명시된 대로 실행
  5. Consolidate — 커밋, 스펙과 현실 조율, 스크래치패드 정리

핵심 논지는 이렇다: AI 에이전트는 어제 내가 내린 결정을 기억하지 못한다. 암묵적 습관을 턴 간에 유지하지 못한다. 따라서 인간 엔지니어가 머릿속에 가지고 있던 '플랜'이 에이전트가 다시 읽을 수 있는 쓰여진 플랜이 되어야 한다. 엔지니어링 규율을 아티팩트로 렌더링하는 것—이것이 이 루프의 존재 이유다.

가장 비싼 실패 모드: 스펙을 건너뛰는 것

이 루프에서 사람들이 가장 많이 건너뛰는 건 1단계다. "나는 뭘 만들어야 하는지 알아, 그냥 코드 짜자"는 본능. 나도 그랬고, 내가 지켜본 엔지니어들도 전부 그랬다.

Bun 사례가 이를 정확히 실증한다. 스펙 없이 AI에게 코드를 맡기면, 에이전트는 3턴 후부터 원래 의도를 잃기 시작한다. 컨텍스트가 일부 압축되고 엣지 케이스를 추론하는 시점에서, 에이전트는 그냥 그럴싸한 기본값을 채워넣는다. 아슬아슬하게 당신이 원하던 것과 비슷하지만 다른 것으로. 이 잘못된 결정이 다음 턴에 영향을 주고, 또 다음 턴에 영향을 준다. 10턴쯤 지나면 테스트는 통과하지만 당신이 요청한 게 아닌 피처가 완성된다. 스펙은 10~15분 작업이다. 이 드리프트를 진단하는 데 드는 수 시간과 비교해보라.

플랜 모드가 시간을 가장 많이 아끼는 이유

2단계가 실질적으로 가장 큰 ROI를 제공한다. 경제적 논리는 단순하다: 나쁜 플랜은 버리기 싸다. 나쁜 구현은 비싸다. 잘못된 플랜은 토큰 몇 천 개 손해다. 잘못된 구현은 수백~수천 줄의 코드, 더럽혀진 git 상태, 정리해야 할 테스트 실패다. 심리적 매몰비용도 무시 못 한다—구현이 이미 있으면 버리기가 어렵다.

플랜 모드에는 덜 알려진 두 번째 효과가 있다. 에이전트는 플랜 모드에서 더 꼼꼼하게 읽는다. "실행한다"가 아니라 "제안한다"는 프레임이 코드베이스를 탐색하고, 관련 파일을 파악하고, 대안을 고려하는 방향으로 에이전트를 유도한다. Claude Code를 포함한 주요 코딩 에이전트 하네스들이 플랜 모드 유사 기능을 핵심 기능으로 두고 있는 건 우연이 아니다.

테크 리드의 시사점: 검증 루프는 선택이 아니다

Bun 사례가 우리 팀에게 던지는 메시지는 명확하다. AI 생성 코드의 위험은 코드 품질 문제가 아니라 이해 가능성 문제다. 단기적으로 재작성 버전이 대체로 잘 동작할 수 있다. 주요 경로는 테스트로 커버되고, canary 단계에서 명백한 문제가 드러날 것이다. 하지만 6개월 뒤 동시성 버그가 나타나면, 디버깅 엔지니어는 팀 누구도 진정으로 이해한 적 없는 시스템을 마주하게 된다.

"이해된 적 없는 시스템"은 버그가 없다는 뜻이 아니다. 버그가 나타났을 때 왜 그런지 아무도 모른다는 뜻이다.

5단계 루프는 이 문제에 대한 엔지니어링적 응답이다. 스펙을 먼저 쓰고, 플랜을 검토하고, 검증 블록을 명시하는 것—이것은 AI 시대에 검증 가능성을 유지하는 최소한의 규율이다. 팀이 AI 도구를 빠르게 쓸수록, 이 루프의 각 단계를 건너뛰고 싶은 유혹도 커진다. 하지만 Bun이 실증했듯, 건너뛴 검증은 미래의 누군가가 반드시 치르게 될 부채다.

전망: 스펙-검증 규율이 AI-First의 다음 기준선이 된다

AI 코딩 도구 도입 초기에는 '얼마나 빠르게 코드를 생성하는가'가 기준이었다. 다음 단계는 'AI가 생성한 코드를 팀이 얼마나 이해하고 유지보수할 수 있는가'로 옮겨간다. 이 전환의 시그널은 이미 여러 곳에서 보인다—Hermes Guard 같은 에이전틱 저장소 리스크 감사 도구의 등장, 플랜 모드를 핵심으로 내세우는 하네스 설계 수렴, 그리고 Bun 같은 실패 사례의 공개적 해부.

테크 리드로서 팀에 AI 도구를 도입할 때 지금 당장 적용할 수 있는 최소 규율은 세 가지다. 첫째, 스펙 없는 AI 구현 PR은 머지하지 않는다. 둘째, 대규모 AI 생성 변경은 플랜 모드를 통해 인간이 방향을 먼저 검토한다. 셋째, 검증 블록을 스펙에 명시적으로 작성하고, AI 리뷰어만으로 폐쇄 루프를 형성하지 않는다. 속도는 이 규율 위에서만 지속 가능하다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요