feat(live): P25 Live 증분 동기화 체계 구현 (PD님 직접 지시)

세션 중 반영 불가 파일 9종의 변경을 즉시 반영하는 체계:
- .claude/live/ 파일별 더미 + 증분 읽기
- live_inject.sh: UserPromptSubmit hook (추가분만 주입, 변경 없으면 토큰 0)
- live_session_load.sh: SessionStart hook (전량 1회 로드)
- P25 코어룰 명문화 + P21-2 세션 공유에 Live 비우기 편입
- settings.json hook 등록

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-04-16 20:50:14 +09:00
parent d6bf349b20
commit 5b6cfe3342
4 changed files with 154 additions and 4 deletions

View File

@ -57,6 +57,10 @@
{ {
"type": "command", "type": "command",
"command": "bash scripts/change_digest.sh 2>/dev/null || true" "command": "bash scripts/change_digest.sh 2>/dev/null || true"
},
{
"type": "command",
"command": "bash scripts/live_session_load.sh 2>/dev/null || true"
} }
] ]
} }
@ -72,6 +76,10 @@
{ {
"type": "command", "type": "command",
"command": "bash scripts/hold_watch.sh 2>/dev/null || true" "command": "bash scripts/hold_watch.sh 2>/dev/null || true"
},
{
"type": "command",
"command": "bash scripts/live_inject.sh 2>/dev/null || true"
} }
] ]
} }

View File

