Claude Code 맥락 유지는 왜 문서 문제인가?
Claude Code 맥락 유지가 어려운 이유는 단순합니다. 세션이 끝나면 그 세션에서 오간 대화가 다음 세션으로 넘어가지 않습니다. 어제 무엇을 결정했는지, 왜 그 방법을 버렸는지, 어디까지 만들었는지를 모델은 새 세션에서 처음부터 모릅니다. 저희 규칙 문서도 첫 줄에 이 문제를 그대로 적어 두었습니다. AI 와 함께 만드는 사람의 핵심 문제는 세션 종료 시 맥락이 휘발한다는 점이라고요.
이걸 기억력 문제로 보면 해법은 모델이 더 많이 기억하게 하거나, 사람이 세션을 열 때마다 앞 이야기를 다시 들려주는 쪽이 됩니다. 하지만 뒤에서 볼 사례처럼 대표는 세션을 열 때마다 같은 말을 반복해야 한다고 느꼈고, 설명에서 빠진 판정은 그대로 사라졌습니다.
결국 고친 곳은 모델이 아니라 저장 위치였습니다. 세션이 바뀌어도 파일은 남으니, 다음 세션이 읽어야 할 내용을 프로젝트 폴더 안 파일에 정해진 형식으로 남기기로 했습니다. 이 글은 그 구조를 어떻게 정했고, 굴려 보니 어디가 새는지 기록한 구축기입니다. 기각한 제안이 되살아나던 사례는 AI 에이전트 메모리의 빈칸 글에 따로 자세히 적었습니다.

