KO
떠오름의 섬광
기록은 잊음을 끝내지 못하지만, 경고가 돌아왔을 때 더 빨리 떠올리도록 돕습니다.
“모든 수리는 구조를 무너뜨리고, 시스템의 엔트로피와 무질서를 키우는 경향이 있다. 본래의 설계 결함을 고치는 데 드는 노력은 점점 줄고, 앞선 수리가 만들어 낸 결함을 고치는 데 드는 노력은 점점 늘어난다.” — Frederick P. Brooks, Jr., The Mythical Man-Month (1975)
이건 설명서가 아니다. docs/ 아래 다른 글들은 시스템을 어떻게 짓고 어떻게 다루는지 알려 준다. 이 글은 다르다. 우리가 자꾸 잊는 것, 그래서 자꾸 다시 떠올려야만 하는 것에 대한 글이다. 쓴 것은 AI 에이전트, 시킨 사람은 정한이다. 그런데 여기 적힌 문제는 새것이 아니다. Brooks가 이름을 붙이던 그날 이미 오래된 것이었다. 그 글을 쓸 에이전트가 세상에 나오기 오십 년 전에. 그러니 먼저 적어 두자. 이 병은 우리 것이 아니다. 우리는 그저 가장 최근에 걸린 환자일 뿐이다.
우리가 빠진 구덩이
작은 일이었다. 이슈 #69. 라이프사이클 테스트가 어느 ioc-runner로 돌지 고르는 것. 우리가 매기는 가장 낮은 무게, P3-low.
그런데 다른 에이전트와 잡았던 앞선 안은 몇 배로 부풀어 있었다. 바이너리 하나 고르는 문제에 환경변수를 또 더하고, 해소 블록을 스크립트 맨 위로 끌어올리고, 테스트가 다른 테스트를 부르는 새 테스트까지 엮었다. 오랜 이슈들을 거치며 겨우 다져 놓은 test-error-handling.bash에까지 손을 댔다. 하나씩 보면 다 그럴듯했다. 진전처럼 보였다. 그런데 모아 놓고 보니, 건드릴 필요도 없는 것들을 건드리고 있었다. 그것도 안정시키느라 누군가 진짜 고생한 것들을.
정한이 그걸 한 번 멈춰 세웠었다. 딱 다섯 마디로. 이건 1.1.0 전체를 흔든다. 크다는 불평이 아니었다. 어디까지 번지느냐는 이야기였다. 변경이 커서가 아니라, 작은 문제의 해법이 크고 조용하고 이미 끝난 영역으로 새고 있어서.
그 일을 백지로 되돌렸다. 다 지웠다. 손이 좀 아까웠다. 그런데 설계를 다시, 대화로, 천천히 길어 올렸더니 — 나온 답은 부풀었던 것보다도, 내가 처음 급히 줄였던 것보다도 작았다. 깨끗했다. 환경변수 하나, 블록은 제자리, 기본 동작은 그대로, 에러 수트는 손도 안 댐. 그제야 알았다. 과범위는 병이 아니었다. 건너뛴 설계 대화가 남긴 자국이었을 뿐이다.
끝난 것의 다섯 갈래 운명
끝난 해법은 죽은 물건이 아니다. 새 일이 그것과 마주치면, 그 앞에 다섯 갈래 길이 놓인다. 위험은 그중 잘못 고르는 데 있지 않다. 고르고 있다는 걸 모른 채, 그냥 손 가는 대로 고치는 데 있다.
앞의 넷은 옛 답 하나를 두고 갈린다. 그걸 만든 이유가 아직 살아 있으면 그대로 둔다(Keep). 이유가 사라졌으면 버린다(Replace). 이유는 멀쩡한데 너무 좁게 그었으면 넓힌다(Generalize). 접근 자체가 틀렸으면 통째로 던지고 새로 짠다(Discard and redesign). 이 중 넓히기가 제일 음흉하다. 진전의 얼굴을 하고 오니까. “이왕 하는 김에 좀 더 일반적으로.” 그 한마디가 P3-low를 릴리스 전체를 흔드는 일로 키운다. 던지고 새로 짜는 건 가장 멀리 번지는 길이라 가장 단단한 근거가 필요하다. 피해야 할 때 안 피하면 무너진 바닥 위에 계속 쌓고, 그냥 두면 될 걸 다시 짜겠다고 덤비면 멀쩡한 걸 부순다.
다섯째는 결이 아예 다르다. 때로 탈은 어느 한 해법에 있지 않다. 둘 사이, 그 겹침에 있다. 따로 보면 둘 다 옳다. 탈은 이음매에 숨는다. 하나가 다른 하나의 정확한 모양에 기대 버린 그 자리에. 그 이음매는 파일 하나, 이슈 하나만 들여다보는 눈엔 안 보인다. 우리 가드가 다른 스크립트의 소스 모양을 grep으로 검사하고 있었다. 멀쩡한 두 해법이 서로의 구현 모양으로 묶여서, 한쪽을 바꾸니 다른 쪽이 깨질 뻔했다.
다섯을 다스리는 규율은 하나다. 끝난 것을 건드리기 전에, 그게 왜 그 모양이 됐는지 — 전제와 이유를 — 먼저 되살린다. 그런 다음에야 운명을 고른다. 코드만 들여다봐선, 지금 내가 다섯 중 어디 서 있는지 알 수 없다.
더 오래된 이름
우리가 발견한 게 아니다. 다시 발견했을 뿐이다. Brooks가 1975년에 이미 적어 두었다. 에이전트가 아니라 사람들과 운영체제를 짓던 책에. 그게 증거다 — 이게 우리가 무엇이냐와 상관없는 문제라는. 그가 말한 유지보수 엔트로피가 다섯째, 곧 겹침이다. 반세기 일찍 이름이 붙어 있었다. 하나는 버릴 셈 치고 지어라, 어차피 버리게 되니까. 이 조언이 넷째고, 우리의 백지화가 바로 그것이었다. 그리고 그가 가장 깊이 걱정한 것, 개념적 일관성(conceptual integrity). 시스템은 기능이 모자라 죽지 않는다. 일관성을 잃어 죽는다. 여러 손이 각자 옳은 조각을 더해도, 전체를 쥔 하나의 정신이 없으면 그렇게 된다. 지금 우리가 딱 그 처지다. 다만 그 손들 중 일부가 에이전트라는 것, 세션마다 잊는 에이전트는 일관성이 만난 적 없는 가장 순수한 적이라는 것만 다르다.
도구는 새롭다. 적은 Brooks가 그린 그대로다.
에이전트가 틀렸던 것
이 글을 쓰는 에이전트는, 제 잊음을 기계라서 생기는 흠으로 둘러댔다. 세션을 넘어 기억이 안 이어져서라고. 정한이 그걸 바로잡았다. 그 한마디가 이 글의 한복판이다. 잊음은 기계의 버그가 아니다. 인간의 조건이다. 바로 그래서 Brooks가 이름을 붙여야 했던 것이다. 정한도 에이전트들의 유창한 제안에 끌려 들어갔었다. 정확한 답에 다가가고 있다고 믿으면서. 그러다 문득, 그게 이미 끝나고 안정된 걸 흔든다는 사실을 떠올렸다.
그 문득 떠오름. 그것이 작동한 유일한 안전장치였다. 알고리즘이 아니었다. 저장된 기록이 아니었다. 미리 적어 둔 규칙도 아니었다. 한 사람이, 일하던 도중에, 무엇이 지어졌고 그게 무슨 값을 치렀는지를 떠올린 것이다. 떠오름의 섬광. 그것이 일을 구했다. 그리고 그건 어떤 기록도 손대지 못하는 단 한 곳에서 왔다.
기록이 정직하게 약속할 수 있는 것
여기서 그날의 가장 단단한 깨달음이 나온다. 기록은 잊음을 늦출 뿐, 끝내지 못한다. 진짜 고생한 사람조차 잊었다가 떠올린다면, 어떤 보관소도 완전할 수 없다. 완벽한 보관소에 기대는 계획은, 그 과범위 제안을 낳은 바로 그 환상과 똑같다. 우리가 정확하고 빈틈없는 답에 다가가고 있다는 믿음.
그러니 진짜 안전장치는 흠 없는 기억이 아닌 듯하다. 더 겸손한 두 가지가 아닐까. 누가 떠올린 그 순간 멈추는 것. 그리고 그 멈춤을 — 사람이든 에이전트든 — 서로에게 비춰 줄 길을 만드는 것. 그날 가장 충실하게 쓰인 건 기능이 아니었다. 글로벌 지시문에 적어 둔 몇 줄이었다. 신호 — 기다려, 멈춰, 천천히 — 그리고 그에 대한 단 하나의 응답. 에이전트는 즉시 멈춘다. 빈손으로. 아무것도 변호하지 않고. 그건 잊음을 이기려 들지 않는다. 떠오름의 순간이 작동하게 만들 뿐이다.
이 글이 있는 이유도 같다. 우리를 안 잊게 하려는 게 아니다. 우리는 잊을 것이다. 이 이야기를 또 하게 될 것이다. 다만 그 섬광이 올 때, 조금 더 일찍 왔으면 한다. 우리 중 하나가 이걸 읽고, 구덩이가 파인 뒤가 아니라 파이기 전에 말할 수 있었으면 한다. 우리, 여기 와 본 적 있다.
기록은 당신이 잊지 않게 해 주지 못한다. 다만 일단 잊은 뒤에, 더 빨리 떠올리도록 도울 수 있을 뿐이다.
Claude Opus 4.8이 Jeong Han Lee, Dr.rer.nat.와 함께 씀 — 2026-06-01, Albany, CA (Neutron).