8월 4일 새벽, 봇이 밤새 한 일이 창고에 들어가기 37초 전에 멈췄습니다.

그런데 그날 화면은 전부 초록불이었습니다. 문제를 찾는 쪽은 멀쩡히 돌았고, 멈춘 건 그 목록을 받아 고치는 쪽이었습니다. 알림은 한 건도 오지 않았습니다.

여러분이 어딘가에 서류를 넣고 “접수됐습니다” 문자를 받은 뒤로 소식이 끊겼을 때도 마찬가지예요. 그게 진행 중인지 멈춰 있는지 알려 주는 장치는 대개 없거든요.

제 알림은 대부분 잘 됐을 때만 오게 되어 있었으니까요.

새벽 3시, 아무도 없는 자리
Photo: Julien Bachelet / Pexels

지난 두 편과는 결이 좀 다릅니다. 개발기⑫는 켜 둔 줄 알았던 감시가 쉬고 있던 이야기였고, 개발기⑬은 반대로 제대로 만들어져 있던 것 이야기였습니다.

오늘은 잘 만든 장치가 오히려 일을 망친 이야기입니다.

화면은 초록불인데, 결과물만 없었습니다

제 봇은 밤에 두 번 깨어납니다. 새벽 2시에 한 번, 새벽 3시에 한 번입니다.

앞의 것은 몸 상태를 점검하는 쪽입니다. 어디가 고장 났는지 훑어서 고칠 목록을 만들어 두고 잠듭니다. 뒤의 것은 그 목록을 받아 실제로 고치는 쪽이고요.

8월 4일 새벽은 이랬습니다.

그날 새벽의 시간표
머니노트 · 정보·교육·참고용
표로 보기
점검은 성공했고 수리는 증발했습니다
시점 사건 설명
02시 00분 점검 시작 몸 상태 훑기
02시 21분 점검 정상 종료 고칠 목록 1건 작성
03시 00분 수리 시작 목록을 받아 감
03시 30분 **강제 종료** 기록 파일 177바이트 · 알림 0건

점검 쪽은 21분을 돌고 정상적으로 끝났습니다. 고칠 항목도 한 건 찾아서 인수인계 쪽지에 적어 뒀고요.

그 쪽지를 수리 쪽이 가져가면 읽었다는 표시가 남습니다. 그날 그 표시가 비어 있었습니다.

남은 증거는 이게 전부였습니다

다음 날 제가 본 기록 파일은 이랬습니다.

기록 파일에 남은 것
머니노트 · 정보·교육·참고용

종료 번호 143은 스스로 잘못돼서 죽은 게 아니라 누가 밖에서 껐다는 뜻입니다.

껐다면 누가 껐을까요. 로그엔 안 적혀 있어서 저는 번호만 보고 짐작해야 했습니다. 제가 붙여 둔 감시 장치였을 겁니다.

30분이 지나도 안 끝나면 먹통이라고 보고 강제로 끄도록 만들어 뒀거든요. 무한정 매달려 컴퓨터를 붙잡고 있는 걸 막으려던 장치였죠.

그래서 이때까지 제 결론은 이랬습니다. “수리 쪽이 먹통이 됐고, 감시 장치가 제 역할을 했다.”

틀렸습니다.

죽은 자리에 산출물이 있었습니다

기록 파일에 아무것도 없으니 다른 데를 봤습니다. 파일이 언제 마지막으로 바뀌었는지를 본 겁니다.

컴퓨터는 파일을 건드릴 때마다 그 시각을 몰래 적어 둡니다. 쉽게 말하면 기록 파일이 비어 있어도 발자국은 남는다는 뜻입니다.

새벽 3시부터 3시 35분 사이에 바뀐 파일을 훑었더니 정확히 두 개가 나왔습니다.

죽기 직전까지 손이 움직이고 있었습니다
Photo: Daniil Komov / Pexels

하나는 그날 고치기로 한 바로 그 코드였고, 다른 하나는 그게 제대로 고쳐졌는지 확인하는 검사 파일이었어요.

마지막 발자국과 종료 시각의 거리
머니노트 · 정보·교육·참고용
표로 보기
먹통이 아니라 일하는 중이었습니다
항목 설명
마지막 파일 저장 → 강제 종료 37초 이만큼을 못 버텼습니다
그날 고쳐 놓은 코드 분량 257줄 저장 완료
검사 파일 크기 39KB 저장 완료

37초입니다.

다 만들어 놓고 창고에 넣기 직전에 꺼진 거죠. 마지막 한 칸을 못 채웠으니 인수인계 쪽지도 못 읽었다고 표시됐고, 그날의 자동 수리는 거기서 끊겼습니다.

만들어 둔 것 자체가 사라진 건 아닙니다. 그날 저녁, 작업 폴더에 남아 있던 그 파일들을 찾아내 다시 검증하고 창고에 넣었습니다. 다만 그건 자동으로 된 게 아니라 사람이 뒤져서 찾아낸 것이에요. 안 찾았으면 그대로 묻혔겠죠.