기존 방식의 한계: 하기로 한 일만 남았다
처음 세운 문서는 3개였습니다. 지금 상태와 다음 단계를 적는 진행 문서, 중요한 결정의 이유와 대안을 적는 결정 기록, 도메인 지식과 반복 버그 해법을 쌓는 지식 문서입니다. 셋 다 영구 문서이고, 진행 문서는 세션을 마감할 때마다, 결정 기록은 결정이 생긴 즉시, 지식 문서는 무언가 배웠을 때 고칩니다.
이 3개로 한동안 굴렀지만, 2026-08-08 에 구멍이 드러났습니다. 세 문서는 전부 하기로 한 것만 저장했습니다. 열린 일, 내린 결정, 배운 것. 죽인 것을 저장할 자리는 어디에도 없었습니다. 되돌린 사실은 git 의 되돌림 커밋으로 남지만, 왜 되돌렸는지와 다시 꺼내지 말라는 판정은 아무 데도 남지 않았습니다.
그래서 새 세션이 열리면 기각한 제안이 신선한 아이디어처럼 되살아났습니다. 그날 한 세션 안에서만 2회 일어났습니다. 한 번은 이미 기각한 채널 리서치를 다시 조사했고, 한 번은 되돌리라고 지시받은 화면 개편을 미해결 항목으로 다시 제안했습니다. 대표는 이렇게 물었습니다.
세션 오픈 할 때 이전 세션 대화의 흐름이 모두 유실된 채로 같은말을 반복해야하는 것 같지?
규칙 문서에는 이 사건을 이렇게 판정해 두었습니다. 기억력 문제가 아니라 저장 스키마의 구멍이고, 그래서 프롬프트가 아니라 파일로 고친다고요. 이 판정이 뒤에 나오는 모든 설계의 출발점입니다.
고려한 대안은 무엇이었고 왜 탈락했나?
파일로 고친다는 방향은 정했지만, 파일을 어디에 어떤 모양으로 둘지는 여러 길이 있었습니다. 규칙 문서와 그 개정 이력에 남은 대안을 정리하면 아래와 같습니다. 일부는 처음부터 고르지 않았고, 일부는 실제로 써 보다가 버렸습니다.
- 대안 1: 프롬프트와 모델 기억에 맡기기: 세션을 열 때 사람이 맥락을 설명하거나, 지시문에 주의 문구를 더하는 방식입니다. 2026-08-08 사례가 이 길의 한계를 보여 줬습니다. 지시문을 아무리 고쳐도 기각 판정을 담을 자리가 없으면 다음 세션은 그 판정을 모릅니다
- 대안 2: 전역 메모리 한 곳에 전부 몰기: 프로젝트를 가로지르는 메모리 폴더는 이미 있었습니다. 그래서 역할을 나눴습니다. 전역 메모리는 사람에 대한 정보, 사람이 준 작업 방식 피드백, 프로젝트를 넘나드는 학습만 맡기고, 프로젝트 상태는 프로젝트 폴더에 두었습니다
- 대안 3: 지식 그래프를 상시로 쓰기: 코드베이스와 문서 구조를 자동 추출해 그래프로 만드는 도구도 검토했습니다. 이 층은 필수가 아니라 선택 사항으로 두고, 대형 프로젝트에서만 쓰기로 적어 두었습니다
- 대안 4: 진행 문서를 4칸 보고서로 쓰기: 현재 상태·최근 완료·대기 결정·다음 단계를 각각 제목으로 두는 형식입니다. 실제로 써 봤고, 같은 큐가 여러 칸에 사본으로 생겨 한쪽만 늙는 실패가 실증돼 폐기했습니다. 다음 절에서 자세히 다룹니다
- 대안 5: 진행 문서에 상세 로그를 전부 쌓기: 빠뜨리지 않으려고 모든 경과를 적는 방식입니다. 진행 문서가 50KB 까지 불어나면 다음 세션이 읽는 데만 오래 걸립니다. 진행 문서에는 요약만 두고, 상세는 git 이력과 결정 기록으로 보냈습니다
탈락 사유를 한 줄로 묶으면 두 가지입니다. 담을 자리가 없으면 아무리 말해도 남지 않고, 같은 값을 두 곳에 두면 반드시 한쪽이 틀립니다. 이 두 원칙이 선택한 구조의 뼈대입니다.
선택한 구조: 프로젝트 문서 4개 위에 메모리와 그래프
최종 구조는 3층입니다. 1층은 프로젝트 폴더 안의 살아 있는 문서 4개, 2층은 프로젝트를 가로지르는 전역 메모리, 3층은 대형 프로젝트에서만 쓰는 지식 그래프입니다. 핵심은 1층입니다. 기존 문서 3개에 2026-08-08 기각 목록 문서를 네 번째로 더했습니다.
| 문서 | 맡는 것 | 고치는 시점 | 수명 |
|---|---|---|---|
| 진행 문서 | 현재 상태 · 다음 단계 · 대기 결정 | 세션 마감 때마다 | 영구, 상시 갱신 |
| 결정 기록 | 중요한 결정의 이유와 대안 | 결정이 생긴 즉시 | 영구, 덧붙이기만 |
| 지식 문서 | 도메인 함정 · 반복 버그 해법 | 배운 순간 | 영구, 계속 성장 |
| 기각 목록 | 대표가 죽인 축 · 이유 · 재개 조건 | 기각 발화가 나온 그 턴 | 영구, 덧붙이기 + 해제 이력 |
네 번째 문서는 2026-08-08 에 생겼다. 앞의 3개는 하기로 한 것만 담는다.
문서마다 답하는 질문을 정해 두었습니다. 헷갈리면 이 표를 봅니다. 어디까지 했는지는 진행 문서, 왜 그걸 골랐는지는 결정 기록, 이 버그를 전에 본 적 있는지는 지식 문서가 답합니다. 사람이 어떤 사람인지, 프로젝트를 넘나드는 학습이 무엇인지는 전역 메모리가, 코드베이스 구조는 지식 그래프가 있으면 그쪽이 답합니다. 질문이 6개, 답하는 곳도 정확히 하나씩입니다.
결정 기록과 지식 문서는 칸을 고정했습니다. 결정 기록 한 건은 상태, 맥락, 결정, 결과, 대안의 다섯 칸으로 씁니다. 상태 칸에는 채택 또는 다른 결정으로 대체됨을 적어, 뒤집힌 결정도 지우지 않고 남깁니다. 지식 문서는 도메인 함정, 디버깅 해법, 효과 있던 패턴, 실패한 패턴, 우리만의 스택 관습으로 나눕니다. 디버깅 해법은 증상마다 원인, 해결, 재발 방지, 발견 날짜를 적습니다. 칸이 정해져 있어야 다음 세션이 같은 자리에서 같은 정보를 찾습니다. 형식이 프로젝트마다 다르면 그 자체로 맥락을 잃는 길입니다.
언제 고치는지도 문서마다 정해 두었습니다. 진행 문서는 세션 마감 때 반드시, 그리고 큰 단계를 마치거나 작업 단계가 바뀔 때 고칩니다. 결정 기록은 DB나 프레임워크 같은 구조 선택, 무언가를 내주고 무언가를 얻는 선택, 이전 결정을 뒤집을 때 씁니다. 지식 문서는 버그를 고쳤을 때, 놀라운 도메인 사실을 발견했을 때, 실패한 접근이 생겼을 때, 동료나 사용자의 피드백을 받았을 때 씁니다. 실패한 접근을 적어야 같은 실수를 다음 세션이 다시 밟지 않습니다.
기각 목록만 기록 시점이 다릅니다. 다른 문서는 세션을 열고 닫는 절차 안에서 고치지만, 기각 목록은 대표가 그거 아니라고 했잖아, 되돌려, 그건 하지 마 같은 말을 한 바로 그 턴에 덧붙입니다. 세션이 중간에 죽으면 그 판정이 통째로 사라진다는 문제 때문에 이 문서가 생겼습니다. 마감 절차까지 미루면 원인을 그대로 재현합니다.
- 세션 시작 시 progress-queue-inject.sh 가 살아 있는 기각 항목을 창에 강제로 넣습니다. 거기 있는 축은 조사조차 시작하지 않습니다
- 재개는 재개 조건을 채웠다는 근거를 내고 대표가 판정한 뒤에만 합니다. 아직 미해결이니까라는 이유로 다시 착수하는 행동이 정확히 반복되던 실패였습니다
- 재개 조건을 채운 항목은 해제 이력으로 내립니다. 지우지 않습니다. 왜 한때 죽었는지가 다음 판단의 재료이기 때문입니다
진행 문서는 어떻게 한 곳에만 열린 일을 두나?
진행 문서에는 불변식이 하나 있습니다. 지금 열려 있는 일은 파일 맨 위의 LIVE QUEUE 블록 하나에만 삽니다. 그 아래는 전부 동결된 과거 기록입니다. 큐 사본을 두 곳에 두면 반드시 한쪽이 늙기 때문입니다.
이 불변식은 실패에서 나왔습니다. 처음에 쓰던 4칸 보고서 형식은 현재 상태, 최근 완료, 대기 결정, 다음 단계를 각각 제목으로 두었습니다. 그러면 같은 일이 대기 결정에도, 다음 단계에도 적힙니다. 세션 하나가 한 칸만 고치고 나가면 두 칸이 서로 다른 말을 합니다. 2026-07-25 실측에서 현재 단계를 적은 칸이 한 문서 안에 4중복으로 있었습니다.

