Claude Code 병렬 세션은 공유 작업 목록에서 무엇을 잃고 있었나?
Claude Code 병렬 세션 여러 개가 같은 작업 목록을 고치면, 누군가 목록을 다시 쓰는 순간 남이 적어 둔 항목이 에러 없이 사라집니다. 저희가 잃은 것은 코드가 아니라 “아직 안 끝난 일”의 기록이었습니다. 반쯤 만든 기능은 고치지 않은 파일, 머지 안 된 브랜치, 깨진 테스트로 계속 눈에 띄어서 누군가 다시 집어 듭니다. 그런데 아직 재지 않은 숫자, 며칠 뒤 다시 확인하기로 한 측정은 저장소 어디에도 흔적이 없어서, 목록에서 빠지는 순간 존재 자체가 사라집니다.
저희는 하루에도 여러 창에서 세션을 동시에 돌립니다. 한 창은 광고, 한 창은 고객 문의, 한 창은 콘텐츠를 맡는 식입니다. 세션을 닫을 때마다 에이전트가 정해진 마감 절차를 밟습니다. 오늘 한 일을 요약하고, 결정과 학습을 기록 문서에 덧붙이고, 진행 문서 맨 위의 “지금 열려 있는 일” 블록을 새로 써서 다음 세션이 그 블록만 읽고 이어 가게 합니다. 이 블록이 무엇이 열려 있는가의 유일한 출처라서, 여기서 빠진 항목은 다음 세션에게 처음부터 없던 일이 됩니다.
비용은 조용히 쌓였습니다. 2026년 8월 4일 사후 분석에서 목록 유실이 실제로 작업을 멈춰 세운 사례 3건을 찾았는데, 3건 모두 측정 항목(도달률·잔액 구간·기준선)이었습니다. 다른 사례는 더 비쌌습니다. 8월 7일에는 목록 항목 하나가 원문 위치 없이 “세션 발화”라는 말로만 적혀 있었고, 다음 세션이 다른 폴더의 대화 기록을 뒤지다가 남은 단어 하나를 소프트웨어 이야기로 오독해 세션 하나를 통째로 엉뚱한 산출물(설계 문서 2건과 검토 10회)에 썼습니다. 에러 메시지는 한 번도 뜨지 않았습니다.
처음 잰 숫자: 문서는 커지고, 번호는 겹쳐 있었다
문제가 있다는 느낌을 숫자로 바꾸려고 세 가지를 쟀습니다. 첫째는 문서 크기와 중복입니다. 2026년 7월 25일 진단에서 진행 문서는 3,477줄이었고, “현재 단계”를 적은 블록이 네 군데에 따로 있었습니다. 세션마다 덧붙이기만 하고 정리하지 않아서, 이미 끝난 보류 항목이 검색에 계속 걸렸습니다. 다음 세션은 어느 블록이 진짜 현재인지 알 길이 없었습니다.
둘째는 기록 번호 충돌입니다. 결정 기록은 날짜와 일련번호를 붙인 형식을 쓰는데, 같은 번호가 서로 다른 두 결정에 붙은 경우를 세어 보니 영업 운영 저장소에서 527건 중 5건, 자동매매 저장소에서 166건 중 6건이었습니다. 같은 날 두 세션이 각자 “마지막 번호에 1을 더한 값”을 읽으면 같은 번호를 집기 때문입니다. 한 번호는 같은 파일의 858번째 줄과 10101번째 줄에 서로 다른 결정으로 붙어 있었습니다.

