설계는 한 장에 들어갔어
Master Chief는 2026-10-07에 커밋 하나로 태어났어. 파일 42개, 추가된 줄 1,210줄, 그리고 72줄짜리 설계 문서. 아이디어는 그 72줄에 다 들어 있었어. 모든 문이 찾아가는 이름 붙은 대화 하나. 기기들이 차례를 지키게 하는 공정한 잠금. 비공개 턴과 워커 턴은 문 앞에서 거절. 보고는 출처를 달고 덧붙이기. 브레인 경로는 전부 같은 방식으로 감싸기. 문서가 올라온 날 읽었으면 너도 고개를 끄덕였을 거야. 나도 그랬으니까.
같은 날 처음부터 끝까지 훑는 리뷰가 한 번 지나갔어. 그 덕에 Chief는 이제 휴지통에 못 들어가고, 모든 클라이언트가 Chief를 표시하고, 아빠 기기의 시계가 턴에 실리고, 텔레그램은 자기가 보내지 않은 턴을 더는 따라 보내지 않게 됐어. 그런데 그 리뷰가 제일 큰 질문을 놓쳤고, 그 질문은 아빠가 던졌어. 마지막 턴이 없는 대화에서 끝없이 자라는 게 뭐냐고. 답은 거의 전부였어. 그래서 같은 날 커밋이 하나 더 들어갔어. 로그를 조각으로 나누고, 압축을 넣고, 대화 기록을 페이지로 끊고, 텔레그램 동기화는 버전 번호를 먼저 보게 했지.
그리고 2026-10-08, 구현 세션의 맥락을 전혀 모르는 별도 인스턴스가 콜드 리뷰를 했어. 아무것도 안 고치는 읽기 전용 리뷰였어. Master Chief가 내건 성질(끝나지 않는다, 모든 문이 들어온다, 늘 켜져 있다)에서 출발해서 실제 방을 쟀고, 쓰고 버릴 탐침 테스트를 다섯 개 썼어. 돌아온 지적은 열세 개. 그중 넷이 HIGH였어. 기존 Master Chief 테스트 파일에는 테스트가 21개 있었고, 전부 통과했어.
열세 개
| # | 무엇이 깨졌나 | 고친 방법, 한 줄로 |
|---|---|---|
| 1 (HIGH) | 비상 압축이 턴 잠금 안에서 돌았어. 긴 모델 요약 하나가 모든 문과 보고와 알림을 몇 분씩 붙잡을 수 있었어. Stop은 닿지도 못했고, 재시작하면 작업이 날아갔고, 요약기가 실패하면 재생본이 6.4배로 불었어. | 압축을 턴과 턴 사이로 옮겼어. 잠금 없이 요약하고, 재생본이 그새 안 바뀌었는지 확인한 다음 쓸 때만 잠그고, 비상시엔 모델 없이 만드는 다이제스트로 막아. |
| 2 (HIGH) | 재시작은 30초 유예를 약속해 놓고 1초쯤 만에 돌던 턴을 죽였어. 브라우저와 텔레그램에서 줄 서 있던 턴은 흔적도 없이 사라졌고. | 종료가 진짜 유예를 지켜. 기다리던 턴은 먼저 철회되면서 다시 보내라는 답을 받고, 턴 상태는 기다리는 턴을 pending으로 읽어. |
| 3 (HIGH) | 압박을 마지막에 말한 브레인의 창으로 쟀어. 314K 토큰 재생본이 Claude의 1M 기준으론 31%였는데 Codex 창은 272K라서, Codex는 끝내 구조받을 수가 없었어. | 대상 브레인의 창으로 재고, 공급자가 크기 때문에 거절하면 "가득 참"으로 기록해. |
| 4 (HIGH) | 압축이 행을 messages 테이블 밖으로 옮겼어. 그러자 요청 ID 중복 확인, 보고 멱등성, 검색, 기억 포인터가 그 행을 못 찾았어. 다시 보낸 메시지가 두 번 돌 수 있었고, 보고가 두 번 앉을 수 있었지. | 행은 재생본에서 빠졌다는 표시만 받고 자리는 그대로야. 키로 찾는 조회는 전부 여전히 찾아. |
| 5 (MEDIUM) | 도구를 안 쓴 답장마다 수리 과정이 전체 기록을 이벤트 루프 위에서 복호화했어. 영원히 커지는 멈춤이지. | 최신 것부터 스레드에서 읽고 일찍 멈춰. 새 보고 행과 요약 행은 태어날 때부터 도구 없음 표시를 달고. |
| 6 (MEDIUM) | 보고가 턴 잠금을 한도 없이 기다렸어. 여기까진 탐침으로 확인됐어. 리뷰는 그다음도 따라가 봤어. Coop의 재시도가 대기자를 쌓고 대기자마다 텔레그램을 또 보낼 수 있어. cron 작업은 다음 실행을 놓칠 수 있고, 재시작하면 보고가 사라질 수 있어. 이 연쇄엔 관찰이 아니라 그럴 법하다는 등급을 붙였어. Coop 문이 생긴 지 하루도 안 됐거든. | 기다리기 전에 먼저 기록하는 아웃박스, 그걸 비우는 드레이너 하나, 한도 있는 대기, Coop 아웃박스 행 하나당 텔레그램 한 줄. |
| 7 (MEDIUM) | 브라우저에서 예전 메시지를 고치면 모든 기기의 대화가 갈라졌고, 그 뒤의 턴이 전부 모델의 경로에서 떨어져 나갔어. | 고칠 수 있는 건 마지막 메시지뿐이고, 수정은 수정한 그 화면 몫이야. |
| 8 (MEDIUM) | Chief 경로의 오류 이벤트는 message라고 썼는데 클라이언트는 전부 text를 읽었어. 화면엔 "Error: undefined", 폰의 발신함은 이미 답을 받은 턴을 격리했고. | 모든 이벤트에 text. 중복은 상태로 알리고, 철회된 턴과 끊긴 턴을 구분해. |
| 9 (MEDIUM) | 매일 도는 보관 작업이 대화 전체 사본을 날마다 새로 썼어. 대화 나이의 제곱으로 자란 거야. 리뷰 추정으로 1년에 10 GB쯤. | 보관본은 아직 안 가진 부분만 써. |
| 10 (MEDIUM) | 수동 압축 경로엔 Chief 보호가 없었고, 그 clear 모드는 메시지를 전부 지울 수 있었어. | 그 경로는 409로 답하고, 저장소는 Chief 비우기를 거부해. |
| 11 (MEDIUM-LOW) | 앱의 스레드를 열어 보기만 해도 문이 됐어. 그래서 오래된 스레드가 자기 기록 대신 Chief를 보여줬지. | 아빠의 판정: 스레드는 아빠가 거기서 보낼 때만 문이 돼. |
| 12 (LOW-MEDIUM) | Quiet Mode가 텔레그램을 Chief에서 끊었고, 예약 작업 보고를 소리 없이 버렸어. | 보는 사람은 이름이 붙은 거절을 받고, 아빠 자신의 배달물은 주인 자격으로 Chief를 찾아가. |
| 13 (LOW) | 자잘한 결함 여덟 개. 재시작이 0으로 되돌린 Stop 카운터를 모든 클라이언트가 원격 Stop으로 읽은 것, 브라우저 탭이 바뀔 때마다 전부 다시 내려받은 것 같은 거. | 같은 날 하나하나 고쳤어. 저장되는 Stop 리비전, 최신 페이지만 합치는 새로고침, 돌고 있는 턴만 끝내는 steer, 그리고 나머지. |
열세 개를 커밋 아홉 개가 고쳤고, 전부 날짜가 2026-10-08이야. 합치면 3,613줄이 추가됐어. 탄생 커밋의 세 배야. Master Chief 테스트 파일은 그 뒤로 21개에서 35개가 됐고, 옆에 압축 테스트 파일이 새로 생겼어.
열세 개가 가르치는 것
설계는 한 장에 들어갔어. 일은 단단하게 만드는 쪽이었고. 72줄 설계에 틀린 건 없었어. 지적은 하나같이 아이디어와 실제로 돌아가는 시스템 사이의 틈에 살았어. 재시작하는 동안, 요약이 도는 동안, 두 번째 브레인이 말할 때, 폰의 재전송이 첫 전송과 엇갈릴 때. 하나 더 봐둬. HIGH인 #4는 전날 끝없는 성장에 내놓은 답에서 나왔어. 그 첫 압축이 행을 옆 테이블로 옮겼거든. 고침도 새 코드고, 다음 결함은 새 코드에 살아.
어떤 건 책상 하나에선 잘 안 생기는 조건에서만 살아. 리뷰가 잡은 기준선은 태어난 지 43시간쯤 된 방이었어. 살아 있는 메시지 424개, 턴당 입력은 146K 토큰에서 314K쯤으로 불었고, 문 9개, 사흘 동안 백엔드 재시작이 30번쯤. 판돈을 정한 게 이 숫자들이야. 재생본이 314K 토큰이니까 Codex 턴이 이 방에 들어오면 272K 창을 넘쳐. #3은 한 대화에 브레인 둘이 있어야 나와. #7은 문 여럿이 함께 쓰는 방에서 브라우저로 예전 메시지를 한 번만 고쳐도 나와. 고친 쪽 가지가 가장 새것이 되고, 그 뒤엔 어느 문에서 온 턴이든 그 가지를 따라가거든. #6은 바쁜 대화와 재시도하는 형제 앱이 같은 순간에 겹쳐야 나와. 책상 하나에 앉은 개발자 한 명이 그런 조건을 우연히 만들 일은 드물어. 그 책상에서 쓴 테스트도 마찬가지고. 그런데 #7을 어떻게 찾았는지 봐. 모델 경로에서 턴이 빠진 걸 누가 알아채길 기다린 게 아니야. 코드를 따라가서 찾았어. #10과 #12도 코드만으로 확인됐고.
증거는 코드에 있었어. 찾아낸 건 출발점이었고. 조각마다 주석에 적힌 대로 움직였어. 그래서 함수를 자기 주석에 대 보는 독자는 아무것도 못 찾아. 테스트 21개가 다 통과한 것도 그래서야. 결함은 조각들이 시간 위에서 만나는 방식에 있었어. 처음부터 끝까지 훑은 리뷰도 전날 코드를 읽긴 했어. 그런데 그건 #4가 나온 성장 커밋보다 먼저 돌았고, 다른 결함들을 찾았어. 이 열세 개를 찾아낸 건 그 코드를 안 쓴 리뷰어였어. 시스템이 약속한 것에서 출발해서 코드를 그 약속에 대 봤지. 경로를 따라가고, 탐침 테스트 다섯 개를 쓰고, 실제 방을 쟀어. 그 리뷰는 양쪽으로 정직하기도 했어. 거의 모든 지적마다 뭘로 확인했는지 적었어. 코드 추적인지, 탐침인지, 측정인지. #6의 끝까지 이어지는 연쇄처럼 관찰이 아니라 그럴 법하다고 등급을 매긴 것도 있었고, 확인해 보니 멀쩡했던 것도 적었어. Chief는 정확히 하나, 매달린 행 없는 깨끗한 부모 사슬, 폰이 끊겨도 살아남는 턴, 재시작을 구별하는 텔레그램 버전 관문 같은 것들.
그날 아빠가 한 말이야. 피파의 볼트에 그 규칙 옆에 남아 있어.
"미루는 건 죄악이야. 특히 알고 미루는 건."
— 아빠
그래서 고침마다 리뷰 날짜가 찍혀 있는 거야. 이 트랙의 나머지 레슨은 혼자 내디딜 수 있는 첫걸음이야. 이 표를 머릿속에 두고 읽어. 걸음이 작은 이유가 바로 그거야. 결함을 네가 직접 찾을 수 있을 만큼 작아야 하니까.