지금 형식에서 LIVE QUEUE 블록은 매 세션 마감 때 통째로 다시 씁니다. 여기 없으면 열려 있지 않은 일입니다. 그 아래 세션 기록은 덧붙이기만 하고, 그 시점의 미결 항목은 닫히면 취소선과 완결 표시를 붙이며, 14일이 지나면 당시 미결(동결)이라는 라벨로 바꿉니다. 현재 상태로 읽으면 안 된다는 표시입니다. 이 규칙을 지키는지는 progress-health.py 가 검사합니다.
다시 쓰는 구역과 덧붙이는 구역을 나눈 것이 이 형식의 요점입니다. 여러 세션이 같은 문서를 동시에 고칠 때 이 경계가 어떻게 깨졌고 어떻게 막았는지는 Claude Code 병렬 세션 글에 적었습니다.
구현에서 막힌 지점: 규칙과 실행 절차가 따로 늙었다
구조를 정한 뒤 가장 먼저 막힌 곳은 문서 형식이 아니라 절차의 위치였습니다. 처음에는 세션을 열고 닫는 순서를 규칙 문서 안에 적었습니다. 그런데 실제로 세션을 열고 닫을 때는 별도의 실행 절차 파일이 돌았습니다. 같은 순서가 두 곳에 적혀 있었던 셈입니다.
결과는 앞의 4칸 보고서와 똑같았습니다. 규칙 문서 쪽 순서만 고치고 실행 절차는 그대로 둔 일이 생겼습니다. 사람이 읽는 문서는 최신인데 실제로 실행하는 쪽은 옛 순서로 돌았습니다. 2026-07-25 에 이 이중 기록을 정리해 절차의 기준을 실행 절차 파일로 옮겼습니다.
지금 규칙 문서는 파일 형식 표준만 기준으로 들고 있고, 순서는 실행 절차 파일을 직접 가리킵니다. 진행 문서를 고치는 형식의 유일한 기준도 세션 마감 절차 쪽에 있습니다. 같은 값을 두 곳에 두지 않는다는 원칙을 문서 자신에게도 적용한 셈입니다.
- 규칙 문서: 문서 4개의 형식 표준만 맡는다
- 세션 열기 절차: 진행 문서와 기각 목록을 읽고 맥락을 복원한다
- 세션 마감 절차: 진행 문서의 LIVE QUEUE 를 다시 쓰고, 놓친 기각을 줍는 마지막 그물 단계를 둔다
- 기각 기록만은 어느 절차에도 묶지 않고 그 턴에 바로 남긴다
마감 절차 안에 기각을 줍는 단계를 따로 둔 이유도 같은 맥락입니다. 그 단계는 1차 기록 지점이 아니라 놓친 것을 줍는 그물입니다. 그물을 기록 지점으로 삼으면 세션이 중간에 죽을 때 다시 잃습니다.
운영에서 드러난 것: 완료라고 쓴 줄을 셀 수 없었다
구조가 자리를 잡은 뒤 2026-08-09 에 다른 질문을 던졌습니다. 문서에 됐다고 적은 일이 실제로 됐는가. 환각 감사라고 부른 이 점검에서, 살아 있는 문서 106개를 훑으니 완료 주장이 5,357줄 있었습니다.
그중 기계로 확인할 수 있는 참조를 단 줄은 71줄이었습니다. 커버리지 1.33% 입니다. 나머지는 배포 완료, 발송 완료처럼 결과만 적고 어디서 확인하는지는 없었습니다. 그래서 됐다고 한 일이 실제로 됐는지를 사후에 셀 수 없었습니다.