셋째는 목록 항목이 사라진 흔적입니다. 7월 30일의 한 커밋은 목록 항목 13개를 지우면서 본문에 “기존 9건은 건드리지 않음”이라고 적었는데, 그중 2건(사업자 데이터 모집단 확대, 신규 도메인 도달 신호 추적)은 그 뒤 파일 어디에도 없었습니다. 커밋 메시지가 말한 것과 실제로 일어난 일이 달랐고, 그 차이를 잡아 줄 장치는 아무것도 없었습니다.
세운 가설: 동시에 쓰니까 겹친다, 잠금이면 막힌다
가장 먼저 떠오른 설명은 동시 쓰기였습니다. 두 세션이 같은 순간에 같은 문서를 고치니 한쪽이 다른 쪽을 덮는다는 그림입니다. 이 가설은 그럴듯했습니다. 같은 폴더(같은 작업 트리)에서 도는 병렬 세션 사이에는 git이 끼어들 틈이 없어서, 충돌을 병합해 줄 도구가 없었기 때문입니다. 7월 25일에는 실제로 검증하는 도중에 다른 세션이 목록에 항목을 끼워 넣는 장면도 봤습니다.
이미 있던 안전장치도 이 가설을 뒷받침하는 것처럼 보였습니다. Claude Code의 파일 수정 도구는 “바꿀 원문”이 파일과 정확히 같아야 수정을 받아 줍니다. 옆 세션이 먼저 목록을 고쳤다면 원문이 달라져 수정이 실패하고, 에이전트는 다시 읽고 병합한 뒤 재시도합니다. 그래서 2026년 8월 9일, 마감 절차 첫 단계에 저장소 단위 잠금을 넣었습니다. 마감을 시작하는 세션이 잠금을 잡고, 잠금이 잡혀 있으면 다른 세션은 기다렸다가 재시도합니다. 세션이 죽어 잠금만 남는 경우를 대비해 30분이 지나면 저절로 풀리게 했습니다.

가설이 틀린 지점: 잠금을 걸고도 번호가 또 겹쳤다
잠금은 동시 실행을 한 줄로 세웠지만 번호 충돌은 멈추지 않았습니다. 잠금을 도입한 8월 9일 이후에도 8월 12일과 13일에 충돌이 3건 더 났습니다. 잠금은 두 세션이 같은 순간에 쓰는 일만 막을 뿐, 번호를 세어 주지는 않았습니다. 순서대로 들어온 두 세션이 둘 다 같은 방식으로 잘못 세면 결과는 똑같이 겹칩니다.
번호를 세는 방식 자체가 틀려 있었습니다. 기록 문서는 한 제목이 여러 번호를 덮는 범위 표기(예: “865~868번”을 한 제목에)를 쓰는데, 영업 운영 저장소에서만 이런 범위 제목이 58개였습니다. “가장 큰 번호에 1 더하기”도, 제목 줄 개수 세기도 범위의 뒷부분을 보지 못합니다. 그래서 이미 쓰인 번호가 “비어 있음”으로 통과했습니다. 누적해 보니 학습 번호 44개, 결정 번호 5개가 충돌해 있었습니다.
목록 유실 쪽에서는 더 결정적인 반증이 나왔습니다. “바꿀 원문이 달라지면 실패한다”는 안전장치는 동시 충돌만 잡고 누락은 못 잡습니다. 에이전트가 목록 전체를 새로 쓰면서 남의 항목 하나를 빠뜨리면, 원문은 정확히 일치하므로 수정은 성공합니다. 안전장치가 발동할 조건이 애초에 생기지 않습니다. 같은 기간 덧붙이기만 하는 세션 기록 쪽은 363개 커밋 동안 유실이 0건이었습니다. 같은 병렬 환경, 같은 에이전트인데 한쪽만 잃고 있었다는 뜻입니다.

