AI 사용기
AI 활용기: 리뷰마다 다른 결함이 나온 무인 자동화, 원인은 네 가지였다
사람이 안 보는 예약 자동화 허브를 만들면서 코드 리뷰를 세 번 돌렸는데 그때마다 Critical이 나왔다. 실제 결함 네 가지와 그걸 고친 커밋, 그리고 크론잡 운영 커뮤니티가 이미 정리해둔 원칙 중 어디까지가 겹치는지 확인했다.
사람이 지켜보지 않는 예약 자동화(크론·스케줄 에이전트)를 설계하는 사람에게, 기능이 동작하는 것과 무인으로 안전하게 도는 것이 왜 다른 문제인지 실제 결함 목록으로 보여준다.
무인 예약 실행 허브를 만들고 코드 리뷰를 세 차례 받았는데 매번 Critical이 나왔다. 실제 결함은 네 가지였다 — 허브의 지금 실행 요청과 정규 예약 슬롯이 겹쳐 같은 작업이 두 번 도는 문제, 껐다 켠 작업이 지나간 예약 슬롯을 뒤늦게 발사하는 문제, 커밋을 만드는 점검 작업이 저장소가 깨끗한지 확인하지 않고 도는 문제, 감사 작업이 만든 커밋을 과도 차단 시 자동으로 되돌리는 장치가 그 감사 실행 자체가 만든 범위 밖의 커밋까지 되돌릴 수 있던 문제. 메모에 남긴 교훈은 이 넷을 '두 번 돈다·조용히 안 돈다·남의 변경을 먹는다' 세 축으로 정리했다. 참고한 두 크론잡 운영 자료는 앞의 두 축(멱등성, 마지막 성공 감시·데드맨 스위치)은 다루지만, 세 번째 축인 '남의 변경을 먹는다'는 다루지 않았다.
무인 예약 자동화를 만들 때는 멱등성(겹쳐 돌아도 안전한가)과 실패 가시성(조용히 안 죽는가)만으로 끝내지 말고, 같은 저장소·같은 자원을 건드리는 다른 무인 작업의 변경을 침범하지 않는지도 별도 시나리오로 점검한다.
먼저 답하면
사람이 지켜보지 않는 예약 자동화 허브를 만들고 코드 리뷰를 세 번 받았는데, 세 번 모두 Critical 결함이 나왔다. 실제로는 네 가지 문제였고, 메모에는 이 넷을 “두 번 돈다 / 조용히 안 돈다 / 남의 변경을 먹는다” 세 축으로 정리해뒀다.
재현 방법
여러 개의 개별 파이프라인(영상 제작, 앱 제작, 게임 제작, 블로그 발행, 웹 도구 제작)을 각자 스케줄러로 따로 돌리던 걸, 하나의 허브가 일괄 예약·실행·감사하도록 묶는 작업이었다. 결과를 사람이 실시간으로 보지 않는 게 전제라 “일단 동작한다”로는 부족하다고 판단해 코드 리뷰를 요청했는데, 세 차례 모두 Critical 등급 결함이 나왔다.
실제로 지적된 결함은 네 가지였다.
- 지금 실행 요청과 정규 슬롯의 이중 실행. 허브에는
bin/hub run으로 작업을 즉시 돌리는 명령이 있는데, 그 직후에 같은 작업의 정규 예약 시각이 겹치면 스케줄러가 같은 작업을 또 발사할 수 있었다. - 껐다 켠 작업의 지연 슬롯 발사. 잠시 꺼뒀다 다시 켠 작업이 그동안 지나간 예약 슬롯을 뒤늦게 발사하는 경우가 있었다.
- 커밋하는 점검 작업의 청결 미검사. 저장소에 커밋을 남기는 점검 작업이 실행 전에 저장소가 깨끗한 상태인지 확인하지 않고 돌았다.
- 감사 되돌림의 범위 미지정. 주간 감사 작업(factory-audit)은 게이트 설정을 바꾸는 커밋을 직접 남기고, 그 감사가 계속 과도하게 차단한다고 판단되면 허브가 감사 커밋을 자동으로 되돌리는 장치가 있었다. 이 되돌림이 검증 범위를 그 감사 실행이 실제로 만든 구간으로 한정하지 않아서, 다른 작업이 그사이 만든 커밋까지 되돌릴 수 있었다.
검증 결과
1, 3, 4번은 실제로 커밋 메시지에 남은 수정으로 확인된다.
- 1번은 지금 실행 요청이 대신 소비한 정규 슬롯을 실행 기록에 남기도록 고쳐서, 스케줄러가 “이미 처리됐다”고 판단하게 만들었다.
- 3번은 커밋을 만드는 작업 전부에 저장소 청결 사전 확인을 강제 조건으로 걸었다(
require_clean). - 4번은 되돌림의 사후 검증 범위를 “그 실행이 시작한 시점부터 끝난 시점까지(start_head..HEAD)“로 한정해서, 그 범위 밖의 커밋은 건드리지 않도록 했다.
2번(껐다 켠 작업의 지연 슬롯 발사)이 정확히 어떤 커밋으로, 어떻게 고쳐졌는지는 커밋 메시지만으로는 특정하지 못했다 — 메모에는 결함 목록에만 남아 있다.
한계와 다음 개선
정리하다가 크론잡 운영을 다루는 글을 찾아봤다. “Idempotent Cron Jobs are Operable Cron Jobs”(Robust Perception)는 여러 번 겹쳐 돌거나 재시도돼도 결과가 같아야 한다는 멱등성과, “최근에 정상적으로 끝났는가”를 모니터링해 실패를 놓치지 않는 방법을 다룬다. CronGuard의 “12 Cron Job Best Practices”는 하나의 느린 작업이 자기 자신과 겹쳐 쌓이지 않도록 막는 락과, 제대로 돌았는지 알리는 데드맨 스위치를 제시한다. 이 두 자료는 메모가 말한 “두 번 돈다”(멱등성)와 “조용히 안 돈다”(마지막 성공 감시·데드맨 스위치) 축과 맞닿아 있다.
하지만 세 번째 축인 “남의 변경을 먹는다” — 서로 다른 무인 작업(커밋하는 점검 작업과 감사 작업)이 같은 저장소를 함께 건드리다 한쪽이 다른 쪽의 변경을 침범하는 문제 — 는 두 자료 어디에도 없었다. Robust Perception 글은 이 주제를 아예 다루지 않고, CronGuard의 락도 “느린 작업 하나가 자기 자신과 겹치는” 경우를 막는 것이지 서로 다른 작업 간의 충돌을 다루지는 않는다. 이 부분은 참고한 두 자료 밖의 문제였고, 실제로 겪은 결함과 그 결함을 고친 커밋을 통해서만 확인할 수 있었다.