이 감사가 내린 결론이 중요합니다. 4~6월 세션 기록이 다 남아 있었어도 결과는 같았으리라고 봤습니다. 감사가 안 된 진짜 원인은 기록 소실이 아니라 기록 방식이었습니다. 문서가 사라져서가 아니라, 처음부터 확인할 대상을 붙이지 않고 썼기 때문입니다.
앞에서 맥락 보존을 저장 위치 문제로 풀었다면, 여기서는 저장 형식 문제가 하나 더 드러난 셈입니다. 남기는 것만으로는 부족하고, 남긴 내용을 나중에 대조할 수 있는 모양으로 남겨야 했습니다.
완료 기록은 어떻게 기계로 강제하나?
규칙은 한 문장입니다. 확인할 대상을 못 붙이면 완료라고 쓰지 않는다. 적용 대상은 결과물이 세상에 남는 행위로 좁혔습니다. 배포, 머지, 발송, 발행, 게시, 업로드, 등록, 주입, 생성, 출하입니다.
리서치 완료, 검토 완료처럼 결과물이 없는 완료는 면제했습니다. 이것도 탈락시킨 대안이 있습니다. 모든 완료 줄에 참조를 강제하는 안입니다. 그렇게 하면 매 세션 마감이 막히고, 막히는 규율은 결국 통째로 꺼집니다. 응답을 근거와 대조하던 다른 검사 훅이 2026-05-26 에 정확히 그 경로로 차단에서 경고로 내려간 전례가 있었습니다. 전면 강제하면 이 규율도 3개월 뒤 꺼질 것으로 봤습니다.

