ai-coding-mines목차GitHub

CI 그린은 실동작을 보증하지 않는다

Claude Code · 에이전트

실증 3건

해법

그린은 필요조건이다. 실기기·실브라우저와 계측 지표로 라이브를 별도 검증한다. 판정은 조회 시 재계산한다.

역방향 지뢰 — 회귀 계약이 '버그값'을 동결한다

캡처된 산출물을 baseline으로 삼아 재실행 결과와 대조하는 계약 테스트에서, 캡처 시점이 버그 상태였다면 그 버그가 동결된다. 실측: baseline이 images: 1(갤러리 버그)을 기록 → 수리로 1→11이 되자 계약이 red.

의도된 수리는 baseline을 재추출값으로 갱신해야 한다.

  1. 영향 필드만 재생성
  2. 나머지 계약 필드 불변 실증
  3. 커밋 메시지에 "버그 동결 아님, 교정값 반영" 명시

지연 import의 함정

try: from PIL import Image / except: return None 은 CI collect-only 안전을 위한 정본 패턴인데, 없을 때 예외 대신 조용히 무력화된다. 지연 import로 감싼 서드파티는 반드시 requirements 확인 + 명시 계약을 건다. "테스트가 통과하니 있다"는 근거가 아니다 — 그 테스트도 같은 컨테이너에서 돈다.

실증 4건째 — mock이 프로덕션이 안 지나는 길을 검사한다

외부 API 오류를 수리하고 mock으로 "재현 → 통과"까지 찍어 보고했다. 그런데 그 mock은 직결 레그에 패치돼 있었고, 프로덕션은 같은 호출을 릴레이로 내보낸다. 갈림은 환경변수 하나로만 일어나고 샌드박스 기본값이 조용한 쪽(직결) 이라 그린이 떴다. 릴레이를 켜고 같은 코드를 돌리자 직결 호출 0회, 릴레이 호출 1회 — 검사한 길을 프로덕션은 한 번도 밟지 않는다. 호출부는 단일 관문이라 코드를 읽어서는 어느 레그가 도는지 모른다.

  1. 분기를 만드는 env를 테스트가 직접 켠다. 기본값에 기대면 조용한 쪽만 검사한다
  2. 반대편 레그가 0회 호출임을 단언한다 — 패치 지점이 프로덕션 경로라는 사실을 계약으로 박는다
  3. 환경으로 갈리는 경로는 양쪽 다 계약을 둔다. 하나만 두면 나머지가 사각이 된다

"재현했다"는 어느 코드를 재현했는지까지 말해야 성립한다. 틀린 길의 초록은 없느니만 못하다 — 고쳤다고 믿게 하니까.

그린의 함정의 거울 — 면책의 함정

캡처 화면에서 아이콘이 깨져 보였다. 에이전트는 "캡처 아티팩트다 — 정적 자원 경로를 파일 기반 렌더가 못 가져올 뿐, 앱에서는 정상"이라고 판정했다. 메커니즘 설명은 그럴듯했고 결론은 틀렸다 — 라이브에서 찍은 같은 파손이 나왔다.

아티팩트 판정은 조사를 끝내는 판정이다. "우리 문제가 아니다"로 분류된 자리는 아무도 다시 안 본다. 그래서 틀리면 결함이 라이브에 그대로 남는다 — 못 본 건 언젠가 보이지만, 면책된 건 안 찾는다. 그리고 메커니즘이 맞아도 그게 이 파손의 원인이라는 증거는 아니다. 판정은 검증이 싼 쪽이 아니라 비싼 쪽에 있는데, 라이브 확인을 메커니즘 설명으로 대신했다.

"우리 문제가 아니다"는 가장 비싼 결론이라 가장 비싼 증거를 요구한다. 초록의 함정이 검증을 건너뛰게 한다면 면책의 함정은 조사를 멈추게 한다 — 조사를 멈추는 판정일수록 근거가 무거워야 한다. 재현이 안 돼도 의존을 없애는 수리(인라인화)는 가능하다.