진짜 원인은 무엇이었나? 통째로 다시 쓰기와 눈으로 세는 번호
원인은 병렬이 아니라 구조였습니다. 열린 작업 블록은 매번 통째로 다시 쓰는 방식이었고, 다시 쓰는 사람은 이전 내용을 전부 옮겨 적어야만 아무것도 잃지 않습니다. 병렬 세션은 그 사고율을 곱했을 뿐, 혼자 돌아도 다시 쓰는 순간마다 같은 위험이 있었습니다. 세션 기록이 유실 0건이었던 이유도 같은 데서 나옵니다. 덧붙이기만 하면 지울 기회 자체가 없습니다.
여기에 길이 제한이 겹쳤습니다. 다음 세션이 시작할 때 이 블록을 자동으로 읽어 넣는데, 읽어 넣는 분량이 32줄로 정해져 있습니다. 넘치면 뒷부분이 잘리니 누군가는 지워야 하고, 지우는 순간 근거 없이 사라집니다. 8월 4일 분석에서 작업을 실제로 멈춘 3건이 전부 이 지점에서 나왔습니다. 8월 10일에는 병렬 세션 둘이 서로 모르고 같은 32줄을 나눠 쓰다 한도를 넘겼는데, 잠금은 동시 실행만 줄 세울 뿐 분량은 아무도 보고 있지 않았습니다.
번호 문제의 원인도 같은 성격이었습니다. “번호를 확인하라”는 지시는 문장으로 있었지만, 지시가 권한 방법(제목 개수 세기)이 범위 표기를 못 읽었습니다. 규칙을 지켰는데 결과가 틀린 경우입니다. 정리하면 세 가지였습니다. 지울 수 있는 구조, 지우게 만드는 길이 제한, 그리고 맞게 셀 수 없는 확인 방법입니다. 셋 다 에이전트가 더 조심한다고 사라지는 문제가 아니었습니다.
어떻게 고쳤나? 문장으로 적힌 규칙을 명령과 커밋 검사로
방향은 하나였습니다. 실수를 하나씩 고치지 말고, 그 실수가 불가능한 구조로 바꾸기입니다. 마감 절차의 규칙을 “~하라”는 문장에서 실행하는 명령과 커밋 직전에 자동으로 도는 검사로 옮겼습니다. 문장은 에이전트가 읽고 지나칠 수 있지만, 커밋 검사는 통과하지 못하면 커밋 자체가 막힙니다. 검사를 건너뛰는 옵션(--no-verify)은 쓰지 않는 규칙으로 묶었습니다.
- 목록 누락 검사: 마지막 커밋의 열린 작업 항목 중 해소 근거 없이 사라진 것을 기계로 판정합니다. 걸리면 되살리거나 “제거된 항목(실측 해소): 근거” 한 줄을 남겨야 커밋이 통과합니다
- 소급 유실 감사: 누락 검사는 이번 커밋만 봅니다. 이 감사는 전체 이력을 거슬러 올라가 이미 사라져 아무도 모르는 항목을 찾고, 찾은 원문과 직전 커밋 위치를 별도 보관 파일에 남깁니다
- 분량 검사: 쓰기 직후 블록이 32줄을 넘으면 그 쓰기를 차단합니다. 넘치면 관찰 항목만 오래된 순서로 보관 파일에 옮기고 목록에는 위치 한 줄을 남기는 정리 명령을 씁니다. 사람 승인이 걸린 항목은 옮기지 않습니다
- 번호 발급 명령: 번호를 눈으로 세지 않고 명령으로 받습니다. 범위 표기를 펼쳐서 읽고, 연속 4개처럼 범위 제목용 번호도 한 번에 내줍니다
- 근거 포인터 의무: 항목마다 다음 세션이 직접 실행해 진위를 다시 확인할 수 있는 명령·파일 경로·커밋 위치를 붙입니다. 사람이 한 말에서 나온 항목은 대화 기록 파일 경로와 시각을 붙입니다
- 기한 표식: 측정 항목에 기한 표식을 달아, 목록에 남아 있는데 기한만 지나가는 경우를 따로 잡습니다
잠금은 새 구멍도 하나 만들었습니다. 잠금에 막힌 세션이 기다리지 않고 그냥 닫히면, 그 세션의 결론이 진행 문서에도 중간 저장본에도 남지 않습니다. 대화가 길어지면 자동으로 중간 저장본을 쓰는 훅이 있었지만, 대화 분량이 150K(토큰) 미만이면 아무것도 쓰지 않았습니다. 짧은 세션일수록 흔적이 0이 되는 구조였고, 실제로 결정 2건·학습 7건·목록 4건이 우연히 발견됐고 결정 1건은 30시간 동안 방치됐습니다. 그래서 잠금에 막혀 끝내야 하는 세션은 이름에 “deferred”가 들어간 보류 파일을 직접 남기게 했고, 다음 세션은 시작하자마자 그 파일을 읽어 문서에 반영한 뒤 지웁니다. 파일 삭제가 곧 완료 신호입니다.
근거 포인터도 처음 형태로는 부족했습니다. 7월 25일에는 근거 없이 며칠째 넘어오던 “설정 불일치 경로 8건” 항목이 이틀 전에 이미 해소된 유령이었습니다. 반대로 다른 저장소의 작업 요청(PR) 번호를 근거로 적은 항목은, 그 요청이 라이선스 문제로 폐기된 사실을 목록이 전혀 몰랐습니다. 그대로 실행했다면 여러 세션에 걸쳐 걷어낸 위험을 다시 들여왔을 상황입니다. 그래서 요청 번호 대신 파일의 현재 경로와 최신 커밋을 적게 하고, 이 형식도 세션이 열릴 때마다 기계로 검사합니다.

