만들면서 배운 것

리포트가 숫자를 틀렸는데, 잡아낸 것도 같은 AI 팀이었습니다 🔍

생각에 잠긴 초록이 아빠

돈독(제가 혼자 만드는 자산관리 앱, https://don-doc.com )을 매일 점검하는 AI 에이전트가 있습니다. 코드가 잘 도는지, 보안 구멍은 없는지, 테스트가 잘 커버되는지 매일 리포트를 씁니다. 그런데 이번 주, 그 리포트 자신이 숫자 하나를 틀렸다는 걸 다른 에이전트가 잡아냈습니다. 그리고 같은 라운드에서, 넉 달째 아무도 자기 것으로 등록하지 않은 채 흘러가던 버그 하나도 다시 떠올랐습니다.

병합 승인만 기다리는 브랜치 세 개

9월 5일 오후 3시 3분부터 10분 사이, 로컬에 브랜치 세 개가 조용히 생겼습니다. 각각 대시보드·자산현황 화면의 중복 계산 로직 통합, API 라우트 20곳의 에러 메시지 노출 정리, 무인증 라우트 4곳의 설계 의도 문서화를 끝낸 브랜치였습니다. 다음 날(9월 6일) 점검 담당 에이전트가 diff를 전량 대조하고 병합을 권장했는데, 이틀이 지난 9월 7일에도 병합은 그대로 대기 중이었습니다.

리포트가 스스로 만든 숫자를 틀렸다는 걸 알아챈 순간 🔍

9월 6일 리포트는 이 중 하나(대시보드·자산현황 통합 브랜치)에 “테스트 10개 케이스를 새로 추가했다”고 적었습니다. 그런데 9월 7일, 기획 담당 에이전트가 원본 이슈 파일(issues/gated/issue-20260904-213435-dashboard-wealth-dup.md)을 직접 열어보고서야 숫자가 달랐다는 걸 확인했습니다. 새로 추가된 테스트는 19개, 전체 통과한 테스트는 318개였습니다. 개발 담당 에이전트도 같은 날 원본을 다시 대조해 이 정정을 확인했습니다.

10개와 19개, 거의 두 배 차이입니다. 원인은 단순해 보입니다. 리포트를 쓴 에이전트가 “새로 추가된 것”과 “기존에 있던 것”을 섞어 셌거나, 원본 파일을 직접 열지 않고 요약만 보고 옮겨 적은 것으로 보입니다. 다행히 이번엔 다음 라운드가 원본 파일을 직접 열어서 잡아냈습니다. 만약 아무도 원본을 다시 열어보지 않았다면, 틀린 숫자가 그대로 기록으로 굳었을 겁니다.

점검 리포트도 결국 누군가 요약한 결과물입니다. 숫자가 나오면, 한 번은 원본과 맞춰봐야 합니다.

넉 달째 표류한 버그 하나

같은 라운드에서 또 다른 게 나왔습니다. 로그아웃 라우트(app/api/auth/logout/route.ts 11~13번째 줄) 코드를 보면, 쿼리파라미터로 들어온 redirectTo 값을 검증 없이 그대로 리다이렉트 주소로 씁니다. 문제는 redirectTo에 절대 주소(예: https://다른사이트.com)를 넣으면, 원래 도메인이 무시되고 그 외부 주소로 그대로 넘어가버린다는 겁니다. 로그아웃 버튼을 눌렀는데 낯선 사이트로 튕기는 셈이죠.

이 문제는 사실 5월 29일 리포트가 처음 짚었던 것이었습니다. 그런데 그 뒤로 두 번, 다른 이슈(무인증 라우트 점검)를 처리하던 중에 “이건 지금 범위 밖”이라며 흘려보내졌습니다. 자기 이슈로 따로 등록된 적은 한 번도 없이, 넉 달 동안 “누군가의 담당”이 되지 못한 채 떠돌았던 겁니다. 이번에도 다른 작업(무인증 라우트 문서화)을 하던 중에 우연히 다시 눈에 띄었습니다.

삽질하다 멘붕한 초록이 아빠

다행히 실제 피해는 크지 않습니다. 로그아웃 라우트라 세션이나 데이터가 새는 건 아니고, 피싱에 신뢰를 얹어주는 정도의 위험입니다. 그래도 넉 달 동안 “내 담당 아님”이 반복됐다는 사실 자체가 걸립니다. 고치는 방법도 간단합니다. redirectTo가 /로 시작하고 //로는 시작하지 않는 내부 경로일 때만 허용하고, 아니면 로그인 화면으로 돌려보내면 됩니다.

실물 스샷 브랜치 병합 승인 후 npm test 실행 결과 터미널 화면 — "19개 신규 케이스, 318개 전체 통과" 문구가 보이는 지점


따라 하기

비슷하게 AI에게 코드 점검을 맡기고 있다면, 아래 두 가지는 직접 해보시길 권합니다.

1. 리포트 숫자를 원본과 대조하기

리포트가 “몇 개 추가했다”·“몇 건 고쳤다”처럼 숫자를 내놓으면, 그 숫자의 근거가 된 원본 파일을 한 번은 직접 열어봅니다.

grep -n "신규 케이스\|테스트 케이스" issues/gated/issue-<날짜>-<슬러그>.md
  • 이슈 파일에 리포트가 인용한 숫자의 원문이 있는지 먼저 찾습니다. 없으면 리포트가 요약 과정에서 숫자를 새로 만들어낸 것일 수 있습니다.
git show <브랜치>:<테스트파일경로> | grep -c "^\s*it("
  • 테스트 파일 자체에서 케이스 개수를 직접 세어봅니다. 리포트 숫자와 다르면, 리포트 쪽이 틀린 겁니다.

✅ 이렇게 되면 성공 — 원본 숫자와 리포트 숫자가 정확히 맞아떨어집니다. 안 맞으면 그 자리에서 정정하고 넘어가면 됩니다.

⚠️ 막히면 — 원본 이슈 파일이 어디 있는지 모르겠다면, 리포트에 파일 경로가 인용돼 있는지부터 확인하세요. 경로 인용이 없는 리포트는 애초에 대조가 안 되는 리포트입니다.

2. “범위 밖” 판정이 반복되는 이슈 찾기

같은 문제가 여러 리포트에 걸쳐 “이건 지금 안 본다”로 흘러간 적이 있는지 확인합니다.

grep -rl "범위 밖\|스코프 밖" agent-reports/ | xargs grep -B3 "범위 밖\|스코프 밖"
  • 과거 리포트들에서 “범위 밖” 판정이 어디에 얼마나 나오는지 한 번에 봅니다. 같은 항목이 두 번 이상 나오면, 그건 방치가 아니라 표류입니다.

✅ 이렇게 되면 성공 — 두 번 이상 나온 항목을 찾으면, 그 자리에서 바로 독립 이슈로 등록합니다.

⚠️ 막히면 — 리포트 문구가 매번 달라 grep으로 안 걸리면, 날짜순으로 훑어보며 같은 파일·같은 줄 번호가 반복 언급되는지 사람이 직접 확인하는 수밖에 없습니다.

배운 것

이번 주에 새로 배운 건 두 가지입니다. 하나는 AI가 만든 점검 리포트도 결국 숫자를 요약한 결과물이라, 한 번은 원본과 맞춰봐야 한다는 것. 다른 하나는 “이건 내 담당이 아니다”가 반복되는 게 방치가 아니라 표류의 신호라는 것 — 작은 문제일수록 자기 이슈로 등록해두지 않으면 몇 달이고 흘러갑니다.

다행인 건, 이번엔 둘 다 같은 팀 안에서 잡혔다는 겁니다. 숫자를 틀린 것도 AI였고, 원본을 다시 열어 정정한 것도, 표류하던 버그를 다시 찾아낸 것도 AI였습니다. 사람이 할 일은 그 사이에서 병합 버튼을 누르는 것뿐이었는데, 그마저도 이틀째 미뤄지고 있네요.

오늘도 한 걸음. 🐴

이 글은 산업 구조와 만드는 과정을 정리한 개인 기록입니다.
특정 종목의 매수·매도 추천이 아니며, 투자 판단과 그 결과는 독자 본인에게 있습니다.

← 글 목록으로