AI › Claude Code
세션이 끝나면 Claude는 다 잊는다 — HANDOFF.md·Lessons.md·Plan Mode·TDD로 클로드 코드 완전 정복을 마치며
파트3(Hooks·Sub-agent·Plugin)까지 하고 나서 “이제 자동화는 끝났다” 싶었는데, 진짜 문제는 다른 데 있었다. 대화창을 닫고 다음날 다시 열면 어제 뭘 했는지 Claude가 하나도 기억을 못 했다. 이번 파트는 그 문제를 어떻게 풀었는지, 그리고 시리즈 전체를 마무리하면서 배운 마지막 조각들 얘기다.
HANDOFF.md — 매일 아침 어제 뭐 했는지부터 다시 설명하던 게 지겨워서
블로그 이 프로젝트 자체가 딱 이 문제를 겪고 있었다. 하루는 학습 로드맵 진행하고, 다음날 또 다른 세션에서 이어가는 식인데, 새 세션을 열 때마다 “저번에 어디까지 했더라”부터 다시 설명해야 했다. 심지어 저번에 이미 정리해뒀던 카테고리 규칙을 다시 설명한 적도 있었다.
지금 상태를 스냅샷으로 남기기
원리는 생각보다 단순했다. 세션이 끝나기 직전에 “완료한 것 / 현재 상태 / 바로 다음 작업” 딱 세 칸짜리 파일을 갱신해두는 것뿐이었다.
1
2
3
4
5
6
7
8
9
10
11
# HANDOFF
## 완료한 것
- Claude Code 파트3(Hooks·Sub-agent·Plugin) 학습 완료
- 포스트4 발행 완료
## 현재 상태
- 파트4(세션 관리) 진입 직전, 11단계 시작 안 함
## 바로 다음 작업
- /teach Claude Code 11단계 (HANDOFF.md + Lessons.md 시스템)
사실 이거 만들면서 깨달은 게, 이미 내가 글로벌 CLAUDE.md에 “진행상황_PLAN.md에 완료한 것/현재 상태/바로 다음 작업을 매 단계 갱신하라”는 규칙을 박아둔 적이 있었다. 그때는 그냥 “까먹지 말자” 정도로 만든 규칙이었는데, 알고 보니 이게 정식으로 이름 붙은 패턴이었다.

세션 루프로 정리해보니
이걸 루틴으로 만들면 세션 시작과 끝에 뭘 해야 하는지가 명확해진다.
1
2
3
4
5
세션 시작 ─→ HANDOFF.md 읽기 (완료/현재/다음 파악)
│
작업 진행
│
세션 종료 전 ─→ HANDOFF.md 갱신 (완료 체크, 다음 항목 교체)
이 블로그 프로젝트에서는 .claude/memory/학습진행도.md와 블로그현황.md가 사실상 이 역할을 하고 있다. /teach, /new-post 커맨드가 끝날 때마다 이 파일들을 갱신하도록 만들어둔 게, 결국 HANDOFF.md 패턴을 그대로 구현한 거였다.