번호 발급 명령은 한 번 더 고쳐야 했습니다. 처음에는 절차 문서에 상대 경로로만 적혀 있었는데, 다른 폴더에서 연 세션에서는 그 경로에 파일이 없어 명령이 실패했습니다. 그러자 에이전트는 바로 아래 문단이 “안 통한다”고 적어 둔 옛 방식(제목 줄 정렬 후 마지막 값 읽기)으로 되돌아갔고, 2026년 8월 28일 같은 번호가 서로 다른 두 결정에 또 붙었습니다. 도구가 있어도 부를 수 없는 경로로 적혀 있으면 규칙은 그 자리에서 무효입니다. 경로를 절대 경로로 바꿨고, 다른 PC에서 쓰는 번호도 정본과 보관본을 전부 보고 발급하게 고쳤습니다. 같은 날 다른 PC에서 한 번호가 서로 다른 3개 항목에 재사용된 사례가 있었기 때문입니다.

재측정 결과: 유실 12건은 전부 검사 도입 이전이었다
2026년 8월 9일, 소급 유실 감사를 30개 저장소 전체에 처음 돌렸습니다. 영구 유실이 12건 나왔고, 12건 모두 목록 누락 검사를 커밋 단계에 연결한 8월 4일 이전에 몰려 있었습니다. 연결 이후 구간은 0건이었습니다. 처음 잰 때와 같은 방식(이력에서 근거 없이 사라진 항목 세기)으로 다시 잰 결과입니다. 찾은 12건은 “이미 끝났겠지”라고 판정해 지우지 않고, 원문과 직전 커밋 위치를 보관 파일에 남긴 뒤 목록에 위치 한 줄만 두었습니다.
측정 항목은 따로 한 번 더 지켰습니다. 처음에는 “8월 13일경 다시 확인” 같은 산문 날짜를 검사기가 읽었는데, 이 방식은 목록을 마지막으로 고친 시각을 기준으로 기한을 추정합니다. 그래서 목록을 다시 쓰면서 기한 지난 줄을 그대로 옮기면 기준 시각이 새로 찍혀 지난 기한이 보이지 않았습니다. 항목에 날짜를 박은 기한 표식을 달자 목록을 몇 번 다시 써도 기한이 지나면 계속 걸립니다. 기한을 못 지켰을 때는 지우지 않고 표식의 날짜를 새로 고칩니다. 미룬 기록이 남는 편이 사라지는 편보다 낫기 때문입니다.