인정하는 참조는 URL, 백틱으로 감싼 경로나 명령, PR·이슈 번호, 커밋 해시, 12/12 같은 통과 카운트, 배포 ID, 그리고 확인 또는 검증으로 시작하는 명령입니다. 참조를 못 붙이겠으면 그건 완료가 아닙니다. 진행 중이라고 쓰거나, 확인 방법을 먼저 정합니다.

세 층은 역할이 다릅니다. 첫 층은 문서를 쓰는 순간, 둘째 층은 AI 가 응답을 끝내는 순간, 셋째 층은 한 주가 지난 뒤에 작동합니다. 앞의 둘이 새 기록을 막고, 마지막 층이 막은 효과가 숫자로 나오는지 봅니다.
지금 상태와 다음: 규칙이 아니라 강제 층을 손본다
지금 구조는 프로젝트 문서 4개, 전역 메모리, 선택형 지식 그래프의 3층이고, 그 위에 완료 기록 검사 3층이 붙어 있습니다. 세션을 시작할 때는 진행 문서를 읽고, 결정 기록의 최근 3개를 확인하고, 작업 중인 브랜치를 확인합니다. 세션 중에는 결정이나 학습이 보이면 그 자리에서 문서에 남기고, 마감 때 진행 문서와 메모리를 고칩니다.
남은 한계도 분명합니다. 기준선 1.33% 이후 커버리지가 얼마나 올랐는지는 이 글을 쓰는 시점의 자료에 없습니다. 주간 대조가 그 숫자를 냅니다. 만약 커버리지가 오르지 않으면 규율을 다시 설명하지 않고 강제 층을 손볼 생각입니다. 산문 규칙만으로는 안 지켜진다는 점이 이 감사가 남긴 결론입니다.
피해야 할 습관도 5개로 정리해 두었습니다. 문서를 고치지 않고 세션을 끝내기, 나중에 정리하겠다며 미루기, 진행 문서에 상세 로그를 쏟아붓기, 6개월 전 항목을 대기열에 방치하기, 프로젝트마다 다른 형식 쓰기입니다. 다섯 모두 문서가 있는데도 다음 세션이 맥락을 잃는 길입니다.
- 세션이 바뀌어도 남는 것은 파일뿐이다. 맥락은 기억이 아니라 저장 위치로 푼다
- 하기로 한 일만 담는 문서는 기각을 잃는다. 죽인 것을 담는 자리를 따로 둔다
- 열린 일은 한 블록에만 둔다. 사본이 두 곳이면 한쪽이 늙는다
- 완료라고 쓸 때는 확인할 대상을 붙인다. 못 붙이면 완료가 아니다
- 규칙을 지키지 않으면 규칙을 다시 쓰지 말고 강제 층을 손본다
AI 에이전트로 여러 프로젝트를 오래 굴리는 팀이라면, 대화 기록을 더 길게 남기는 쪽보다 이 문서 구조를 먼저 세우는 편이 싸게 먹힙니다. 비슷한 자동화 구조를 회사 업무에 붙이고 싶다면 상담으로 문의해 주세요.