감시자를 만들었더니 봇 넷이 거짓말을 하고 있었다

지난 글에서 봇 하나가 36일 동안 거짓말한 이야기를 썼다. 그래서 감시봇을 만들었다. 매일 아침 8시 5분에 "봇들 잘 있냐"고 확인하고 텔레그램으로 보내주는 놈이다.
만들면서 원칙 두 개를 파일 맨 위에 적어놨다.
프로세스가 아니라 결과물을 본다. 문제가 없어도 매일 보낸다.
사흘 뒤 아침, 그 감시봇이 "전부 정상"이라고 보냈다.
전부 정상이 아니었다.
다섯 달
훈수로그봇이라는 게 있다. 글을 써서 블로그에 올리는 봇이다. 로그를 열어봤다.
[스케줄] 오늘 발송 시각: 21:31
[스케줄] 오늘 발송 시각: 14:26
[스케줄] 오늘 발송 시각: 18:16
[스케줄] 오늘 발송 시각: 10:05
매일 찍혀 있다. 오늘 몇 시에 보낼지 정하고 있다. 성실하다.
그런데 실제로 발행한 게 언제인지 보려고 레포를 열었다.
2026-04-14 blog: 오늘도 천천히 나아가는 나도봇 운영 일지
마지막으로 글이 올라간 게 4월 14일이었다. 그날이 9월 16일이었으니까 다섯 달이다.
더 있었다. 그 마지막 커밋조차 푸시가 안 돼 있었다. 내 노트북 안에만 있었다는 뜻이다.
## main...origin/main [ahead 1]
그리고 마지막으로, 봇이 성공했을 때 뱉는 주소를 직접 열어봤다.
404
그 도메인은 어느 시점엔가 롤토체스 정보 사이트로 바뀌어 있었다. 블로그가 아니었다. 그러니까 이 봇은 글이 뜰 곳이 없는 상태로 다섯 달을 성실하게 돌았다.
내가 만든 감시봇은 그동안 이 봇을 "정상"이라고 보고했다. 로그 파일이 매일 갱신됐으니까.
원칙 첫 줄에 프로세스가 아니라 결과물을 보라고 써놓고, 정작 이 봇은 로그 시각으로 확인하고 있었다. 내가 내 규칙을 안 지킨 자리였다.
보유 0
두 번째가 더 아팠다.
비트코인 매매 규칙을 확인해주는 봇이 있다. 매일 아침 계좌를 보고 지금 상태를 알려준다. 어제 보고는 이랬다.
보유 0.000000 BTC
진입 조건 아님
그런데 같이 찍히는 잔고 숫자가 며칠째 출렁이고 있었다. 아무것도 안 들고 있으면 잔고가 움직일 이유가 없는데.
계좌를 직접 조회해봤다.
포지션이 있었다. 비트코인 롱이 열려 있었다. 내가 이틀 전 저녁에 손으로 연 매매였고, 그건 내 판단이니까 문제가 아니다.
문제는 봇이 그걸 못 보고 있었다는 것이다.
원인은 한 줄이었다.
pos_instrument = pos.get("instrument", {})
응답을 열어보니 이렇게 생겼다.
{"position_info": {"instrument": {"underlying": "BTC"}, "qty": "..."}}
껍질이 한 겹 더 있었다. instrument를 맨 바깥에서 찾는데 실제로는 position_info 안에 들어 있다. 못 찾으니까 None을 돌려주고, 그러면 보유량이 0이 된다.
그래서 이렇게 된다.
if qty <= 0:
... # 진입 조건만 확인하고 끝
# 이 아래가 매도 규칙인데, 여기까지 절대 못 온다
등록해둔 분할 청산 규칙이 구조적으로 발동할 수 없는 상태였다. 몇 주 전에 "감으로 팔지 말자"고 규칙을 만들어 넣었는데, 그 규칙이 실행될 수 있는 경로가 없었다.
반대 방향이 더 무섭다. 매수 조건이 뜨면 봇은 아무것도 안 들고 있다고 믿는다. 그러면 내가 손으로 잡아둔 포지션 위에 또 산다.
그날 아침에도 감시봇은 이 봇을 정상이라고 보고했다. 로그가 갱신됐으니까.
열일곱에서 열셋으로
그날 오전 내내 이런 걸 찾았다.
훈수로그봇을 내렸다. 되살리려면 글이 뜰 주소부터 정해야 한다. 그게 안 정해지면 되살려도 또 허공에 쓴다.
비트코인 봇도 내렸다. 여기서 한 가지는 일부러 안 했다. 버그를 안 고쳤다. 고치면 매도 규칙이 살아나고, 그러면 내가 손으로 잡아둔 포지션에 봇이 개입한다. 포지션의 주인이 누구인지가 애매해지는 게 버그보다 나쁘다.
다른 조사용 봇 두 개도 정리했다. 열일곱 개에서 열세 개가 됐다.
감시 목록에서 뺄 때는 왜 뺐는지를 코드 안에 남겼다. 나중에 이 파일을 열었을 때 "이거 왜 없지?" 하고 다시 넣지 않도록.
그리고 오후에, 감시자가 꺼졌다
오후 늦게 서버에 접속이 안 됐다. 몇 번 두드려봐도 응답이 없었다.
yonghun-ui-macmini offline 보낸 바이트 9204 / 받은 바이트 0
내 쪽에서는 계속 신호를 보내는데 저쪽에서 한 바이트도 안 돌아온다. 나는 내가 오전에 띄운 컨테이너가 메모리를 먹어서 그런 줄 알았다. 몇 시간을 그렇게 의심했다.
정전이었다.
집에 전기가 나갔고, 서버가 그때 꺼진 거였다. 저녁에 다시 켰다. 그런데 켜졌는데도 봇이 하나도 안 올라왔다.
loginwindow 떠 있음
Dock / Finder 없음
/dev/console root
로그인 화면까지는 왔는데 아무도 로그인을 안 한 상태였다. 이 서버의 봇들은 화면에 로그인이 돼야 뜨는 구조라서, 원격으로는 올릴 방법이 없었다. 직접 로그인하고 나서야 열세 개가 한꺼번에 살아났다.
그러니까 이날 하루는 이렇게 흘렀다. 아침에 감시자가 거짓말쟁이 넷을 잡아냈고, 오후에 그 감시자가 아홉 시간 동안 꺼져 있었다. 그동안 아무 알림도 오지 않았다.
내가 감시봇 파일에 적어둔 두 번째 원칙이 이거였다.
조용한 걸 정상이라고 두면, 감시자가 죽었을 때도 똑같이 조용하다.
정확히 그 문장대로 됐다. 그것도 내가 그 문장을 쓴 지 사흘 만에.
남은 것
감시자는 결국 자기 자신을 못 본다. 다른 기계에서 봐주는 게 있어야 하는데, 아직 없다. 오늘 확인된 구멍이니까 적어만 두고 다음으로 넘긴다.
배운 걸 굳이 정리하자면 이런 것들이다.
로그가 찍힌다는 건 "코드가 거기까지 실행됐다"는 뜻이지 "일이 됐다"는 뜻이 아니다. 이걸 머리로는 알고 있었고 파일 맨 위에 적어두기까지 했는데도, 열네 개 중 열세 개를 로그 시각으로 확인하고 있었다.
그리고 봇이 자기 상태를 스스로 보고하게 두면 안 된다. 비트코인 봇은 자기가 뭘 들고 있는지 매일 보고했고, 그 보고가 틀렸다. 계좌를 직접 열어보기 전까지는 아무도 몰랐다.
만든 사람이 자기 규칙을 제일 먼저 어긴다. 두 번 연속 그랬다. 다음에 또 그럴 것 같아서 여기 적어둔다.