@ -733,10 +733,12 @@ PD님이 **"세션 갱신"**이라고 지시하면, PM 단일 세션 에이전
PD님이 **"세션 공유"**라고 지시하면, 현재 세션의 모든 변경사항을 **즉시 git commit + push**하여 다른 세션에서 접근 가능하게 만든다. PD님에게 추가 확인을 요청하지 않는다. PD님이 **"세션 공유"**라고 지시하면, 현재 세션의 모든 변경사항을 **즉시 git commit + push**하여 다른 세션에서 접근 가능하게 만든다. PD님에게 추가 확인을 요청하지 않는다.
### 수행 절차 ### 수행 절차
1. `git add -A` 1. `.claude/live/` 더미 파일 내용을 원본에 반영 (아직 미반영분이 있다면)
2. `git commit` (변경 내용 요약 메시지 자동 생성) 2. `.claude/live/` 더미 파일 비우기 (README.md 제외)
3. `git push origin main` 3. `git add -A`
4. 완료 보고 (1줄) 4. `git commit` (변경 내용 요약 메시지 자동 생성)
5. `git push origin main`
6. 완료 보고 (1줄)
### 트리거 표현 ### 트리거 표현
- "세션 공유" - "세션 공유"
@ -877,6 +879,43 @@ grep -r "기각안" 공유/대화로그/ # 기각 이유 추적
| **P24 (대화로그)** | "논의 맥락·경위·기각 이유" | 상위 근거 | | **P24 (대화로그)** | "논의 맥락·경위·기각 이유" | 상위 근거 |
| ~~P20 (일일보고)~~ | 폐기 — P24로 대체 | - | | ~~P20 (일일보고)~~ | 폐기 — P24로 대체 | - |
## P25. Live 증분 동기화 체계 (2026-04-16 PD님 직접 지시)
> 세션 시작 후 변경된 설정·규칙·에이전트 정의를 **세션 갱신 없이 즉시 반영**하기 위한 임시 더미 파일 체계. 원본 수정 + 더미 기록의 이중 반영으로, 현재 세션은 hook이 즉시 주입하고 다음 세션은 원본이 이미 최신.
### 대상 (세션 중 반영 불가 9종)
CLAUDE.md, CLAUDE.local.md, .claude/settings.json, settings.local.json, .claude/skills/*/SKILL.md, .claude/agents/*.md, .claude/rules/*.md, .claude/commands/*.md, .mcp.json
### 더미 파일 위치
`.claude/live/` — 원본과 동일 파일명으로 **변경분(diff)만** 기록.
### 변경 발생 시 절차
1. **원본 파일 즉시 수정** (다음 세션·다른 PC를 위해)
2. **`.claude/live/{파일명}`에 변경 요지 append** (현재 세션 즉시 반영용)
3. UserPromptSubmit hook(`live_inject.sh`)이 증분 감지 → 추가분만 컨텍스트 주입
### 증분 읽기 원리
- hook이 파일별 "마지막 읽은 줄 번호" 기록
- 다음 턴에 추가된 줄만 stdout 출력 → 에이전트 컨텍스트 주입
- 변경 없으면 출력 없음 (토큰 비용 0)
### 서브에이전트 의무
모든 에이전트는 작업 착수 전 `.claude/live/` 디렉토리에 더미 파일이 존재하는지 확인하고, 존재하면 Read하여 변경사항을 인지한다.
### Write 권한
- **PM만 Write** (서브에이전트는 Read 전용)
- 각 더미 파일 최대 8,000자
### "세션 공유" 시 동기화 (P21-2 연계)
1. 더미 내용이 원본에 이미 반영되어 있는지 확인
2. `.claude/live/` 더미 파일 비우기 (README.md 제외)
3. commit + push
### C14 준수
- 변경 없는 턴: 토큰 비용 0 (해시 비교만)
- 변경 감지 턴: 추가분만 주입 (전체 재읽기 없음)
- 세션 시작 시: SessionStart hook이 전량 1회 로드
--- ---
## 교훈 및 노하우 ## 교훈 및 노하우

56
scripts/live_inject.sh Normal file
View File

@ -0,0 +1,56 @@
#!/bin/bash
# UserPromptSubmit hook — .claude/live/ 증분 읽기 + 컨텍스트 주입
# 세션 중 반영 불가 파일의 변경분을 실시간 주입
# 증분 방식: 마지막 읽은 줄 이후 추가분만 출력
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
[ -z "$REPO_ROOT" ] && exit 0
LIVE_DIR="$REPO_ROOT/.claude/live"
[ ! -d "$LIVE_DIR" ] && exit 0
THROTTLE_DIR="$HOME/.claude/.nerdnavis_throttle"
mkdir -p "$THROTTLE_DIR" 2>/dev/null
OUTPUT=""
TOTAL_CHARS=0
MAX_CHARS=8000 # 10,000자 한도에서 기존 hook 여유분 확보
for LIVE_FILE in "$LIVE_DIR"/*.md "$LIVE_DIR"/*.json; do
[ ! -f "$LIVE_FILE" ] && continue
BASENAME=$(basename "$LIVE_FILE")
[ "$BASENAME" = "README.md" ] && continue # README는 스킵
# 파일별 마지막 읽은 줄 번호 추적
FILE_HASH=$(echo "$LIVE_FILE" | sha1sum 2>/dev/null | cut -d' ' -f1)
LAST_LINE_FILE="$THROTTLE_DIR/live_lastline_$FILE_HASH"
LAST_LINE=$(cat "$LAST_LINE_FILE" 2>/dev/null || echo 0)
TOTAL_LINES=$(wc -l < "$LIVE_FILE" 2>/dev/null || echo 0)
# 새 줄이 추가된 경우에만 출력
if [ "$TOTAL_LINES" -gt "$LAST_LINE" ]; then
NEW_CONTENT=$(tail -n +$((LAST_LINE + 1)) "$LIVE_FILE" 2>/dev/null)
NEW_CHARS=${#NEW_CONTENT}
# 한도 체크
if [ $((TOTAL_CHARS + NEW_CHARS)) -lt $MAX_CHARS ]; then
OUTPUT="$OUTPUT
[LIVE:$BASENAME] 변경분 (${LAST_LINE}줄 이후):
$NEW_CONTENT
"
TOTAL_CHARS=$((TOTAL_CHARS + NEW_CHARS + 50)) # 헤더 여유
echo "$TOTAL_LINES" > "$LAST_LINE_FILE"
else
OUTPUT="$OUTPUT
[LIVE:$BASENAME] ⚠️ 증분 크기 초과 — Read 도구로 직접 확인 필요
"
fi
fi
done
# 출력이 있을 때만 주입
if [ -n "$OUTPUT" ] && [ "$TOTAL_CHARS" -gt 0 ]; then
echo "📝 [Live 증분 동기화]$OUTPUT"
fi
exit 0

View File

@ -0,0 +1,47 @@
#!/bin/bash
# SessionStart hook — .claude/live/ 전량 로드 (세션 시작 시)
# 세션 시작 시점에 모든 live 더미 파일을 읽어서 컨텍스트에 주입
# 증분 카운터도 리셋하여 다음 턴부터 증분 추적 시작
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
[ -z "$REPO_ROOT" ] && exit 0
LIVE_DIR="$REPO_ROOT/.claude/live"
[ ! -d "$LIVE_DIR" ] && exit 0
THROTTLE_DIR="$HOME/.claude/.nerdnavis_throttle"
mkdir -p "$THROTTLE_DIR" 2>/dev/null
OUTPUT=""
TOTAL_CHARS=0
MAX_CHARS=8000
FILE_COUNT=0
for LIVE_FILE in "$LIVE_DIR"/*.md "$LIVE_DIR"/*.json; do
[ ! -f "$LIVE_FILE" ] && continue
BASENAME=$(basename "$LIVE_FILE")
[ "$BASENAME" = "README.md" ] && continue
CONTENT=$(head -c $MAX_CHARS "$LIVE_FILE" 2>/dev/null)
CHARS=${#CONTENT}
if [ "$CHARS" -gt 0 ] && [ $((TOTAL_CHARS + CHARS)) -lt $MAX_CHARS ]; then
OUTPUT="$OUTPUT
[LIVE:$BASENAME]
$CONTENT
"
TOTAL_CHARS=$((TOTAL_CHARS + CHARS + 30))
FILE_COUNT=$((FILE_COUNT + 1))
# 증분 카운터를 현재 줄 수로 설정 (다음 턴부터 증분 추적)
FILE_HASH=$(echo "$LIVE_FILE" | sha1sum 2>/dev/null | cut -d' ' -f1)
TOTAL_LINES=$(wc -l < "$LIVE_FILE" 2>/dev/null || echo 0)
echo "$TOTAL_LINES" > "$THROTTLE_DIR/live_lastline_$FILE_HASH"
fi
done
if [ "$FILE_COUNT" -gt 0 ]; then
echo "📝 [Live 세션 로드] ${FILE_COUNT}개 더미 파일:$OUTPUT"
fi
exit 0