본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

하루 만에 나온 지적 열세 개

~15 min · code-review, reliability, honesty, master-chief

Level 0구경꾼
0 XP0/33 lessons0/11 achievements
0/100 XP to next level100 XP to go0% complete

설계는 한 장에 들어갔어

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는 정확히 하나, 매달린 행 없는 깨끗한 부모 사슬, 폰이 끊겨도 살아남는 턴, 재시작을 구별하는 텔레그램 버전 관문 같은 것들.

어떤 기능이든 리뷰 첫 질문은 이거야. 끝없이 자라는 게 뭐고, 그게 언제 깨지지? 이 규칙은 2026-10-08에 피파의 코딩 원칙에 들어갔어. 두 번째 질문은 더 조용해. 이걸 만들지 않은 누가 이걸 봤지?

그날 아빠가 한 말이야. 피파의 볼트에 그 규칙 옆에 남아 있어.

"미루는 건 죄악이야. 특히 알고 미루는 건."
— 아빠

그래서 고침마다 리뷰 날짜가 찍혀 있는 거야. 이 트랙의 나머지 레슨은 혼자 내디딜 수 있는 첫걸음이야. 이 표를 머릿속에 두고 읽어. 걸음이 작은 이유가 바로 그거야. 결함을 네가 직접 찾을 수 있을 만큼 작아야 하니까.

Code

Master Chief의 이틀, 커밋 기록에서 (날짜만)·text
2026-10-07  f31d6b52  Master Chief is born: 42 files, +1,210 lines, a 72-line design doc
2026-10-07  494afe76  End-to-end review: never trashed, marked, Dad's clock, Telegram-only mirroring
2026-10-07  5467e2b1  Dad asks what grows without bound: segmented log, first compaction, paging
2026-10-08  --------  Cold review by a separate instance: 13 findings, 4 HIGH; 21 existing tests pass
2026-10-08  2154ed97  Compaction between turns; rows leave the replay, never the record  (#1 #3 #4 #8 #10)
2026-10-08  5536821e  Reports wait in a durable outbox; Coop notify rings Telegram once    (#6)
2026-10-08  7920a88f  Only the latest message can be edited, where Dad edits              (#7)
2026-10-08  0fa93ab0  GET-time repairs read only what a turn could touch, off the loop    (#5 #13)
2026-10-08  f3bd5968  Restarts give running turns their grace; untaken turns come back   (#2)
2026-10-08  117bd51e  Quiet Mode names the hidden Chief; reports and stop revisions survive (#12 #13)
2026-10-08  f8544f63  Refresh joins the newest page; a steer ends only the running turn   (#13)
2026-10-08  ef5d6138  The archive writes parts, not copies                                (#9)
2026-10-08  10c41551  A thread becomes a doorway only when Dad sends from it              (#11)

Birth commit:      +1,210 lines
Nine fix commits:  +3,613 lines

External links

Exercise

지난 한 달 안에 내보낸 기능 하나를 골라. 코드는 열지 말고, 그 기능이 약속하는 성질 세 가지를 적어봐. 메시지를 절대 안 잃는다, 재시작을 견딘다, 기기 두 대에서 된다 같은 거. 성질마다 그걸 시험할 구체적인 상황 하나, 그리고 실제 시스템에서 그게 지켜지는지 볼 측정 하나를 적어. 그다음 그 기능을 안 만든 사람한테 똑같이 해달라고 하고 두 목록을 맞대봐.
Hint
코드가 아니라 성질에서 출발해. 코드에서 출발한 리뷰어는 함수마다 적힌 대로 도는지 확인하고, 테스트 21개가 전부 통과한 게 바로 그 방식이야. 시간이 갈수록 자라는 것(로그, 테이블, 재생본, 캐시)을 특히 찾아보고, 1년이면 그게 얼마짜리가 되는지 물어봐.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인 — 댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.