Cheondi
개발 · AI

Codex AI 하네스 엔지니어링 설계 6 — 검증 체계

코드, 테스트, 빌드, 배포 자산과 실제 화면을 서로 다른 증거 단계로 관리한 검증 체계 기록입니다.

  • #ai
  • #codex
  • #verification
  • #evidence
  • #observability

5편까지 작업 경계, 컨텍스트, 도구, 권한, 분할을 정리했다. 마지막으로 남은 건 완료를 판단하는 방식이었다. AI가 “수정했습니다”, “정상입니다”라고 말해도 그 문장을 그대로 믿을 수는 없다. 무엇을 확인했는지가 빠져 있으면 실제 상태를 알 수 없기 때문이다.

이 문제는 AI만의 문제도 아니었다. 나도 로컬 빌드가 성공하면 일이 거의 끝났다고 생각하곤 했다. 하지만 운영에서 겪은 오류는 코드, 빌드, 배포, 실행 환경 사이의 틈에서 많이 생겼다. 그래서 완료를 하나의 단어로 처리하지 않고 증거의 층으로 나눴다.

완료라는 한 단어의 분해

화면 수정 작업이라면 최소 다섯 단계가 있다.

1. 소스 코드에 변경이 존재
2. 관련 테스트가 통과
3. 빌드 산출물에 변경이 포함
4. 대상 서버가 새 산출물을 제공
5. 실제 브라우저에서 기대 동작 확인

2번을 확인하고 5번까지 성공했다고 말할 수는 없다. 각 단계는 다음 단계로 넘어갈 수 있는 근거일 뿐이다.

증거 단계 확인 방법 말할 수 있는 범위
코드 git diff, 정적 검사 의도한 파일이 바뀜
테스트 단위·통합 테스트 준비한 시나리오가 통과
빌드 빌드 로그, 산출물 해시 배포 가능한 결과 생성
배포 서버 자산, 실행 버전 대상 환경에 결과 반영
런타임 브라우저, API, 로그 실제 요청과 사용자 동작 확인

이 표를 작업 보고에 그대로 사용하니 “어디까지 확인했는가”를 다시 묻는 일이 줄었다.

검증 명령도 시작 전에 결정한 방식

구현이 끝난 뒤 테스트를 찾으면 변경에 유리한 검사만 고르기 쉽다. 그래서 수정 전에 실패를 보여 줄 검증을 먼저 정했다.

symptom: 빈 목록인데 로딩 표시가 끝나지 않음
reproduction:
  - API 응답 200
  - items는 빈 배열
expected:
  - 로딩 종료
  - 빈 상태 문구 표시
regression_test:
  - 빈 배열 응답에서 loading=false 확인
runtime_check:
  - 브라우저에서 빈 계정으로 화면 확인

테스트를 먼저 실패시키면 그 테스트가 실제 문제를 잡는다는 증거가 생긴다. 수정 후 처음부터 통과한 테스트는 구현을 검증한 것처럼 보여도 원래 증상을 잡는지 알 수 없다.

성공뿐 아니라 실패를 분류한 이유

검증이 실패하면 처음에는 같은 명령을 다시 실행했다. 하지만 실패 원인이 다르면 다음 행동도 달라야 했다.

TASK_FAILURE
  이번 변경 때문에 발생한 실패

BASELINE_FAILURE
  변경 전부터 존재했던 실패

ENVIRONMENT_FAILURE
  의존성, 권한, 네트워크, 실행 환경 문제

UNCERTAIN
  실행 결과 또는 외부 반영 여부를 확인할 수 없는 상태

TASK_FAILURE는 구현으로 돌아간다. BASELINE_FAILURE는 변경 전 결과와 비교하고 이번 범위에 미치는 영향을 기록한다. ENVIRONMENT_FAILURE는 코드를 고치기보다 환경을 확인해야 한다. UNCERTAIN은 같은 외부 작업을 반복하지 않고 현재 상태를 조회한다.

이 구분만으로도 무의미한 재시도가 많이 줄었다. 실패했다는 사실보다 실패의 종류가 다음 행동을 결정했다.

로그의 신선도와 출처

로그 한 줄은 강한 증거처럼 보이지만 어느 서버의 어떤 파일인지 모르면 의미가 약하다. 특히 여러 인스턴스가 있거나 파일명이 비슷한 환경에서는 오래된 로그를 현재 요청으로 착각하기 쉬웠다.

내가 확인한 순서는 다음과 같다.