물론 “그럼 감시 장치를 없애면 되지 않나요?”라고 하실 수 있습니다. 그런데 그러면 진짜 먹통이 됐을 때 밤새 매달리게 되죠. 장치가 잘못된 게 아니라 판단 기준이 잘못된 것이었습니다.

엿새 전에도 같은 일이 있었습니다

여기서 더 서늘한 게 나왔습니다.

같은 모양의 기록이 과거에 또 있는지 훑어봤거든요. 7월 29일 것이 바이트 단위로 똑같았습니다.

두 사건과 진짜 먹통의 차이
머니노트 · 정보·교육·참고용
표로 보기
세 값이 완전히 똑같아서 구별이 안 됐습니다
재던 값 7월 29일 8월 4일 진짜 먹통이라면
종료 번호 143 143 143
걸린 시간 30분 30분 30분
기록 파일 크기 177바이트 177바이트 177바이트
바뀐 파일 여러 개 2개 0개
이 값이 뜻하는 것 일하는 중 일하는 중 먹통일 것

그날도 일하는 중이었습니다. 다만 그때는 만든 것을 이미 창고에 넣은 뒤라 잃은 게 없었어요.

그래서 더 아무도 몰랐습니다. 그 기록은 엿새 동안 그 자리에 그대로 있었고, 저도 안 봤습니다.

안 열어 본 채 쌓입니다
Photo: Sam J / Pexels

한 번이면 사고지만 두 번이면 구조잖아요. 제가 그걸 몰랐던 이유는 단순합니다. 찾아보질 않았거든요. 알림이 안 왔으니 아무 일도 없다고 생각한 겁니다.

그래서 처방을 반대로 바꿨습니다

처음 제 처방은 이랬습니다. “기록 파일이 5분 동안 안 늘어나면 먹통으로 보고 끄자.”

이것도 틀렸습니다.

두 사건 모두 기록 파일이 177바이트에서 한 바이트도 안 늘었는데 둘 다 일하는 중이었습니다. 봇이 쓰는 도구가 중간중간 보고하지 않고 끝날 때 한 번에 몰아서 쓰기 때문이거든요.

바꿔 말하면 이 상황에서 “조용하면 먹통”이라는 기준은 정상을 먹통으로 부르는 기준이었습니다.

기준을 어떻게 바꿨나
머니노트 · 정보·교육·참고용
표로 보기
끄는 대신 재기만 하기로 했습니다
단계 내용 설명
1단계 조용하면 끈다 처음 처방 — 정상 작업을 죽입니다
2단계 조용하면 기록만 남긴다 끄지 않습니다. 얼마나 자주 헛짚는지부터 셉니다
3단계 정상 종료면 알림을 참는다 조용했어도 잘 끝났으면 헛짚은 걸로 셉니다
4단계 **발자국을 같이 적는다** 바뀐 파일이 몇 개인지 · 마지막이 언제인지
5단계 쪽지가 안 읽혔으면 알린다 이 한 줄만 있었어도 그날 바로 드러납니다

마지막 줄이 이 수리의 심장입니다. 앞의 것들이 다 없어도 쪽지가 안 읽힌 채 남아 있는지만 보면 그날 무슨 일이 있었는지 드러나거든요.

단, 여기까지는 기록에 남긴다는 뜻입니다. 그게 제 손에 도착하는 건 또 다른 문제였고, 그 이야기는 조금 뒤에 나옵니다.

이틀 뒤 새벽, 같은 일이 또 일어났습니다

8월 5일 새벽은 조용히 지나갔습니다. 60초 만에 정상 종료됐고 할 일도 없었고요.

그런데 오늘 새벽, 8월 6일 3시 30분에 또 강제 종료됐습니다.

이번엔 기록이 달랐습니다.

오늘 새벽 기록에 남은 것
머니노트 · 정보·교육·참고용

이틀 전에는 제가 파일 시각을 하나하나 뒤져서 알아낸 사실이었는데, 오늘은 기록이 스스로 말해 줬습니다.

“조용했지만 끄지 않았다”는 줄도 남았고 “누가 껐다”는 줄도 남았어요. 예전엔 이 줄조차 안 남았습니다. 감시 장치가 자기가 껐다고 적기 전에 자기도 같이 정리돼 버렸기 때문입니다.

그런데 마지막 한 칸이 비어 있었습니다

솔직하게 적어야 할 게 있습니다.

오늘 새벽 기록의 맨 마지막 줄은 이랬습니다.

실패 알림 발송 실패.

실패를 감지하는 데까지는 성공했는데, 그걸 저한테 보내는 마지막 단계에서 또 걸린 겁니다. 결국 오늘도 알림은 안 왔고, 저는 아침에 기록을 열어 보고서야 알았습니다.

