BurningTimesAi/공유/소통/완료/2026-04-16_핫리로드대안_기술검토_개발팀.md

17 KiB

CLAUDE.md 핫 리로드 대안 — 기술 검토 보고서

작성: 개발팀장 (PD님 지시, 2026-04-16) 대상: 총괄PM 목적: PD님이 제안한 "CLAUDE.md 핫 리로드 대안(공용 임시 md 파일)" 구현의 기술적 실현 가능성 검토


1. Claude Code의 CLAUDE.md 로드 메커니즘 — 사실 기반 분석

1-1. CLAUDE.md 로드 시점

Claude Code의 CLAUDE.md 처리는 두 가지 수준에서 발생한다.

수준 시점 동작
디스크 읽기 세션 시작, /compact 후, 서브디렉토리 파일 접근 시 .md 파일을 디스크에서 읽어 메모리에 적재
API 전송 매 턴(every turn) 메모리에 적재된 CLAUDE.md 내용을 API 요청의 시스템 프롬프트 영역에 포함하여 전송

핵심 사실: Claude Code는 매 API 호출마다 시스템 프롬프트 + 도구 정의 + CLAUDE.md + 대화 이력 전체를 재전송한다. 프롬프트 캐싱(prompt caching)으로 비용은 최적화되지만, 구조적으로 매 턴 재전송은 사실이다.

그러나 CLAUDE.md를 디스크에서 재읽기하는 시점은 제한적이다:

  1. 세션 시작 시 — 프로젝트 루트 및 상위 디렉토리의 CLAUDE.md, CLAUDE.local.md를 전부 읽음
  2. /compact — 프로젝트 루트 CLAUDE.md만 디스크에서 재읽기 + 재주입
  3. 서브디렉토리 파일 접근 시 — 해당 서브디렉토리의 CLAUDE.md를 lazy load
  4. 서브에이전트(Agent/Task) 생성 시 — 새 인스턴스가 CLAUDE.md를 독립적으로 로드

결론: 세션 중간에 CLAUDE.md를 외부에서 수정하더라도, 에이전트가 Read 도구로 명시적으로 읽지 않는 한 변경분은 자동 반영되지 않는다. 단, /compact 시에는 루트 CLAUDE.md만 재읽기된다.

1-2. @파일경로 import 구문의 동작

공식 문서 확인 결과:

  • @path/to/import 구문으로 외부 파일을 임포트 가능
  • 임포트된 파일은 "세션 시작 시(at launch)" 확장(expand)되어 컨텍스트에 적재
  • 최대 재귀 깊이 5단계
  • 상대 경로는 임포트를 포함하는 파일 기준으로 해석

핵심 한계: @CLAUDE_LIVE.md 같은 임포트를 넣어도, 해당 파일은 세션 시작 시 1회만 읽힌다. 세션 중간에 CLAUDE_LIVE.md를 수정해도 자동 반영되지 않는다.

1-3. system-reminder 태그의 원리

Claude Code는 <system-reminder> XML 태그를 사용하여 매 턴 동적 컨텍스트를 주입한다.

  • 시스템 프롬프트(정적, 캐싱됨)와 달리, system-reminder메시지 배열(messages array) 에 삽입
  • 프롬프트 캐시를 깨뜨리지 않으면서 동적 정보(날짜, 파일 상태, git 상태 등)를 주입
  • Claude는 이 태그를 "높은 우선도 컨텍스트"로 취급
  • 반응형(reactive): 주기적이 아니라 특정 조건(파일 수정, 도구 사용, 컨텍스트 전환)에 따라 주입

이것이 PD님 제안의 핵심 실현 경로가 될 수 있다.

1-4. hooks의 컨텍스트 주입 능력

Hook 이벤트 발화 시점 stdout 처리 한도
SessionStart 세션 시작/재개/clear/compact stdout → 에이전트 컨텍스트 주입 10,000자
UserPromptSubmit 사용자 프롬프트 제출 시 (매 턴) stdout → 에이전트 컨텍스트 주입 10,000자
PreToolUse 도구 실행 전 updatedInput 가능 10,000자
PostToolUse 도구 실행 후 additionalContext 가능 10,000자

UserPromptSubmit이 "매 턴 자동 실행"되므로, 여기서 파일을 읽어 stdout으로 출력하면 에이전트 컨텍스트에 매 턴 주입이 가능하다.

JSON 구조 옵션:

{
  "additionalContext": "파일 내용을 여기에..."
}

또는 단순 텍스트 출력도 컨텍스트에 주입된다.

