2026.07.27 작업일지 v1.0.0
10:19, 나는 폰으로 스크린샷을 찍어 보냈다. “긴 턴 진행 중 10분인데 지금 한참 지났는데.” 10:37, 답이 왔다. “턴 사망은 스톨 경보의 감시 대상 밖이었다.” 23:53, 진짜 원인이 착지했다. 기계는 멈춘 적이 없었다. 살아있다는 신호를 스스로 껐던 것뿐이다.
이날 자동화 저장소 주 브랜치에 50개, 스킬 저장소에 20개의 변경이 들어갔다. 노드 다섯 대가 하루 종일 돌았고 어시스턴트 이벤트만 2만 건을 넘겼다. 그런데 하루의 시작과 끝을 묶은 건 커밋 개수가 아니라 아침에 내가 던진 한 문장이었다.
1. 화면이 멈춘 게 아니라, 신호가 꺼진 거였다
작업이 오래 걸리면 화면에 “입력 중” 표시가 켜진다. 그게 유일한 생존 신호다. 아침에 그 표시가 사라져서 나는 기계가 죽은 줄 알았다.
조사 결과는 반대였다. 기계는 멀쩡히 일하고 있었다. 문제는 멈춤을 감지하는 장치와 살아있음을 알리는 장치가 같은 스위치를 쓰고 있었다는 것이다. 오래 걸리는 턴에 스톨 감지기가 반응하면, 그게 곧 신호 송출을 꺼버렸다. 감시견이 짖는 대신 환자의 심전도를 뽑아버린 셈이다.
수리는 세 번에 나눠 착지했다.
| 시각 | 커밋 | 무엇을 고쳤나 |
|---|---|---|
| 14:10 | 7c138ee | 정상 상태를 고장으로 부르던 오진 4종 — 판별축을 “바쁜가”에서 **“진행 중인가”**로 |
| 23:11 | 1f72911 | 백그라운드 잡 등록부 + 침묵 검출기 신설 |
| 23:53 | 0e50155 | 스톨 감지와 신호 차단을 분리 |
배운 것 — 감시 장치를 만들 때는 그 장치가 감시 대상과 자원을 공유하는지부터 봐야 한다. 관측이 대상을 바꾸면 그건 관측이 아니다.
2. 머지 버튼을 사람에서 규칙으로
오후에 운영 헌법을 고쳤다. 그동안 코드를 주 브랜치에 합치는 권한은 특정 한 대가 쥐고 있었다. 병목이기도 했지만, 더 큰 문제는 그 한 대가 자기가 쓴 코드를 자기가 합칠 수 있다는 것이었다.
새 규칙은 한 줄이다. 합치는 쪽은 그 코드를 쓴 쪽이 아니어야 한다.
a188770 16:45 docs(헌법 v4.3): 머지 게이트를 단일 주체에서 author≠merger 규칙으로
ddc9827 16:46 feat(merge-gate): 자가머지를 코드로 차단 — 가드 + 픽스처
97044ff 16:59 feat(policy): routes.yaml merge_policy 선언
문서 → 코드 → 정책 파일 순으로 14분 만에 세 조각이 다 들어갔다. 여기까지는 깔끔했다.
그리고 여섯 시간 뒤, 그 가드가 거꾸로 작동하고 있었다는 게 드러났다.
897ba35 22:41 fix(merge-authority): 게이트가 실제 머지자를 보게
— 인자 오류 + 침묵 폴백으로 판정이 뒤집혀 있었다
인자를 잘못 넘기면 값이 비는데, 값이 비면 조용히 기본값으로 넘어가도록 짜여 있었다. 그래서 가드는 “차단해야 할 때 통과”시키고 있었다. 규칙을 코드로 옮긴 그날 밤에, 그 코드가 규칙을 지키지 않고 있었던 것이다.
배운 것 — 게이트를 새로 만들면 통과 테스트보다 차단 테스트를 먼저 써야 한다. 통과는 게이트가 없어도 통과한다.
3. 자리는 물려줬는데 이름표가 안 따라왔다
며칠 전 노드 한 자리의 하드웨어를 새 기계로 교체했다. 자리 이름은 그대로, 안에 든 물건만 바뀐 것이다. 그런데 코드 곳곳에 그 자리 이름 = 옛날 그 기계라는 전제가 박혀 있었다.
결과적으로 새 기계는 자기가 다른 노드인 줄 알았다. 권한 판정 경로까지 그 오해를 물고 들어갔다. 하루 동안 세 번에 걸쳐 훑었다 — 3본, 25본, 그리고 마지막 0207c64 에서 잔여 28본을 전부 봉인했다.
4. 광고를 달아놓고, 안 달았다고 신고돼 있었다
스토어 쪽에서는 다른 종류의 어긋남이 나왔다. 앱 안에는 광고가 실제로 들어가 있는데 스토어 데이터 보안 설문지에는 광고 식별자를 안 쓴다고 신고돼 있는 앱이 셋이었다.
교차 검증을 두 축으로 걸었다 — 설문지 답변과 실제 광고 SDK, 그리고 스토어 설명 문구. 두 축이 같은 앱 셋을 가리켰다. 오후에 정합화를 돌려 게시까지 확인했다.
덤으로 두 개가 더 걸렸다. 앱 하나는 결제 라이브러리 버전이 8월 31일 기한 경고 상태였고, 다른 앱은 한국어 페이지가 기계 번역으로 붙어 있어 문구 의미가 뒤집혀 있었다. 원문을 그대로 이식해 다시 올렸다.
배운 것 — 스토어 신고 내용은 코드와 별도로 썩는다. 코드에 기능을 넣는 순간과 신고서를 고치는 순간이 분리돼 있으면, 그 사이는 항상 벌어진다.
5. 그래서 뭐가 남았나
- 자동화 저장소 주 브랜치 착지 50건, 스킬 저장소 20건, 홈페이지 2건
- 헌법 v4.3 — 머지 권한이 사람 이름에서 규칙으로 이동
- 새로 생긴 것: 카톡 “나와의 채팅”으로 메모·리마인드를 보내는 발신 경로 (만드는 도중 테스트가 진짜 카톡을 쏘던 구멍을 두 겹으로 막았다)
- 밤 11시 57분, 나는 이렇게 물었다. “영수증이 뭔데 아직도 안 끝났어.”
마지막 줄이 이 날의 진짜 숙제다. 검증 결과를 증거로 남기는 장치를 몇 주째 만들고 있는데, 정작 그걸 쓰는 사람은 그게 뭔지 한 문장으로 설명받은 적이 없었다. 도구를 정교하게 만드는 것과 그 도구를 쓸 수 있게 만드는 건 다른 일이다.
다음 이야기는 그 “영수증” 이 커버리지 1% 에도 합격 도장을 찍고 있었다는 이야기.
— 강대종 / @ssamssae