죽으면 누가 아픈가 — 구조를 다시 짠 한 주

자동매매 봇의 trader/desk 프로세스 분리, 코드 0줄 재작성 프로젝트의 커밋 전 문서 위생, 그리고 49일 된 launchd 상주 체제의 전면 철거

하려던 것

이번 주는 코드보다 구조를 만졌다. 사건 세 개가 겹쳤다.

첫째, 자동매매 봇이 커졌다. 스케줄러 잡 49개, 테이블 37개인데 계좌를 만지는 잡은 6개뿐. 목표인 “20영업일 무배포”를 켜려면, 화면 한 줄 고칠 때마다 매매 데몬까지 재시작되는 구조(8월에만 66번)부터 갈라야 했다.

둘째, 자동매매 봇의 경험을 오픈소스로 다시 쓰는 재작성 프로젝트. 코드는 0줄 — src 아래는 전부 .gitkeep이고 설계 문서 12개와 결정 로그 19건이 전부다. 개명하며 히스토리를 버리고 git init을 새로 해 커밋도 0개. 첫 커밋이 될 문서들을 점검하는 게 일이었다.

셋째는 계획에 없었다. 토요일 오후, 맥미니에서 49일째 돌던 launchd 상주 체제를 걷어내기로 했다.

어떻게 시켰나

분리는 ADR부터 썼다. 기존 “단일 데몬” ADR을 개정하며 결합의 실측치를 표로 만들게 했다 — 화면 커밋이 매매 데몬을 재시작시키고, 관찰용 마이그레이션 하나가 실패하면 매매 데몬이 안 뜬다. 기준은 한 문장, 죽으면 누가 아픈가. 계좌·주문·손실 한도를 만지면 trader, 아니면 desk. 레포도 이미지도 하나, 환경변수로 역할만 갈린다. trader는 마이그레이션도 HTTP 포트도 없이 배포 동결 대상, desk는 매일 배포해도 매매 문이 안 닫힌다.

재작성 프로젝트에는 커밋 전 감사를 돌렸다. 새 이름은 PyPI·npm에서 비어 있는지 당일 실측해 결정 근거로 남기게 했고, “공개 레포에 남으면 안 되는 것”을 렌즈로 에이전트 감사를 시켰다.

철거 지시는 한 줄이었다.

자동으로 띄우는 거 다 삭제하고 launchctl도 언로드하고 삭제해

어디서 막혔나

분리 중 유령 잡이 나왔다. 새벽 재기동 잡이 35일간 한 번도 안 돌았다. sys.exit(0)을 워커 스레드 안에서 불러 잡 러너가 SystemExit을 삼키고 있었던 것. 그동안 아무 문제가 없었고, 배포마다 새 컨테이너가 뜨는 환경이라 상태 리셋 자체가 무의미했다. 고치는 대신 제거했다.

재작성 쪽은 결정 로그 한 줄이 문제였다. 이건 커밋에 남기면 안 되겠다고 걸었더니, Claude가 그 한 줄이 공개 히스토리에서 드러낼 사실을 분해해 보여줬다 — 저자에게 고용 관계가 있다는 것, 개인 프로젝트를 회사와 분리하는 비공개 정책 문서를 운영한다는 것까지. 중립 재작성을 시켰다. “사장” 27회를 “저자”로, 로컬 경로는 git 미추적 파일로, 옛 이름 흔적 0건. 감사를 한 번 더 돌리자 유료 웹서비스를 전제하던 시절의 세계관이 50건 더 나왔다. 문서가 깨끗해진 다음 물었다.

지금 문서로 금융 전문 AI 에이전트를 만들 수 있겠어?

에이전트 셋에게 이 문서만 주고 첫 마일스톤 구현을 시뮬레이션시켰다. 판정은 “못 만든다” — “무엇을 왜”는 상급인데 “어떻게”가 비어서, 다섯 단계 중 완주 가능한 단계가 0개였다.

철거에서는 Claude가 방아쇠를 못 당겼다. launchctl이 권한 분류기에 막혀 plist 파일까지만 만질 수 있었다. 대신 범위부터 표로 갈라 왔다 — 자기가 만든 14개(레포 상주 12+모니터+로그 로테이트)만, 남의 plist와 텔레그램 봇·리포트 서버는 제외. 붙어 있던 원격 세션의 미커밋 작업이 고아 worktree로 남는다는 경고도 딸려 왔다.

결과

분리는 일요일에 끝났다. trader 잡 23개, desk 잡 27개 — 원래 49개에 헬스체크 중복 1. watch path도 갈라 관찰 커밋이 trader를 재시작하지 않는 것까지 확인했다. 이제 배포 동결 카운트를 시작할 수 있다.

재작성 프로젝트는 토요일 밤, 시뮬레이션이 짚은 구멍을 메우는 딥다이브로 이어졌다. 첫 커밋은 여전히 코드가 아니라 문서가 될 것이다.

철거는 Claude가 써준 스크립트를 저녁에 직접 실행했다. 순서가 요점 — plist 14개 백업, unload 먼저(안 그러면 KeepAlive가 계속 살린다), 그것도 1초 간격 순차, 삭제 후 잔존 검증. 로그와 래퍼 스크립트는 되살릴 여지로 남겼다. 세울 때는 로그인을, 걷을 때는 launchctl을 사람이 눌렀다. 40분 만에 세운 체제가 49일 만에 내려갔고, 백업 폴더에 plist 14개가 남았다. 그중 막내는 사흘 전 추가한 재작성 프로젝트의 것이었다.

배운 점