호스트와 현재 시각
 -> 실행 프로세스와 작업 경로
 -> 로그 파일의 크기와 수정 시각
 -> 요청 시각 또는 요청 ID 검색
 -> 앞뒤 문맥 확인

검색 결과가 없을 때도 바로 “요청이 오지 않았다”고 결론 내리지 않았다. 먼저 실제 프로세스가 그 로그를 쓰는지 확인했다. 최신 로그라는 조건이 충족돼야 부재도 증거가 된다.

브라우저 검증에서 본 세 가지 층

브라우저에서는 화면, 네트워크, 제공된 자산을 따로 봤다.

화면

사용자가 실제로 보는 문구, 버튼, 상태 변화가 기대와 같은지 확인한다.

네트워크

어떤 설정 파일과 API 주소를 요청했고 응답이 무엇인지 확인한다. 화면이 같아 보여도 잘못된 환경을 호출할 수 있다.

배포 자산

서버가 제공하는 번들에 변경이 포함됐는지 확인한다. 로컬 파일과 배포 파일이 같다는 추측을 피하기 위한 단계다.

세 층이 모두 맞아야 “실제 화면에서 확인했다”고 말했다. 캐시가 의심되면 URL에 임시 쿼리를 붙이거나 새 세션에서 확인하되, 그것만으로 원인을 캐시라고 확정하지는 않았다.

증거를 포함한 완료 보고

완료 보고도 짧은 구조로 통일했다.

change:
  - 빈 목록에서 로딩 종료 처리
verification:
  code: 변경 파일 1개와 회귀 테스트 확인
  test: 18개 통과
  build: 성공, 산출물 생성
  deploy: 새 자산 제공 확인
  runtime: 빈 목록 화면과 네트워크 응답 확인
remaining_risk:
  - 느린 네트워크 조건은 별도 확인 필요

숫자와 결과를 적는 이유는 보고서를 길게 만들기 위해서가 아니다. 다음 사람이 같은 검증을 반복할 수 있게 하기 위해서다. 확인하지 못한 항목은 비워 두지 않고 미확인이라고 적었다.

하네스 설계 이후의 변화

여섯 편을 정리하고 보니 하네스는 거대한 자동화 프로그램이 아니었다. 프로젝트 규칙, 작은 상태 기록, 도구 계약, 권한 경계, 작업 분할, 검증 명령이 맞물린 작업 방식이었다.

작업 경계
 -> 컨텍스트 구조
 -> 도구 계약
 -> 권한 통제
 -> 작업 분할
 -> 증거 기반 검증

모델이 바뀌어도 이 구조는 남는다. 오히려 모델이 더 많은 일을 할수록 어떤 근거로 움직였고 어디까지 확인했는지를 기록하는 장치가 중요해진다.

나에게 AI 하네스 엔지니어링은 AI를 통제하는 기술이라기보다 개발 과정을 명확하게 만드는 기술에 가까웠다. 예전에는 머릿속으로 넘기던 경계와 검증을 문서와 도구로 꺼내 놓게 됐고, 그 결과 AI뿐 아니라 내가 다시 작업을 이어갈 때도 훨씬 편해졌다.


이전 글: Codex AI 하네스 엔지니어링 설계 5 — 작업 분할

관련 글: Codex AI 루프 엔지니어링 설계 — 상태 전이

참고: OpenAI Codex 활용 사례

유사 문제 대응 기준

나중에 같은 증상을 다시 만나지 않으려고 문서에 적힌 기준으로 구현을 한 번 더 정리했다.

에이전트 활용 자료를 다시 읽으며 workflow와 agent를 먼저 구분했다. 순서와 분기가 정해진 일은 workflow로 고정하고, 탐색이 필요한 부분만 도구 선택을 맡기는 편이 결과를 비교하기 쉽다. 저장소 작업도 격리된 환경, 명시적 권한, 실행한 테스트와 diff가 함께 있어야 검토 가능한 변경이 된다.

하네스는 지시문 모음보다 입력 범위, 허용 도구, 중단 조건, 증거 형식을 코드와 문서로 고정하는 층에 가깝다.

다음에 Codex AI 하네스 엔지니어링 설계 6 — 검증 체계 같은 문제를 보면 아래 순서부터 확인하려고 한다.

  • 읽기·수정·실행·배포 권한 구분
  • 작업마다 허용한 파일과 도구 범위
  • diff·테스트·실행 화면 증거
  • 반복 상한과 사람에게 돌려줄 조건

성공 문장보다 실제 diff·테스트 출력·배포 화면을 우선하고, 쓰기·배포·비밀 접근은 별도 권한 경계로 남겨야 한다.

공식 참고 자료