갱신을 깜빡했다가 이미 끝난 작업을 또 시킬 뻔한 사건
한 번은 HANDOFF.md 비슷한 메모를 며칠째 안 갱신한 채로 방치한 적이 있다. 새 세션에서 “다음 작업”란에 적힌 대로 시켰는데, 뭔가 이상했다.
추정 — 처음엔 그냥 “오늘 컨디션이 이상한가” 싶었다. 이미 끝낸 리팩터링을 또 하라고 시킨 것 같은 느낌적인 느낌이었다.
소거 — Claude가 딴생각을 한 건 아니었다. 시킨 그대로, 메모에 적힌 “다음 작업”을 정확히 수행하고 있었다. 문제는 Claude 쪽이 아니라 메모 쪽이었다.
검증 — 메모 파일의 마지막 수정 날짜를 보니 사흘 전이었다. 그 사이 이미 그 작업을 끝냈는데 메모를 안 고쳐놨던 거다. Claude 입장에선 “다음 작업”이라고 적힌 걸 그대로 믿을 수밖에 없었다.
1
2
3
4
5
문제 있는 흐름:
작업 완료 → (메모 갱신 안 함) → 새 세션 → 사흘 전 메모 그대로 읽음 → 이미 끝난 작업 재실행
고쳐야 할 습관:
작업 완료 → 메모 즉시 갱신 → 새 세션 → 최신 상태 읽음 → 다음 작업만 진행
“메모를 남긴다”는 것보다 “메모를 세션 끝날 때마다 갱신한다”는 습관이 진짜 핵심이었다. 안 갱신된 HANDOFF.md는 없느니만 못하다는 걸 이때 알았다.
Lessons.md — 같은 삽질을 세 번째 반복하고 나서야 만든 파일
HANDOFF.md만 있으면 될 줄 알았는데, 다른 문제가 남아 있었다. “지난번에 이거 왜 안 됐더라” 싶은 것들이 있는데, HANDOFF.md는 매번 새로 덮어쓰는 파일이라 예전 삽질 기록이 남아있질 않았다.
상태 파일과 지식 파일은 다른 물건이었다
회사에서 인수인계서랑 사내 위키를 따로 쓰는 이유를 생각해보니 답이 나왔다. 인수인계서는 “지금 상태”를 담는 거라 매번 새로 쓰는 게 맞고, 위키는 “쌓인 노하우”를 담는 거라 계속 누적돼야 한다. 이 둘을 한 파일에 합치면, 인수인계서 볼 때마다 몇 달 전 노하우까지 다시 읽어야 해서 오히려 비효율적이다.
1
2
3
4
5
6
7
8
# Lessons
## DB 마이그레이션
- 프로덕션 마이그레이션 전엔 반드시 스테이징에서 먼저 실행할 것
이유: 컬럼 타입 변경 마이그레이션을 스테이징 없이 바로 적용했다가 인덱스가 깨진 적 있음
## 인증
- JWT secret은 절대 코드에 하드코딩하지 말 것 (환경변수만)
Lessons.md는 “규칙 + 왜”로 적는 게 핵심이었다. 이유 없이 규칙만 적으면, 나중에 상황이 바뀌었을 때 이 규칙을 계속 지켜야 하는지 판단할 근거가 없어진다.
파일이 너무 커져서 오히려 세션 시작이 느려진 일
Lessons.md를 쓰기 시작한 지 얼마 안 됐는데도 벌써 체감이 왔다. 처음엔 세션 시작할 때 이 파일 읽는 게 순식간이었는데, 몇 주 지나니 파일이 꽤 길어졌다.
추정 — “그냥 파일이 커진 거니까 어쩔 수 없다”고 넘기려고 했다.
소거 — 근데 자세히 보니 같은 내용이 표현만 다르게 두세 번 적혀 있었다. 파일이 커진 진짜 이유는 “쌓여서”가 아니라 “정리를 안 해서”였다.
검증 — Anthropic이 만든 consolidate-memory라는 스킬이 정확히 이 문제를 겨냥하고 있었다. 중복되거나 오래돼서 더 이상 안 맞는 항목을 주기적으로 병합·정리하는 역할이다. 실제로 이 스킬로 한 번 정리하고 나니 파일이 절반 가까이 줄었다.
1
2
정리 전: Lessons.md 47줄, 그중 겹치는 내용 3쌍
정리 후: Lessons.md 28줄, 중복 제거 + 오래된 항목 요약
쌓아두기만 하고 안 치우면 창고나 마찬가지라는 걸, 파일 하나로 배웠다.

언제 CLAUDE.md로 옮길지 — 반복 피드백을 규칙으로 승격하는 기준
HANDOFF.md랑 Lessons.md를 둘 다 쓰다 보니 세 번째 질문이 생겼다. “이거 계속 반복해서 말해줘야 하나?” 싶은 것들, 예를 들면 “코드 고치면 테스트도 같이 짜줘” 같은 요청은 언제 CLAUDE.md에 아예 박아넣어야 할까.
1회는 기록, 2회부터는 승격 후보
기준을 정하지 않으면 두 가지로 망한다. 매번 즉시 CLAUDE.md에 박아넣으면 파일이 잡동사니 창고가 되고, 전혀 안 옮기면 매 세션 같은 말을 반복해야 한다. 그래서 “2회 이상 반복” 또는 “사용자가 명시적으로 항상 지켜달라고 요청”이라는 조건을 기준으로 삼기로 했다.
1
2
3
4
5
6
7
# Lessons.md (1회차 — 그냥 기록만)
## 테스트
- 코드 변경 시 테스트도 같이 짜달라고 요청함
# Lessons.md (2회차 — 반복 감지, 승격 후보)
## 테스트
- 코드 변경 시 테스트 요청이 2번째. 승격 후보.
1
2
3
# CLAUDE.md (승격 완료 후)
## 코딩 원칙
- 코드 변경 시 테스트 코드도 함께 작성한다 (매번 명시할 필요 없음)
승격하고 나면 Lessons.md에 남아있던 임시 메모는 지우거나 요약해서 정리한다. 같은 내용이 두 파일에 겹쳐 있으면 나중에 뭐가 최신인지 헷갈리기 때문이다.
이번 대화 앞부분에서 실제로 이 흐름이 동작하는 걸 직접 봤다. 내가 쓰는 Auto memory 시스템의 “feedback” 타입 메모리가 정확히 이 역할이었다. 접근법을 교정하거나 확인해줄 때마다 저장되고, 반복되면 사실상 영구 규칙처럼 취급된다. 이 블로그 프로젝트의 CLAUDE.md에 있는 “세션 시작 시 반드시 브리핑 출력” 규칙도, 아마 처음엔 한두 번 요청했던 게 반복되면서 승격된 결과였을 거다.