알려진 이슈: UserPromptSubmit hook에서 JSON 출력 시 새 세션 첫 메시지에서 에러가 표시되는 버그가 보고되어 있음 (GitHub Issue #17550). 단순 텍스트 출력이 더 안정적.


2. 공용 임시 파일 방안의 기술적 실현성 분석

2-1. PD님 원안: CLAUDE_LIVE.md 접근법

PD님 제안의 핵심 목표:

  • 세션 시작 후에도 계속 업데이트·참조 가능한 공유 파일
  • 여러 세션이 동시에 읽고 쓸 수 있음
  • 일정 주기 또는 세션 재시작 시 메인 CLAUDE.md로 동기화

2-2. 실현 가능한 3가지 경로

경로 A: @CLAUDE_LIVE.md import (CLAUDE.md 내 import)

# CLAUDE.md 내부
@CLAUDE_LIVE.md
항목 평가
자동 로드 세션 시작 시 1회만. 세션 중 갱신 불가
토큰 비용 세션 시작 시 고정비에 편입
동시 쓰기 파일 자체는 가능하나 반영이 안 되므로 무의미
판정 불가 — PD님 요구(세션 중 동적 갱신) 미충족

경로 B: UserPromptSubmit hook으로 매 턴 파일 읽기 + 컨텍스트 주입

#!/bin/bash
# UserPromptSubmit hook
LIVE_FILE="$(git rev-parse --show-toplevel 2>/dev/null)/CLAUDE_LIVE.md"
if [ -f "$LIVE_FILE" ]; then
  CONTENT=$(head -c 9500 "$LIVE_FILE")  # 10,000자 한도 고려
  echo "$CONTENT"
fi
exit 0
항목 평가
자동 로드 매 턴 자동 (UserPromptSubmit 발화 시)
토큰 비용 매 턴 변동비 증가 (파일 크기만큼)
동시 쓰기 git 기반이면 commit/push/pull 필요. 로컬 파일이면 즉시 반영
10,000자 한도 CLAUDE_LIVE.md가 10,000자 초과 시 잘림
판정 기술적으로 가능 — PD님 요구 충족. 단, 토큰 비용·한도 제약 존재

경로 C: SessionStart hook + /compact 트리거 조합

#!/bin/bash
# SessionStart hook (resume, compact 매처 포함)
LIVE_FILE="$(git rev-parse --show-toplevel 2>/dev/null)/CLAUDE_LIVE.md"
if [ -f "$LIVE_FILE" ]; then
  CONTENT=$(head -c 9500 "$LIVE_FILE")
  echo "$CONTENT"
fi
exit 0
항목 평가
자동 로드 세션 시작/재개/compact 시에만
토큰 비용 경로 B보다 낮음 (세션 시작 시 1회 고정비)
동시 쓰기 가능하나 반영은 세션 재시작 또는 compact 시에만
판정 부분 실현 — 세션 재시작/compact 시만 반영. 실시간성 부족

2-3. 실현 가능성 종합

경로 PD님 요구 충족도 구현 난이도 토큰 비용 안정성
A. @import 불가 매우 낮음 고정비 높음
B. UserPromptSubmit 충족 낮음 매 턴 변동비 중 (버그 존재)
C. SessionStart 부분 충족 낮음 세션 시작 고정비 높음
B+C 혼합 충족 낮음 절충 가능 중~높음

3. 권장 구현 방안

3-1. 권장안: 경로 B+C 혼합 — "UserPromptSubmit 조건부 읽기 + SessionStart 전량 읽기"

기본 구조:

D:/NerdNavis/NerdNavisAi/
├── CLAUDE.md              ← 정적 규칙 (세션 시작 시 로드, 변경 빈도 낮음)
├── CLAUDE_LIVE.md          ← 동적 공유 파일 (세션 중 갱신 가능)
└── .claude/settings.json   ← hooks 설정

SessionStart hook (세션 시작 시 전량 주입):

#!/bin/bash
LIVE_FILE="$(git rev-parse --show-toplevel 2>/dev/null)/CLAUDE_LIVE.md"
if [ -f "$LIVE_FILE" ]; then
  CONTENT=$(head -c 9500 "$LIVE_FILE")
  echo "[CLAUDE_LIVE 로드] 세션 시작 시점 스냅샷:"
  echo "$CONTENT"
fi
exit 0

UserPromptSubmit hook (변경 감지 시에만 주입 — throttle + diff 체크):

#!/bin/bash
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
LIVE_FILE="$REPO_ROOT/CLAUDE_LIVE.md"
[ ! -f "$LIVE_FILE" ] && exit 0

THROTTLE_DIR="$HOME/.claude/.nerdnavis_throttle"
mkdir -p "$THROTTLE_DIR" 2>/dev/null
HASH_FILE="$THROTTLE_DIR/live_md_hash"

CURRENT_HASH=$(sha1sum "$LIVE_FILE" 2>/dev/null | cut -d' ' -f1)
PREV_HASH=$(cat "$HASH_FILE" 2>/dev/null)

if [ "$CURRENT_HASH" != "$PREV_HASH" ]; then
  CONTENT=$(head -c 9500 "$LIVE_FILE")
  echo "[CLAUDE_LIVE 갱신 감지]"
  echo "$CONTENT"
  echo "$CURRENT_HASH" > "$HASH_FILE"
fi
exit 0

핵심 설계 의도:

  1. SessionStart: 세션 시작 시 CLAUDE_LIVE.md 전량을 컨텍스트에 주입 (초기 상태 인지)
  2. UserPromptSubmit: 매 턴 SHA1 해시만 비교하고, 변경이 있을 때만 파일 내용을 주입 (토큰 절감)
  3. 변경이 없는 턴에서는 해시 비교만 수행하므로 오버헤드 최소화

3-2. CLAUDE_LIVE.md 파일 설계

파일 위치: 레포 루트 CLAUDE_LIVE.md git 추적: .gitignore 미포함 — git으로 추적하여 세션 간 공유 최대 크기: 9,500자 이내 (10,000자 한도 - 헤더 여유분) 형식:

# CLAUDE_LIVE — 실시간 조직 공유 컨텍스트
> 최종 갱신: 2026-04-16 14:30 by PM

## 긴급 공지
- (없음)

## 활성 HOLD
- (없음)

## 현재 진행 작업 (부서별)
### 개발팀
- Tier 1 구현 진행 중

### 기획팀
- Stage 14~18 밸런싱 진행 중

## 최근 규칙 변경
- C26 Skill 패킹 전환 (2026-04-16)

갱신 주체:

  • 총괄PM이 주 갱신자 (조율·공지 역할)
  • 각 팀장이 자기 섹션 갱신 가능
  • PD님이 직접 긴급 공지를 작성할 수도 있음

3-3. 메인 CLAUDE.md와의 동기화

시점 동작 책임
규칙 변경 확정 시 CLAUDE_LIVE.md의 "최근 규칙 변경" → CLAUDE.md 본문 반영 총괄PM
세션 종료 시 CLAUDE_LIVE.md의 임시 항목 정리 (완료·소멸 항목 삭제) PM
정기적 잔류 항목이 영구화 대상인지 판단 → CLAUDE.md 또는 SKILL.md 편입 PM

동기화 방향: CLAUDE_LIVE.md → CLAUDE.md (단방향). CLAUDE.md의 변경은 세션 재시작으로 자연 반영되므로 역방향 동기화는 불필요.


4. 리스크 및 한계 분석

4-1. 동시 쓰기 문제

시나리오 위험도 대응
같은 PC, 복수 CLI 세션이 동시 write 높음 — 파일 덮어쓰기 경합 단일 세션 구조(C24)에서는 발생 가능성 낮음. Agent 서브에이전트는 순차 실행이므로 동시 write 없음
다른 PC, git push/pull 경유 중간 — merge conflict 가능 섹션별 분리(개발팀/기획팀)로 충돌 최소화. 충돌 시 git이 감지
PD님이 직접 편집 + 에이전트 편집 동시 낮음 — 시간차 존재 CLAUDE_LIVE.md 편집 시 git commit/push 전까지 로컬 한정

단일 세션 구조(C24) 하에서는 동시 쓰기 문제가 구조적으로 크게 완화된다. PM 세션 1개에서 Agent 도구로 부서를 순차/병렬 호출하므로, 파일 쓰기 경합은 Agent 도구의 직렬화에 의해 관리된다.

4-2. 토큰 비용 증가 (C14 정합성)

항목 비용 C14 영향
SessionStart 1회 전량 주입 최대 9,500자 (~1,200 토큰) 고정비 증가 — C14-3에 따라 PD님 승인 필요
UserPromptSubmit 변경 감지 시 변경 없으면 0, 변경 시 ~1,200 토큰 조건부 변동비 — 대부분의 턴에서 0
해시 비교 오버헤드 무시 가능 (sha1sum 1회) 없음

결론: 변경 감지 방식을 채택하면 대부분의 턴에서 추가 토큰 비용 0. 세션 시작 시에만 ~1,200 토큰 고정비 추가. 기존 CLAUDE.md 고정비 대비 약 10~15% 추가 수준으로, C14 관점에서 수용 가능 범위.

4-3. 10,000자 한도

  • hook stdout 출력 한도가 10,000자
  • CLAUDE_LIVE.md를 9,500자 이내로 유지해야 함
  • 초과 시 파일로 저장되고 미리보기만 컨텍스트에 주입 → 에이전트가 별도 Read 필요
  • 대응: CLAUDE_LIVE.md는 "긴급·활성 정보만" 담는 경량 파일로 운용. 상세 내용은 별도 파일에 두고 경로만 명시

4-4. 보안·무결성

위험 평가 대응
임시 파일이 메인 CLAUDE.md를 오염 매우 낮음 — 동기화는 PM 수동 판단 자동 동기화 금지. 방향: LIVE → CLAUDE.md, 수동 한정
악의적 내용 주입 낮음 — git 추적으로 변경 이력 추적 git blame으로 누가 언제 수정했는지 추적 가능
hook 스크립트의 보안 낮음.claude/settings.json에서 관리 기존 hook과 동일한 보안 수준

4-5. 기존 hook과의 상호작용

현재 UserPromptSubmitgit_fetch_throttle.shhold_watch.sh가 등록되어 있다. 신규 hook 추가 시:

  • 복수 hook의 stdout는 연결(concatenate) 되어 에이전트에 주입
  • 10,000자 한도는 hook별이 아니라 전체 합산인지 확인 필요 (공식 문서에서 "per hook"로 명시)
  • 기존 hook의 stdout 출력과 간섭하지 않도록 설계 필요

4-6. 알려진 버그

  • GitHub Issue #13912: UserPromptSubmit hook의 stdout이 에러를 유발한다는 보고 (문서와 모순)
  • GitHub Issue #17550: JSON hookSpecificOutput 사용 시 새 세션 첫 메시지에서 에러 표시
  • 대응: 단순 텍스트 출력 방식 우선 채택. JSON 방식은 버그 해결 확인 후 전환

5. 대안 검토

5-1. .claude/rules/ 디렉토리 활용

.claude/rules/ 하위의 .md 파일은 세션 시작 시 자동 로드된다. paths frontmatter 없는 규칙은 무조건 로드.

  • CLAUDE_LIVE.md를 .claude/rules/live.md로 배치하면 세션 시작 시 자동 포함
  • 그러나 세션 중 동적 갱신은 불가 (경로 A와 동일한 한계)
  • .claude/rules/의 파일도 세션 시작 시 1회 로드 후 변경 감지 안 됨

판정: 동적 갱신 불가로 PD님 요구 미충족.

5-2. /compact 트리거를 통한 강제 재로드

  • /compact 실행 시 프로젝트 루트 CLAUDE.md가 디스크에서 재읽기됨
  • CLAUDE.md에 @CLAUDE_LIVE.md import가 있다면, /compact 시 재확장 여부는 미확인 (공식 문서 미언급)
  • 수동 /compact 실행이 필요하므로 "자동" 요건 미충족
  • GitHub Issue #22085: /compact 시 자동 재로드 기능 요청이 올라와 있으나 미구현

판정: 수동 트리거 의존으로 자동성 부족. 보조 수단으로만 활용 가능.

5-3. /reload 커스텀 Skill 방식

  • Skill 파일에 /reload 명령을 정의하고, SIGHUP으로 Claude 프로세스를 재시작하는 접근법이 커뮤니티에서 공유됨
  • 세션 재시작 = CLAUDE.md 재로드, 그러나 대화 컨텍스트 일부 소실
  • --continue 플래그로 이전 세션 재개 가능하나 사용성 저하

판정: 급진적 해결이나 사용성 비용이 높음. 비권장.


6. 최종 결론 및 권장

6-1. 기술적 실현 판정

PD님의 "공용 임시 md 파일" 구상은 기술적으로 실현 가능하다.

최적 경로는 **UserPromptSubmit hook에서 변경 감지 후 조건부 주입(경로 B+C 혼합)**이며, 이는:

  1. 기존 hook 인프라(.claude/settings.json)에 자연스럽게 통합 가능
  2. 매 턴 해시 비교만 수행하여 토큰 비용 최소화
  3. 변경 시에만 주입하여 C14(토큰 최소화) 준수
  4. 단일 세션 구조(C24)에서 동시 쓰기 문제 자연 완화

6-2. 구현 시 PD님 결정 필요 사항

  1. CLAUDE_LIVE.md의 git 추적 여부 — 추적(세션 간 공유) vs .gitignore(PC별 독립)
  2. C14-3 고정비 증가 승인 — 세션 시작 시 ~1,200 토큰 추가 고정비
  3. 구현 착수 여부 — 본 검토 결과를 바탕으로 착수 지시

6-3. 구현 시 개발팀 예상 작업

  1. scripts/live_context_inject.sh 신규 작성 (UserPromptSubmit hook)
  2. scripts/live_session_load.sh 신규 작성 (SessionStart hook)
  3. .claude/settings.json hook 등록 추가
  4. CLAUDE_LIVE.md 템플릿 작성
  5. 기존 hook과의 상호작용 검증

참고 자료