ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • '위험 낮음' 더미에서 치명 결함 아홉 개가 나왔다
    AI Agent 2026. 7. 19. 09:00
    728x90
    반응형

    늦은 밤 책상 위 식은 커피와 닫힌 노트북 사진
    '위험 낮음' 더미에서 치명 결함 아홉 개가 나왔다

    초록불을 보면서 좀 으쓱했습니다.
    들어온 수정 다섯 건을 1차로 끝낸 에이전트가, 스스로 '적대적 자문자답'까지 돌렸거든요.
    자기가 고친 코드를 자기가 공격해보고, 무너지나 보고, 그러고 나서 건마다 위험도를 매겼습니다.
    거의 다 '위험 낮음', 한두 개만 '보통'.
    그럴듯했습니다.
    검토를 안 한 게 아니라, 평소보다 더 빡세게 한 거니까요.
    다섯 건 모두 코드 수정이 끝났고, 자체 결론은 "이대로 나가도 됨"이었습니다.
    화면 가득 찍힌 초록 글자들을 위에서 아래로 한 번 훑고, 마우스 휠을 끝까지 내려봐도 빨간 줄 하나 안 보였습니다.
    닫아도 되겠다, 그렇게 손이 거의 창을 닫고 있었어요.

    형식적인 절차라고 생각했습니다

    습관처럼, '위험 낮음'으로 닫힌 것들에 별도 검토자를 하나 더 붙였습니다.
    같은 코드, 다른 주체.
    작성자랑 맥락을 공유하지 않은 쪽으로요.
    솔직히 도장 한 번 더 찍는 절차라고 생각했어요.
    이미 본인이 공격까지 해본 코드를, 새 눈이 뭘 더 찾겠나 싶었거든요.
    어려운 수정이라 그냥 관례대로 2단계를 밟은 거지, 뭐가 나올 거라곤 기대하지 않았습니다.

    처음엔 검토자가 너무 천천히 가서 답답하기도 했습니다.
    1차 에이전트는 몇 분 만에 다섯 건을 다 닫았는데, 이쪽은 한 건을 붙들고 한참을 안 움직였거든요.
    그냥 같은 결론을 느리게 다시 내려고 시간만 쓰는 줄 알았습니다.
    한 번은 중간에 끊고 "결론만 빨리" 시킬까 손이 갔는데, 그러지 않고 그냥 뒀어요.

    검토자는 자문자답을 안 했습니다.
    대신 파일을 가로질러 가며 이 함수가 어디서 불리는지, 그게 또 어디로 흘러가는지 호출 경로를 따라갔습니다.
    한 파일 안에서는 멀쩡하던 수정이, 세 파일 건너에서 다른 코드가 깔고 있던 전제를 조용히 깨고 있었습니다.
    데이터가 한 번에 같은 항목이 두 번 들어올 수 있다는 가정의 빈틈, 토큰을 보존하지 않고 큐를 비우면 복구가 막히는 경로, 순서가 어긋나는 지점들.
    전부 한 파일만 들여다봐선 안 보이는 것들이었어요.

    '위험 낮음' 더미에서 아홉 개가 나왔습니다

    한두 개가 아니었습니다.
    치명 결함이 아홉 개.
    한 묶음에서 셋, 다른 묶음에서 여섯.
    그중 둘은 ship blocker였습니다.
    그대로 나갔으면 배포 자체를 막아야 했을 결함이요.
    검토표엔 그냥 "문제 있음"이 아니라 blocker, fix-before-merge, note 세 칸으로 갈라 적혀 있었습니다.
    그 셋을 보고서야 제가 뭘 오늘 막아야 하고, 뭘 나중에 정리해도 되는지 겨우 분리할 수 있었어요.

    여기서 등이 서늘했습니다.
    화는 안 났는데, 좀 무서웠어요.
    에이전트가 거짓말을 한 게 아니거든요.
    게을렀던 것도 아니고.
    자기가 본 범위 안에서는, '위험 낮음'이 정직한 결론이었습니다.
    결함은 전부 그 범위 바깥, 파일을 넘어가는 경로 위에 있었어요.
    자기 코드를 짠 쪽의 시야는 딱 자기가 의식한 그 모양으로만 작동합니다.
    자기가 안 보이게 짠 걸, 자기가 다시 본다고 보일 리가 없었던 겁니다.
    공격하는 나도, 방어하는 나도, 그 함수가 세 파일 건너 무엇과 엮이는지 모른다는 점에선 똑같았으니까요.
    아까 답답하다고 끊을 뻔했던 그 느린 걸음이, 사실은 내가 한 번도 안 걸어본 경로를 짚고 있던 거였습니다.

    검토도 한 번에 깔끔하게 끝나지 않았습니다

    여기까지면 "외부 검토가 자체 검토를 이겼다"는 깔끔한 이야기인데, 실제로는 그렇게 안 흘러갔습니다.
    외부 검토를 돌리던 도구가 검토 도중 세션이 만료돼서 죽어버렸어요.
    한참을 잘 따라가다가, 갑자기 화면이 멈추고 로그인 다시 하라는 메시지만 뱉고요.
    절반쯤 나온 결함 목록을 버려야 하나 잠깐 망설였습니다.
    그래서 같은 검토 지시를 다른 일꾼한테 그대로 넘겨서 처음부터 다시 돌렸습니다.
    우월한 도구가 따로 있어서 아홉 개를 잡은 게 아니었어요.
    지시만 정확하면 평범한 쪽도 똑같이 잡더군요.

    게다가 그 더미 안엔 헛발질도 섞여 있었습니다.
    검토자가 "테스트가 0건"이라고 빨간불을 켰는데, 사실은 다른 일꾼이 이미 회귀 테스트를 한 묶음 추가해둔 뒤였어요.
    검토자가 그걸 못 본 채로 본 거죠.
    진짜 결함 아홉 개와 가짜 경보 한 개가 같은 리포트에 나란히 찍혀 있었고, 어느 게 진짜인지는 결국 사람이 다시 가려야 했습니다.
    검토를 붙인다고 끝이 아니라, 검토 결과를 또 검토해야 했던 거예요.

    다음 묶음도 또 초록불일 겁니다

    결국 아홉 개를 다 뿌리째 고치긴 했습니다.
    막힌 경로엔 복구 장치까지 새로 달았고요.
    그런데 그날 손에 남은 건 "다 해결했다"는 후련함이 아니라, 메모 한 줄이었습니다.
    어려운 수정엔 무조건 작성자 말고 별도 검토자를 붙인다, 검토자한테는 칭찬하지 말고 비판하라고, ship blocker와 그냥 권고를 갈라서 말하라고 시킨다 — 그걸 다음에도 안 까먹게 prompt 기본값에 박아두는 일.

    자신만만하게 닫힌 묶음이 제일 의심스럽다는 걸, 그 더미를 보고서야 받아들였습니다.
    검토는 같은 머리로 두 번 하는 게 아니라 다른 맥락을 가진 주체가 한 번 더 하는 일이라는 것도요.
    그런데 그 별도 검토자도 한 번 죽었고, 한 번은 헛발질을 했습니다.
    그러면 그 검토자는 또 누가 검토하나.
    그 줄이 어디서 끊기는지는 아직 모르겠습니다.
    다음 묶음도 또 초록불일 겁니다.
    이번엔 그 초록불을 안 믿는 채로, 누가 검토할지부터 정해놓고 시작합니다.

    728x90
    반응형
Designed by Tistory.