세 파일을 읽는 순서까지 정리하니
이걸 다 정리하고 나니 세션 경계에서 뭘 언제 읽고 쓰는지가 명확해졌다.
1
2
3
4
5
6
7
8
9
10
11
12
세션 시작
├─ CLAUDE.md 읽기 (영구 규칙, 항상 로드)
├─ HANDOFF.md 읽기 (현재 상태)
└─ Lessons.md 읽기 (최근 교훈)
세션 진행 중
└─ 같은 피드백이 2번째 나오면 → 승격 후보 표시
세션 종료
├─ HANDOFF.md 갱신
├─ 새 교훈 있으면 Lessons.md에 추가
└─ 승격 후보 있으면 → CLAUDE.md로 이동
세 파일 각각의 역할이 겹치지 않게 나눠지니까, 어디에 뭘 적어야 할지 헷갈리는 일이 확실히 줄었다.

Plan Mode — 계획 없이 시켰다가 완전히 다른 방향으로 리팩터링된 사건
세션 관리는 이 정도로 정리됐는데, 마지막으로 배운 두 가지는 세션 안에서의 문제였다. 결제 모듈 하나를 리팩터링해달라고 바로 시켰다가, 완전히 다른 구조로 바뀐 걸 뒤늦게 발견한 적이 있다.
도면부터 보고 승인한 다음 착공하기
인테리어 업자한테 “거실 리모델링 해주세요”라고만 말하고 자리를 비우면 안 되는 거랑 똑같은 문제였다. 공사 전에 도면을 먼저 보여달라고 해야 원하는 방향인지 확인할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
사용자: "결제 모듈을 리팩터링해줘"
Claude (Plan Mode):
계획:
1. PaymentService의 검증 로직을 별도 클래스로 분리
2. 기존 테스트 12개가 계속 통과하는지 확인
3. 새 클래스에 대한 단위 테스트 추가
이대로 진행할까요?
사용자: "2번은 좋은데 1번에서 검증 로직 말고 로깅 로직만 먼저 빼줘"
→ 계획 단계에서 방향을 바로잡음. 실제 코드는 아직 한 줄도 안 바뀜.
이걸 겪고 나서 글로벌 CLAUDE.md에 “모든 작업은 Plan 모드로 시작, 승인 후 실행”이라는 규칙을 넣었다. 지금 이 글을 쓰는 이 대화도 사실 그 규칙대로 계획 단계를 거쳐서 진행되고 있다.
작은 수정까지 매번 계획 단계를 거치면 오히려 느려지길래, “되돌리기 쉬운 작업이면 바로, 되돌리기 어려운 작업이면 계획부터”로 기준을 나눴다. 오타 수정하는 데까지 도면을 그리고 있을 필요는 없으니까.