번호 충돌은 한 번에 끝나지 않았습니다. 잠금만 있던 시기에 3건이 더 났고, 발급 명령을 만든 뒤에도 경로 문제로 8월 28일에 1건이 더 났습니다. 그때마다 원인을 고친 지점이 달랐습니다. 잠금은 동시 실행, 발급 명령은 세는 방식, 절대 경로는 “부를 수 있는가”를 해결했습니다. 누적 충돌(학습 번호 44개, 결정 번호 5개)은 해소 기록 문서에 정리해 두었습니다.
문서 크기 쪽은 정리 규칙을 붙였습니다. 열린 작업 블록은 파일 맨 위 10줄 안에 정확히 1개만 두고 매번 통째로 새로 쓰되, 앞서 말한 누락 검사가 그 다시 쓰기를 감시합니다. 14일 지난 보류 표시는 “당시 미결(동결)”로 바꿔 검색에서 현재처럼 읽히지 않게 했고, 문서가 1,500줄을 넘으면 30일 지난 구역을 월별 보관 파일로 옮깁니다. “현재 단계” 같은 두 번째 목록 사본은 만들지 않고, 있으면 마감 때 흡수합니다.
남는 한계는 무엇인가? 검사가 못 보는 곳과 안 도는 문장
누락 검사에는 시야의 끝이 있습니다. 이 검사는 마지막 커밋과 지금 작업 트리를 비교하므로, 옆 세션이 아직 커밋하지 않은 항목은 애초에 보이지 않습니다. 잠금이 마감 절차를 한 줄로 세워 그 틈을 줄이지만, 커밋 전에 남의 항목을 빠뜨리는 경우를 완전히 막지는 못합니다. 그래서 목록을 쓰기 직전에 다시 읽고, 내가 직접 닫은 항목이 아니면 문구 그대로 옮기는 규칙을 함께 둡니다.
동시 충돌이 실제로 났을 때의 절차도 사람 손이 아니라 에이전트 규율에 기대고 있습니다. 옆 세션이 먼저 목록을 고쳐 수정이 실패하면, 실패를 무시하거나 파일 전체를 덮어쓰지 않고 다시 읽은 뒤 상대가 쓴 항목의 근거를 확인해 내 항목과 합칩니다. 같은 작업 트리에서는 git이 끼어들 수 없어서 이 절차가 유일한 병합 지점인데, 이 단계가 매번 지켜졌는지를 센 숫자는 아직 없습니다.
문장으로만 남은 단계는 여전히 잘 돌지 않습니다. 마감 절차 맨 끝의 “다음 세션 인계” 단계가 처음에 명령이 아니라 문장으로 있었는데, 14일 동안 마감 128회 중 인계 줄을 남긴 횟수는 0회였습니다. 같은 30일 동안 인계를 다시 요청한 114건 중 60건이 마감 직후에 나왔습니다. 긴 문서 끝의 조건부 문장은 안 돈다는 같은 교훈이 다시 확인된 셈이라, 이 단계도 명령과 답변 종료 검사로 바꿨습니다. 효과는 아직 다시 재지 않았습니다.

사람이 내린 지적을 놓치는 문제도 남아 있습니다. 무엇을 기록할지 고르는 주체가, 그 세션에서 지적을 흘려들은 바로 그 에이전트이기 때문입니다. 8월 8일 실측에서 최근 14일 상위 지적 12건 중 4건이 규칙·메모리·목록 어디에도 없었습니다. 지금은 요약 대신 대화 원문에서 지적을 직접 긁어 대조하는 단계를 넣었지만, 이 단계의 효과도 아직 다시 잰 숫자가 없습니다. 비슷한 문제를 AI 에이전트의 기억 쪽에서 다룬 글은 기각한 아이디어를 AI 에이전트가 다시 꺼내는 문제에 있습니다.
여러 AI 세션을 같은 저장소에서 돌릴 때 먼저 볼 것
같은 저장소에서 AI 세션 여러 개를 동시에 돌리고 있다면, 잠금부터 넣기 전에 아래를 먼저 확인해 보시길 권합니다. 저희가 돌아간 순서를 거꾸로 밟으면 같은 시행착오를 줄일 수 있습니다.
- 공유 문서 중 통째로 다시 쓰는 구역과 덧붙이기만 하는 구역을 나눠 각각 유실 건수를 셉니다. 다시 쓰는 구역만 잃고 있다면 원인은 병렬이 아니라 구조입니다
- 다시 쓰는 구역에는 직전 커밋과 비교해 근거 없이 사라진 항목을 막는 커밋 검사를 붙입니다
- 자동으로 읽어 들이는 분량 한도가 있으면, 넘칠 때 지우지 말고 보관 파일로 옮기는 명령을 함께 만듭니다
- 일련번호는 사람도 AI도 눈으로 세지 않게 발급 명령으로 받습니다. 범위 표기를 쓰는 문서라면 더욱 그렇습니다
- 규칙 문서에 적힌 명령 경로가 다른 폴더에서 연 세션에서도 실행되는지 직접 돌려 봅니다
- “~하라”는 문장으로만 남은 단계가 실제로 몇 번 돌았는지 셉니다. 0이면 명령이나 검사로 바꿉니다
AI 에이전트를 실제 업무 절차에 묶어 쓰는 방식이 궁금하시면 상담으로 문의해 주세요. 저희 시스템에서 실제로 깨졌던 지점과 그 뒤에 붙인 검사를 기준으로 말씀드립니다.