오해하지 마세요. 이건 수리가 헛일이었다는 이야기가 아닙니다. 이틀 전엔 제가 파일 시각을 하나하나 뒤져야 알 수 있던 걸, 오늘은 기록이 그 자리에서 말해 줬습니다. 다만 아직 “저절로 알게 되는” 상태는 아니고, 그래서 이 편은 “고쳤습니다”로 못 닫습니다.

원인은 아직 확인 중입니다. 확인되면 그때 적겠습니다.

성공은 알림이 오는데, 실패는 오지 않습니다

여기까지가 봇 이야기입니다. 제가 이 일에서 제일 오래 붙잡고 있던 생각은 따로 있습니다.

제 알림은 처음부터 잘 됐을 때만 오게 만들어져 있었습니다.

일부러 그런 게 아닙니다. 만들 때는 성공하는 경로를 먼저 만들잖아요. 실패하는 경로는 “그럴 일이 없을 것”이라 생각하고 나중으로 미룹니다. 그러다 보면 실패는 조용한 게 기본값이 됩니다.

어느 쪽에 연락이 오나
머니노트 · 정보·교육·참고용
표로 보기
우리가 연락받는 건 대개 한쪽뿐입니다
상황 잘 됐을 때 중간에 끊겼을 때
자동이체 문자 옴 대개 옴
보험금 청구 지급 문자 옴 보완 안내가 오기도 · 안 오기도
민원·신청 접수 접수 문자 옴 처리가 멈춰도 조용한 경우가 있음
내가 아는 방법 기다리면 됨 직접 열어 봐야 함

자동이체처럼 은행이 챙기는 것들은 실패해도 대개 문자가 옵니다. 그건 잘 만들어진 쪽이죠.

문제는 여러 단계를 거치는 일입니다. 내가 서류를 넣고, 그게 다음 부서로 넘어가고, 거기서 다시 심사로 가는 일들이요.

접수됐다는 문자 뒤로 아무 연락이 없을 때
Photo: Andrea Piacquadio / Pexels

이때 각 단계는 자기가 끝냈다는 것만 알립니다. 그런데 2단계가 3단계로 못 넘겼다는 건 어느 쪽 알림에도 안 들어가 있기 쉽습니다.

그럼 저는 어떻게 될까요. 접수 문자를 받았으니 “진행 중”이라고 믿고 기다립니다. 기한이 지나고 나서야 확인해 보면 그제서야 거기서 멈춰 있었다는 걸 알게 됩니다. 그러니까 이런 겁니다 — 제 돈이나 제 권리가 그 사이 그냥 시간만 보낸 거예요.

제 봇이 엿새를 조용히 보낸 것과 똑같은 구조입니다.

오늘 남은 문장

아무 연락이 없다는 건 잘 되고 있다는 뜻이 아닙니다.

연락이 오게 만들어져 있어야 연락이 옵니다. 그리고 대부분의 시스템은 잘 됐을 때만 연락하도록 만들어져 있습니다. 만든 사람 입장에서 그게 훨씬 쉽거든요.

제가 이번에 배운 건 이겁니다. 조용한 걸 정상으로 읽지 말자. 기록이 비었으면 아무 일도 없었던 게 아니라, 볼 자리를 잘못 보고 있는 것일 수 있습니다.

하나 더 있습니다. 제 감시 장치는 나쁜 장치가 아니었습니다. 재는 자가 하나뿐이라 정상과 고장을 구별 못 했을 뿐입니다. 발자국 한 줄을 같이 재기 시작하니 그 자리에서 갈렸죠.

지금 “접수됐습니다” 문자만 받고 그 뒤로 아무 연락이 없는 것이 하나라도 있으신가요? 그게 진행 중인지 멈춰 있는지, 여러분은 어느 쪽으로 알고 계셨나요? 저는 엿새 동안 아무 일도 없었다고 믿고 있었습니다.

다음 글 예고 — 검사를 통과하도록 만들어 두는 여섯 가지 방법

이 이야기에는 더 불편한 뒷장이 있습니다.

수리가 끝나면 검사를 돌립니다. 그런데 그 검사가 통과하도록 만들어져 있으면 어떻게 될까요. 실제로 제 검사 중에 스위치를 꺼 둔 채로 내보내도 전부 초록불이 나오는 것이 있었습니다. 검사가 검사 대상을 비켜 가고 있었습니다.

그걸 찾아낸 건 제가 아니라 다른 AI였습니다.


※ 이 글은 자동매매 시스템을 만들며 겪은 과정을 기록한 개발기입니다. 특정 종목이나 매매 방법을 권유하지 않으며, 본문의 기록은 실제 돈이 오가지 않는 모의계좌·개발 환경에서 일어난 일입니다. 보험·민원 처리 절차는 기관과 상품에 따라 다르므로 개별 사안은 해당 기관에 확인하셔야 합니다. 투자 판단과 그 책임은 본인에게 있습니다. 정보·교육·참고용으로만 봐 주세요.