TDD — 테스트를 나중에 짰다가 조용히 통과된 버그
Plan Mode가 “방향”을 검토하는 거라면, TDD는 “완성 기준”을 미리 정해두는 문제였다. 구현부터 하고 나중에 테스트를 짰더니, 테스트가 구현에 맞춰져서 있으나 마나 한 상황이 생겼다.
실패하는 테스트부터 쓰고 나서
순서를 뒤집어봤다. 구현 없이 “무엇이 되면 성공인지”부터 코드로 적어두는 거다.
1
2
3
4
5
6
7
8
9
10
11
12
# 1단계: 실패하는 테스트부터 작성 (아직 구현 없음)
def test_apply_discount_rejects_negative_price():
with pytest.raises(ValueError):
apply_discount(price=-1000, rate=0.1) # 가격이 음수면 예외가 나야 한다
# 2단계: 테스트를 통과시키는 최소 구현
def apply_discount(price, rate):
if price < 0:
raise ValueError("price must be non-negative") # 테스트가 요구한 조건만 구현
return price * (1 - rate)
# 3단계: 테스트 통과 확인 후, 이제 안전하게 리팩터링 가능
이 순서로 하니까 확실히 달랐다. 구현이 테스트를 맞추는 게 아니라, 테스트가 구현을 이끄는 구조였다. verify 스킬이나 code-review 스킬도 결국 이 “확인” 단계를 팀 차원에서 굳혀놓은 것들이었다.
추정 — 예전에 “테스트 통과했어요”라는 보고를 받고 넘어갔는데, 나중에 특이한 입력값에서 조용히 터진 적이 있었다. 처음엔 테스트 개수가 부족해서 그런 줄 알았다.
소거 — 테스트 개수는 12개나 있었다. 개수 문제는 아니었다.
검증 — 테스트 코드를 다시 보니, 전부 구현이 끝난 다음에 “이렇게 동작하는구나”를 확인만 하는 식으로 짜여 있었다. 버그가 있는 채로 구현됐으면, 테스트도 그 버그를 그대로 통과하도록 맞춰져 있었던 거다.
1
2
❌ 구현 후 테스트 작성: 테스트가 버그까지 통과하도록 맞춰짐
✅ 테스트 먼저 작성: 구현이 테스트(성공 기준)에 맞춰짐
순서 하나 바꾼 것뿐인데, “통과했다”는 말의 신뢰도가 완전히 달라졌다.

13단계를 다 배우고 나서
6월 11일에 “Claude Code를 챗봇으로 쓰고 있었다”는 걸 깨달으면서 시작한 시리즈가 여기서 끝났다. 환경 구축, 요청 아키텍처, 자동화, 세션 관리, 마지막으로 Plan Mode와 TDD까지 13단계를 거치면서, 결국 하나로 압축됐다.
| 순서 | 체크 항목 | 관련 단계 |
|---|---|---|
| 1 | CLAUDE.md에 프로젝트 규칙이 정리돼 있는가 | 2~3단계 |
| 2 | 반복 작업은 Skill로, 사용자 성향은 Auto Memory로 분리했는가 | 4단계 |
| 3 | 요청할 때 5요소(목표·범위·제약·검증·완료조건)를 갖췄는가 | 5단계 |
| 4 | 수정 요청은 “좁은 수정”으로 범위를 한정했는가 | 6단계 |
| 5 | 완료 보고 전에 5계층 검증을 거쳤는가 | 7단계 |
| 6 | 반복 자동화가 필요하면 Hooks/Sub-agent/Plugin을 검토했는가 | 8~10단계 |
| 7 | 세션 종료 전 HANDOFF.md를 갱신했는가 | 11단계 |
| 8 | 반복된 피드백은 Lessons.md → CLAUDE.md로 승격했는가 | 12단계 |
| 9 | 되돌리기 어려운 작업은 Plan Mode로 계획부터 승인받았는가 | 13단계 |
| 10 | 구현 전에 테스트(성공 기준)부터 정의했는가 | 13단계 |
세팅 전후로 체감이 달라진 걸 정리해봤다.
| 지표 | 세팅 전 | 세팅 후 |
|---|---|---|
| 새 세션 맥락 파악 시간 | 이전 대화 스크롤, 5분 이상 | HANDOFF.md 읽고 1분 내 |
| 같은 피드백 반복 횟수 | 세션마다 반복 | 2회 승격 후 0회 |
| 큰 작업 방향 오류로 인한 재작업 | 종종 발생 | Plan Mode 승인 단계에서 조기 차단 |

돌이켜보면 파트1에서 배운 CLAUDE.md 하나로 시작해서, 결국 CLAUDE.md·HANDOFF.md·Lessons.md 세 파일이 각자 역할을 나눠 맡고, 그 위에 Plan Mode와 TDD로 “어떻게 시킬지”까지 얹은 구조가 됐다. 다음엔 이 체크리스트를 실제 팀 프로젝트에 그대로 적용해볼 생각이다.