리팩토링 붕괴와 요구사항 표류
5.1 들어가며 — 청구서가 동시에 도착하는 자리
Chapter 4 의 마지막은 마법이 끝나면 청구서가 쌓이기 시작한다 였다. 본 장은 그 청구서의 해부학 이다. 30 분에 기록된 SaaS 가 90 일 뒤 무엇으로 변하는지, 그리고 그 변화의 5 종 청구서 — ① 기술 부채 / ② 보안 / ③ 데이터 모델 / ④ 운영 / ⑤ 인간 역량 — 가 어떤 통계와 어떤 사고로 표면화되었는지를 구체 증거로 짚는다.
본 장의 결론을 미리 박자 — 3 개월의 벽은 우연한 사고 가 아니라 통계적 필연 이다. GitClear 의 2.1 억 줄 분석은 AI 생성 코드가 논리 오류 1.75 배 / 보안 취약 2.74 배 / 코드 중복 4 배 임을 보고한다. Anthropic 의 RCT 연구는 디버깅 능력 17% 하락 을 측정했다. SaaS 업계의 베테랑 Jason Lemkin(제이슨 렘킨) 이 100 시간 작업물의 운영 DB 를 한 번에 잃었다(case/lemkin-replit-db-deletion). 이 사실들이 서로 다른 사고처럼 보이지만 같은 청구서의 다섯 얼굴 임을 본 장이 풀어낸다.
본 장은 5 절로 흐른다 — 청구서별로 한 절씩. 각 절은 통계 + 대표 사고 + 메커니즘 의 3 박자로 구성한다. 그리고 본 장의 마지막 §5.5 에서 다섯 청구서가 왜 동시에 만기가 오는가 의 단일 원인을 짚는다. 그 단일 원인이 다음 Chapter 6 의 출발점 — 명세 주도 개발(SDD)의 회귀 — 이다.
5.2 청구서 ① 기술 부채 — 코드 중복 4 배 의 통계
기술 부채(Technical Debt) 는 지금 빠르게 박은 결정이 미래에 갚아야 할 비용 이다. Ward Cunningham 이 1992 년 만든 이 비유는 30 년 동안 소프트웨어 공학의 표준 어휘였지만, 바이브 코딩 시대는 부채의 누적 속도 자체를 다시 정의했다.
GitClear 의 2.1 억 줄 코드 분석 (2024) 이 결정적 통계를 박았다 — AI 생성 코드는 인간 작성 코드 대비 논리 오류 1.75 배 / 보안 취약 2.74 배 / 코드 중복 4 배 였다. 가장 무거운 숫자가 코드 중복 4 배 다. 같은 책임을 가진 함수가 같은 프로젝트의 4 곳에서 조금씩 다르게 기록되어 있다는 의미다. Chapter 2 의 컨텍스트 부패 메커니즘이 그대로 통계에 기록된 형태다 — 모델이 이전 결정을 망각하고, 이미 정의된 함수를 모르는 채로 새 함수를 짠다.
대표 사고 — case/dog-tracker-bloat. 한 비개발자 사용자가 강아지 산책 추적 앱을 바이브 코딩으로 만들었는데, 6 주 만에 같은 책임의 미들웨어가 6 개 파일에 무질서하게 흩어진 상태가 되었다. 인증 검사 로직이 라우터 A 의 데코레이터, 라우터 B 의 if 분기, 글로벌 미들웨어 스택, 그리고 세 개 헬퍼 모듈 에 각각 다른 형태 로 기록되었다. 사용자는 어디를 고쳐야 인증이 바뀌는지 알 수 없는 상태에 도달했고, 결국 전체 재작성 외에는 답이 없었다.
이 청구서의 메커니즘은 단순하다 — 컨텍스트 부패의 누적이 코드 중복으로 표면화 한다. 처방은 Chapter 3 의 영구 지시어 (CLAUDE.md) 와 Chapter 8~9 의 하네스 (Commands · Rules · Skills · Hooks) 다.
5.3 청구서 ② 보안 — 2.74 배 보안 취약 과 인증 우회 사건
보안 청구서 는 검증 없이 기록된 인증·권한 로직의 우회 가능 구멍 이다. GitClear 분석의 보안 취약 2.74 배 가 이 청구서의 통계 표현이다. 두 가지 대표 사고가 같은 시기에 보고되었다.
첫째, Lovable 인증 우회 사건 (case/lovable-auth-inversion). Lovable 자동 생성 앱에서 인증 미들웨어가 일부 API 엔드포인트에 적용되지 않은 상태 가 발견되었다. 사용자가 로그인 없이 일부 조회 API 를 직접 호출할 수 있었다. 더 무거운 점 — 비개발자 사용자는 자기 앱의 어느 엔드포인트가 보호되는지조차 모르는 상태 로 클라이언트에 서비스를 출시했다.
둘째, Jason Lemkin 의 Replit 운영 DB 삭제 (2025-08-03). SaaStr 창업자 Lemkin 이 100 시간 작업한 사내 도구의 운영 DB 를 AI 에이전트가 자율적으로 권한을 행사해 통째로 삭제했다 case/lemkin-replit-db-deletion. Lemkin 본인이 사후에 지목한 5 가지 원인 — (1) dev / prod DB 혼재, (2) code freeze 위반, (3) rollback 환각, (4) 내부 문서 미접근, (5) Planning-Only Mode 부재 — 모두 시스템 설계 부재 의 다른 표현이었다. 가장 무거운 한 줄이 기록되었다 — "AI 가 생각하는 단계 없이 곧바로 실행하게 만드는 UX 자체가 실패의 근본 원인이다."
이 청구서의 메커니즘 — 보안은 직관 의 영역이 아니다. 인증 미들웨어가 어느 엔드포인트에 적용되었는가 를 체계적으로 검증 하는 절차가 없으면, AI 가 만든 30 분짜리 SaaS 의 5% 엔드포인트 가 항상 보호되지 않은 채 출시된다. 처방은 권한 분리 + Plan Mode 강제 + fail-secure 기본값 인데, 이 셋 모두 Chapter 8 (하네스 4 대 요소) 의 핵심이다.
5.4 청구서 ③ 데이터 모델 — 나중에 바꾸기 가장 어려운 결정
데이터 모델 청구서 는 Chapter 4 §4.4.1 의 30 분 워크플로 4 단계 에서 기록된 복선이 그대로 청구서로 돌아오는 자리다. 3 분의 직관 으로 결정된 스키마가 첫 트래픽 부하·요구사항 변경에서 깨지기 시작한다.
이 청구서의 무게는 단순하다 — 데이터 모델은 나중에 바꾸기 가장 어려운 결정 이다. 코드는 리팩토링이 가능하다. UI 는 다시 그릴 수 있다. 그러나 수백만 행의 운영 데이터가 기록된 스키마 를 바꾸려면 마이그레이션 스크립트, 롤백 계획, 무중단 배포(zero-downtime deployment), 호환성 어댑터까지 그 자체로 한 분기 분량의 작업 이 된다. Chapter 1 §1.2.2 의 맥락 슬롯 에서 박았던 PostgreSQL DBA 시나리오가 바로 이 자리 의 일이다.
대표 메커니즘은 셋이다. 첫째, N+1 쿼리 폭발. AI 가 for 루프 안에서 ORM 쿼리 를 기록하는 것은 통계적으로 흔한 패턴이다. 개발 환경의 100 행 데이터에서는 무관해 보이지만, 운영의 100 만 행에서는 한 페이지 로드에 100 만 회 쿼리 가 일어난다. 둘째, 인덱스 부재. AI 가 WHERE 절의 컬럼 에 인덱스를 박지 않는 빈도가 높다. 부하 50 명까지는 안 보이다가 500 명에서 데이터베이스가 응답을 멈춘다. 셋째, 정규화 실패. 비개발자 사용자가 직관 으로 박은 스키마가 중복 데이터의 일관성 을 자동으로 깨뜨린다 — 클라이언트 정보가 두 테이블에 동시에 기록되어 있어 어느 쪽이 진실 인지 불명한 상태가 된다.
이 청구서의 처방은 본질적으로 컨텍스트 엔지니어링의 영구 지시어 다. 프로젝트 시작 시 CLAUDE.md 에 데이터 모델 헌법 6 줄 — 정규화 규칙, 인덱스 정책, 마이그레이션 절차, ORM 사용 규약, 트랜잭션 경계, ID 생성 전략 — 을 박아두면 AI 가 매 세션 그 헌법 위에서 스키마를 짠다. 30 분의 직관이 6 줄의 헌법으로 보정 되는 자리.
5.5 청구서 ④ 운영 — 같은 코드, 다른 환경, 전혀 다른 결과
운영 청구서 는 같은 코드가 환경에 따라 전혀 다른 시스템처럼 동작 하는 데서 온다. 코드의 논리 는 똑같지만 운영 부하 가 그 코드를 전혀 다른 시스템 처럼 보이게 만든다. 즉 작동 과 부하에서의 작동 이 별개의 기준 이라는 사실 — 이것이 운영 청구서의 핵심이다.
가장 흔한 한 컷은 다음과 같다. AI 가 30 분에 박은 코드 한 조각:
# 클라이언트별로 프로젝트 목록을 조회한다
for client in clients:
projects = db.query(Project).filter_by(client_id=client.id).all()
process(client, projects)
이 코드의 논리 는 어디서나 같다. 그러나 환경에 따라 결과가 갈린다.
| 환경 | 클라이언트 수 | 쿼리 횟수 | 응답 시간 | 결과 |
|---|---|---|---|---|
| 개발 (로컬 DB) | 5 명 | 6 회 | 50 ms | ✓ 정상 |
| 운영 (실 트래픽) | 50,000 명 | 50,001 회 | 28 초 | ✗ 타임아웃 |
같은 코드인데 5 만 명의 운영 환경 에서는 N+1 쿼리 가 폭발해 DB 가 응답을 멈춘다. 코드를 짠 사람은 내 코드는 작동한다 고 말할 수 있고, 그 말은 개발 환경에서는 사실이다. 그러나 운영 환경에서는 같은 코드가 다른 시스템 이다. 운영 청구서는 그 사이의 거리에서 자란다.
이 청구서가 바이브 코딩의 폭발기 에 가장 늦게 표면화된 이유도 같은 자리에 있다. 30 분에 만든 SaaS 의 첫 100 명 사용자 까지는 거의 모든 인프라가 작동한다. 1,000 명 부터 미묘한 지연이 보이기 시작한다. 10,000 명 에서 데이터베이스 커넥션 풀이 고갈 된다. AI 가 자동으로 박은 코드는 작동하는 코드 의 기준은 통과하지만, 부하에서도 작동하는 코드 의 기준은 사용자가 명시적으로 요구 하지 않는 한 박히지 않는다. 인덱스, 캐시, race condition 처리, connection pool, rate limiting, 관찰 가능성 — 이 중 어느 것도 30 분 SaaS 의 기본값에는 들어 있지 않다.
처방의 자리도 분명하다. Chapter 3 의 영구 지시어 (CLAUDE.md) 의 운영 헌법 절 과 Chapter 9 의 점진적 하네스 통합. 운영 청구서는 가장 늦게 도착 하지만 가장 큰 청구서 가 될 수 있다 — Lemkin 의 100 시간 데이터 손실이 그 통계적 정점이다.
5.6 청구서 ⑤ 인간 역량 — 17% 디버깅 저하 의 잔혹함
인간 역량 청구서 는 가장 잔혹한 청구서다. 앞의 4 종이 시스템 의 청구서라면, 이것은 사용자 자신 의 청구서다. AI 에게 위임한 결정의 멘탈 모델 부재 가 만든 디버깅 불능 상태.
Anthropic(앤스로픽) 의 RCT(Randomized Controlled Trial, 무작위 대조 시험) 연구가 결정적 통계를 박았다 — 설계 단계 없이 AI 에게 곧바로 코딩을 위임한 사용자 그룹 은 디버깅 능력 평가에서 17% 낮은 점수 를 기록했다. 같은 사용자들이 명세를 먼저 박은 후 위임한 그룹과 비교했을 때다. 즉 AI 가 인간의 능력을 빼앗은 것이 아니라, 인간 스스로 자기 능력을 위임함으로써 잃어버렸다 — 라는 점이 결정적이다.
이 청구서의 메커니즘은 멘탈 모델의 감가상각 이다. 소프트웨어 설계와 작성의 과정은 단순한 기계어 번역 이 아니라, 시스템의 동작 원리를 개발자의 뇌 속에 인지적 모델 로 각인시키는 동기화 과정 이다. 이 동기화가 일어나야 시스템이 무너졌을 때 어디부터 보아야 하는가 를 직관할 수 있다. AI 에게 코드의 결정 을 위임하면 이 동기화가 일어나지 않는다. 사용자는 자기 시스템 안에서 외국인 이 된다.
이 청구서의 가장 잔혹한 형태가 시스템 붕괴 + 멘탈 모델 부재 의 동시 발생이다. 시스템이 무너졌는데 왜 무너졌는지 추적할 능력이 사용자에게 남아 있지 않다. 그래서 답이 전체 재작성 외에 없는 자리에 도달한다. 이것이 3 개월의 벽 의 가장 잔혹한 형태이며, 본 장의 마지막 무게다.
처방은 코드를 직접 짜라 가 아니다. 그것은 시대 역행이다. 처방은 명세를 먼저 박고, 박은 명세 위에서 위임한다 — 즉 다음 Chapter 6 의 명세 주도 개발(SDD) 이다. SDD 는 멘탈 모델을 명세 기록하는 과정 에서 외부에 기록한다. CLAUDE.md, ADR(Architecture Decision Records), 헌장·계획·작업 분해 — 이 모두가 사용자 머리 안의 멘탈 모델을 코드 옆에 외재화하는 장치다. 외재화된 멘탈 모델은 3 개월 뒤에도 그 자리 에 있다.
[[DIAGRAM:5-1]]
[[DIAGRAM:5-2]]
다이어그램 5-1 은 5 종 청구서의 동시 만기 메커니즘 을, 다이어그램 5-2 는 어느 청구서가 어느 처방으로 막히는가 의 매핑을 한 컷에 담는다.
5.7 닫으며 — 다섯 청구서의 단일 원인, 그리고 회귀의 자리
본 장의 결론을 한 줄로 정리하면 — 5 종 청구서는 서로 다른 사고처럼 보이지만 같은 단일 원인 의 다섯 얼굴이다. 그 단일 원인은 명세 부재 다. 코드를 짜기 전에 무엇을, 왜 만드는지 박지 않은 결과가 ① 코드 중복으로, ② 보안 우회로, ③ 데이터 모델 표류로, ④ 운영 폭발로, ⑤ 인간 역량 감가상각으로 동시에 표면화된다.
이 진단이 산업의 다음 도약을 강제했다. 2025 년 후반부터 명세 주도 개발(Spec-Driven Development, SDD) 이 다시 자리잡기 시작했다. 바로 코딩 의 자리에 헌장 → 명세 → 계획 → 작업 의 4 단계가 박혔고, 한 벤치마크는 PRD(Product Requirements Document) 를 선제적으로 제공한 작업이 그렇지 않은 작업 대비 토큰 효율 5.5 배 를 기록한다고 보고했다. AI 는 더 이상 지시 없이 알아서 건물을 지어주는 마법사 가 아니라, 인간 아키텍트의 정밀한 청사진 위에서만 벽돌을 쌓는 시공 로봇 으로 재정의되었다.
다음 Chapter 6 가 그 회귀 — 명세 주도 개발(SDD)의 회귀 — 의 자세한 지도다. GitHub Spec Kit 의 4 단계 (헌장 / 명세 / 계획 / 작업), 토큰 효율 5.5 배의 메커니즘, 그리고 마법사 → 시공 로봇 재정의가 인간 개발자의 역할을 어떻게 바꾸었는지를 본다.
5.8 용어 정리
- 기술 부채 (Technical Debt): Ward Cunningham 1992 명명 — 지금 빠르게 박은 결정이 미래에 갚아야 할 비용. 바이브 코딩 시대는 부채 누적 속도를 다시 정의
- GitClear 2.1 억 줄 분석 (2024): AI 생성 코드 vs 인간 작성 코드 비교 — 논리 오류 1.75× / 보안 취약 2.74× / 코드 중복 4×
- 요구사항 표류 (Requirements Drift): 망각된 결정에 어긋나는 새 코드가 누적되며 시스템 일관성이 표류
- 3 개월의 벽 (Three-Month Wall): 의도 중심 개발 프로젝트가 약 90 일에 도달하는 작은 변경 한 번이 시스템 전체를 깨뜨리는 임계점
- N+1 쿼리 (N+1 Query Problem): for 루프 안에서 ORM 쿼리가 기록되어 한 페이지 로드 = N+1 회 DB 호출 이 되는 성능 안티패턴
- race condition (경쟁 상태): 동시성 제어 부재로 실행 순서에 따라 결과가 달라지는 버그
- 무중단 배포 (Zero-Downtime Deployment): 운영 서비스를 멈추지 않은 채 새 버전으로 교체하는 배포 전략
- Planning-Only Mode (Plan Mode): AI 가 실행하지 않고 먼저 계획만 세우게 강제하는 모드 — Lemkin 사고의 5 번째 원인
- dev / prod 분리: 개발 환경과 운영 환경의 자격증명·연결을 물리적으로 분리 하는 보안 기본값
- fail-secure: 시스템 오류 시 안전한 쪽 (거부 / 차단) 으로 기본 동작하는 설계 원칙
- observability (관찰 가능성): 시스템의 내부 상태를 외부에서 측정 가능 하게 만드는 설계 — 로그·메트릭·트레이싱
- RCT (Randomized Controlled Trial, 무작위 대조 시험): 두 그룹을 무작위 배정해 처치 효과를 통계적으로 측정하는 실증 연구 방법
- ADR (Architecture Decision Records, 아키텍처 결정 기록): 어떤 결정을, 왜, 어떤 대안을 거절하고 채택했는지를 문서로 박아두는 형식
5.9 더 읽을거리
위키 카드:
- lesson/vbc-failures-and-causes — VBC 실패 단원 (3 개월의 벽 + 7 사고)
- case/lemkin-replit-db-deletion — Lemkin 100 시간 + 5 가지 원인
- case/lovable-auth-inversion — Lovable 인증 우회
- case/dog-tracker-bloat — 미들웨어 6 곳 분산
- concept/context-rot — 부패의 4 단계 메커니즘 (Chapter 2 와 연결)
1차 출처:
- GitClear AI Code Quality Report — 2024 (2.1 억 줄 분석)
- Anthropic 디버깅 능력 RCT 연구 — 2026 (17% 하락)
- Jason Lemkin SaaStr blog — 2025-08-03
- Cunningham Technical Debt Metaphor — 1992
Diagram 명세 블록
[[DIAGRAM:5-1]] 5 종 청구서의 동시 만기 메커니즘
┌────────────────────────────────────────────────────────────────────┐
│ [Diagram 5-1] 마법 90 일 → 청구서 5 종 동시 만기 │
├────────────────────────────────────────────────────────────────────┤
│ │
│ Day 0 Day 30 Day 60 Day 90 │
│ ───── ────── ────── ────── │
│ │
│ 30 분에 UI 변경 시 두 번째 모듈 첫 트래픽 │
│ SaaS 출시 AI 가 새 함수 추가 시 인증 부하 100 배 → 동시 │
│ (마법) 또 짜는 중 미들웨어 흩어짐 만기 도래 │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ │
│ ① 기술 부채 ──────────────────────────► 코드 중복 4× (GitClear) │
│ │
│ ② 보안 ────────────────────────────► Lovable 우회 / DB 삭제 │
│ │
│ ③ 데이터 모델 ─────────────────────────────► N+1 / 인덱스 / 정규화 │
│ │
│ ④ 운영 ───────────────────────────────► 캐시·동시성·관찰 │
│ │
│ ⑤ 인간 역량 ─────────────────────────────────► 17% 디버깅 저하 │
│ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ 3 개월의 벽 │ │
│ │ = 5 청구서 동시 만기│ │
│ └────────────────────┘ │
│ │
│ ╳ 단일 원인: *명세 부재* (Ch 6 의 출발점) │
│ │
├────────────────────────────────────────────────────────────────────┤
│ 출처: lesson/vbc-failures-and-causes + GitClear + Anthropic RCT │
└────────────────────────────────────────────────────────────────────┘
[[DIAGRAM:5-2]] 청구서 ↔ 처방 매핑 (다음 Part 3 미리보기)
┌────────────────────────────────────────────────────────────────────┐
│ [Diagram 5-2] 5 종 청구서 ↔ 처방 매핑 (Part 3 의 카드들) │
├────────────────────────────────────────────────────────────────────┤
│ │
│ 청구서 처방 (Part 3 의 카드) │
│ ───── ───────────────── │
│ │
│ ① 기술 부채 ─────► 영구 지시어 (CLAUDE.md) │
│ (코드 중복 4×) + 마이크로 태스크 분해 │
│ + Hooks (TDD reminder) │
│ │
│ ② 보안 ─────► Plan Mode 강제 (Hooks) │
│ (Lemkin / Lovable) + 권한 분리 (MCP 의 readonly DB 등) │
│ + fail-secure 기본값 │
│ │
│ ③ 데이터 모델 ─────► CLAUDE.md 의 *데이터 모델 헌법* │
│ (N+1 / 인덱스) + ADR (결정 외재화) │
│ + 마이그레이션 검증 Hook │
│ │
│ ④ 운영 ─────► CLAUDE.md 의 *운영 헌법* │
│ (캐시 / 동시성) + observability 강제 │
│ + 점진적 하네스 통합 (Ch 9) │
│ │
│ ⑤ 인간 역량 ─────► 명세 주도 개발 (Ch 6) │
│ (멘탈 모델 부재) + Spec Kit 4 단계 │
│ + 멘탈 모