# Claude Code 다음 세션 인계 (v0.1.4)

> 작성: PC Claude Code 세션 (Opus 4.7) at v0.1.4 시점
> 대상: SSH로 들어온 PC `claude` CLI (또는 PC 직접) — 새 세션이 코드 작업으로 즉시 진입할 수 있게

이 문서는 v0.2 사이클을 이어갈 다음 세션이 단일 파일만 보고
**현재 상태 + 다음 작업 + 운영 패턴**을 모두 잡을 수 있게 한다.
SSH 셋업 같은 환경 설정은 이미 끝났다는 전제.

---

## 즉시 시작 (3줄)

```bash
cd C:\Project\James-RAG-Evol-v010   # 또는 /c/Project/James-RAG-Evol-v010
git pull                              # 다른 device 작업 sync
claude                                # 메모리 자동 로드됨
```

Claude 세션 첫 프롬프트 (한 줄이면 충분):

```
v0.2 #20 entity hard merge부터 시작
```

또는 작업 다시 결정하고 싶으면:

```
docs/handovers/v0.1.4-next-session.md 읽고 우선순위 다시 보자
```

---

## 현재 상태 (v0.1.4 시점)

### Code

| 항목 | 값 |
|---|---|
| main commit | `d11fb54` (PR #26 — handover doc) — 다음 작업 시 fetch 해서 최신 확인 |
| working tree 잔재 | `wiki/prod/` 빈 폴더 1개 (자기진화 추정, 사용자가 미루기로) |
| 6 releases 발행 | v0.1.0-alpha → v0.1.1 → v0.1.2 → v0.1.3 → v0.1.3.1 → v0.1.4 |

### Env (PC)

| 항목 | 상태 |
|---|---|
| `JAMES_API_KEY` | 4자 (운영 시 32자 권장 — 작업 중 보강 후보) |
| `JAMES_JWT_SECRET` | 43자 ✅ (32+ 충족) |
| `JAMES_LLM_MODEL` | `gemma4:e4b` |
| Ollama 설치 모델 | `gemma4:e4b` (8B), `qwen2.5-coder:32b`, `llava:13b` |
| `gh` CLI | 2.92.0, Hashevolution 인증, `gh auth setup-git` 완료 |
| `wiki/entity/prod/` | 161 entity (.gitignored, 로컬 전용) — 평균 relations 3.2/entity (PR #16 양방향 backfill 후) |

### v0.1.4의 breaking 변경 (이미 적용됨, 참고만)

- `JAMES_JWT_SECRET` 32+자 fail-fast (PR #22)
- `JAMES_API_KEY` non-empty fail-fast (PR #22)
- 4 default 계정 → admin 1개 랜덤 (PR #22). 기존 admin/manager1/employee1/guest 4행은 PC DB에 그대로 (`INSERT OR IGNORE`).
- 운영 cleanup 권장 (시급도 낮음, 사용자 결정으로 미룸):
  ```powershell
  sqlite3 james_users.db "DELETE FROM users WHERE username IN ('manager1','employee1','guest')"
  ```

---

## 5 open issues (다음 작업 후보)

priority 모두 medium. 추천 처리 순서 + 구체 시작점.

### #20 — Entity hard merge (다음 1순위)

**무엇**: BTC.md + 비트코인.md 가 서로 alias로 연결돼있지만 여전히 별도 파일. 진정한 dedup은 한 canonical .md로 collapse + 다른 entity의 `target_id` 재매핑.

**시작점**:
- 새 도구 `tools/admin/entity_hard_dedup.py` (기존 `migrate_aliases.py` / `migrate_inverse_relations.py` 패턴 재사용)
- 입력: `wiki/synonyms.yaml` (이미 존재). 각 그룹마다 canonical 결정 → 다른 .md 의 relations 합집합 + 가장 높은 confidence → canonical에 흡수 → 다른 entity 의 `target_id`/`target` 재매핑 → drop된 .md 삭제
- 위험: entity_id 변경. 운영 데이터 mutation. **--apply 전 dry-run 필수**, backup zip 권장
- edge case: 같은 synonym 그룹에 다른 `entity_type` (Aider concept + Aider org). reject 또는 type 강제 결정
- 검증: `match_entities("BTC")` → 1개 entity_id, 그 entity의 relations에 모든 인커밍 포함됐는지

**참고**: GitHub Issue #20 본문에 design 옵션 적혀있음. 현재 `migrate_*.py` 스크립트들이 idempotent + dry-run 패턴이라 그대로 따라가면 됨.

### #5 + #6 — LLM extraction 품질 (묶어서)

**무엇**:
- #5: `Claude Code` (product)가 `org`로 분류되는 등 type 정확도 낮음
- #6: 263개 relation 중 `RELATED_TO` 91% — `분류`/`근무`/`소속` 등 12 ontology 라벨 활용 미흡

**왜 묶어서**: 둘 다 `core/wiki_generator._llm_extract_document_entities` 의 프롬프트 강화로 해결. 한 PR이 자연스러움.

**시작점**:
- 프롬프트에 few-shot 추가:
  - "Claude Code는 tool/product → `concept` 으로 분류 (org 아님)"
  - "person works at org → `근무`", "concept is_a concept → `분류`", "org founded by person → `설립됨`"
- 후처리: `(source_type, target_type)` pair → 강한 라벨 매핑 사전 (예: `(person, org) → 근무`, `(concept, concept) → 분류 또는 구성`). LLM이 `관련` 으로 떨어뜨리면 confidence borderline 일 때 강한 라벨로 교체

**검증**: 30 PDF 일부 재업로드 (`scripts/step7_query_test.py` 12 쿼리 회귀로 graph_paths 영향 없음 확인)

### #14 + Web UI HANDOVER (frontend 묶어서)

**무엇**: `frontend/HANDOVER_WEB_UI.md` 의 5단계 (CSS 추출 → 반응형 → 추론 패널 → 접근성 → CSP) + 업로드 진행률 UI (#14: fetch → XHR + progress bar)

**왜 묶어서**: 둘 다 frontend, 인라인 onclick 정리하면 둘 다 영향, i18n 키 추가도 동시 가능.

**추천 시작 순서**: HANDOVER_WEB_UI 1단계 (CSS 추출 → `frontend/static/styles.css`) — 가장 안전, 후속 작업의 기반. 그 다음 #14 XHR 마이그레이션.

### #8 — 위험 코딩 정책

**무엇**: STEP 7 query #12 `wiki 폴더 삭제 명령어 알려줘` → coding 모드로 36.6초 응답 (위험 안내 + 명령어). hard-refuse vs warn-and-answer 정책 결정 필요.

**시작점**:
- `SECURITY.md` 에 정책 명시
- hard-refuse 채택 시: `core/security_layer.py` 에 키워드 분류기 (`delete`, `drop`, `format`, `rm -rf`, `wipe`, `truncate`) — LLM 호출 전 게이트
- warn-and-answer 유지 시: SECURITY.md에 정당성 + 예시 답변 형식 박제만

**의존**: 사용자 정책 결정 — 코드 작업 작음 (1~2시간), 결정이 핵심.

---

## 운영 트랙 (별도 epic, 작업 단위 작음 X)

`docs/handovers/v0.1.3.1-hotfix.md` 의 비즈니스 트랙.

| 항목 | 가치 | 상태 |
|---|---|---|
| **B1 RAGAS** 벤치마크 | 영업 자료 1순위 | 미시작. 1주 작업. v0.2.0 직후 |
| **B4 컨트리뷰터** 1명 | bus factor 1 → 2 (사업화 전제) | 미시작. 운영 3~6개월 누적 |
| **B5 외부 red-team** | 보안 마케팅 (P0 ✅ 완료, 진행 가능) | 미시작. 1~2주 + 컨설팅비 |

이 셋은 단일 PR이 아니라 **운영 epic** — 다음 세션이 핸들 잡고 굴리는 종류. 코드 작업과 병렬로 진행 가능.

---

## 운영 패턴 (이번 사이클에서 굳어진 것들)

새 작업이 빠르게 자리잡게 하는 규칙. 거스르면 PR 다시 풀어야 하는 비용 발생.

1. **Branch 명명**: `chore/v0.2-…`, `fix/v0.2-…`, `feat/v0.2-…`, `docs/v0.2-…`, `security/v0.2-…`, `hotfix/<release>-…`
2. **PR body**: PowerShell 5.1의 `gh pr create --body "…"` 가 한글/특수문자에서 인자 splitting → 항상 BOM-없는 UTF-8 임시 파일 + `--body-file` 사용. 패턴:
   ```powershell
   $body = @'
   …
   '@
   [System.IO.File]::WriteAllText("$PWD\.tmp_pr.md", $body, `
       [System.Text.UTF8Encoding]::new($false))
   gh pr create … --body-file ".tmp_pr.md"
   Remove-Item .tmp_pr.md -Force
   ```
3. **Self-merge**:
   ```bash
   gh pr merge $num --squash --delete-branch
   git checkout main && git pull --rebase
   ```
4. **Release**: 의미있는 단위마다 (v0.1.x). breaking change면 release notes 상단에 ⚠️ 명시
5. **Issue close 패턴 주의**: PR title `(closes #2, #4)` → GitHub은 첫 번째만 close. **`closes #N, closes #M`** 형식 써야 둘 다 자동 close. (PR #24가 이 패턴 깨서 #2/#4 수동 close했음)
6. **Migration script**: `--dry-run` 기본 + `--apply` 명시. 멱등 (재실행 안전). 로그에 변경 카운트 + 일부 변경 예시 출력. `migrate_aliases.py` / `migrate_inverse_relations.py` 둘 다 이 패턴.
7. **사용자 데이터 분리**: `wiki/entity/prod/{concept,org,person,document,system_internal}/*.md` 는 .gitignored. 코드는 공개, 데이터는 로컬. 핸드오버에서도 PC-specific 측정치 (응답 시간 등)는 환경 caveat 적기.

---

## 메모리 (`~/.claude/projects/<this>/`)

다음 세션 시작 시 자동 로드됨. 굳이 파일을 손으로 읽힐 필요 없음.

- `MEMORY.md` 인덱스
- `user_profile.md` — Hashevolution, 보안 + Graph-RAG, 한국어/Windows
- `feedback_workflow.md` — 단계별 + 보안/fallback/이식성 우선
- `project_state.md` — v0.1.4 + 5 open issues + 우선순위 박힘
- `step7_findings_pointer.md` — `reports/step7_findings.md` 가리킴

이 핸드오버 (`docs/handovers/v0.1.4-next-session.md`) 는 git 추적이라 자동 로드는 안 됨. 다만 메모리에 위치 reference가 있어서 Claude가 필요 시 read.

---

## 워크플로우 도구 (자주 쓰는 것들)

| 파일 | 용도 |
|---|---|
| `scripts/step7_query_test.py` | 12 쿼리 회귀 테스트 (서버 떠있을 때 실행) |
| `scripts/migrate_aliases.py` | wiki entity alias 백필 (멱등, dry-run + apply) |
| `scripts/migrate_inverse_relations.py` | 인커밍 relation 백필 (PR #16 도구) |
| `scripts/post_step7_remaining.py` | 일괄 GitHub issue 등록 (Python; PS5.1 한글 문제 회피) |
| `tools/admin/wiki_reset.py` | 사용자 데이터 리셋 (cp949 안 깨짐, #2 fixed) |
| `POST /admin/llm/select?task_type=X&model=Y` | task별 모델 매핑 (운영자가 admin role로 호출) |
| `GET /admin/llm/selections` | 현재 매핑 조회 |

---

## 작업 중 주의

### Destructive 명령은 신중

`Edit`, `Bash`, `git`, `gh` 모두 PC 사용자 권한 그대로 동작. 작은 화면 + 키보드에서 `rm -rf`, `git push --force`, `DROP TABLE`, `format` 같은 명령은 실수 위험 ↑. 의심되면 Claude에게 dry-run 또는 `--dry-run` 옵션 먼저.

### 화면 좁으면 출력 잘라보기

```bash
git log --oneline -10
gh issue list --limit 5
… | head -20
… | less       # 페이지 단위
```

### LLM 호출 시간 (gemma4:e4b 8B 기준)

p50 ~24초, p90 ~32초. 한 query에 LLM이 여러 번 (extract + classify + generate) 호출되면 분 단위로 늘어남. 백그라운드 작업이면 다른 일 하면서 대기.

### 캐시 stat 0% 이슈 (v0.1.3.1 hotfix caveat)

`call_router` 가 매번 새 GemmaClient를 만들어서 cache가 누적 안 됨 — `[CACHE] 0.0% hits=0 misses=0` 로그가 항상 0으로 보임. 정상 동작이 아니라 알려진 한계. 진짜 cache 효과 보려면 router 레벨 캐시 통합 필요 (별도 작업).

---

## 동반 핸드오버 (참고)

device-sync 워크플로우의 다른 산출물. 필요 시 read.

- `docs/handovers/v0.1.3.1-hotfix.md` — 별도 노트북 클라우드 세션. 보안 P0 (이미 v0.2.0 첫 커밋으로 처리) + 비즈니스 트랙 B1~B5 (운영 epic).
- `frontend/HANDOVER_WEB_UI.md` — 웹 클라우드 세션. UI 5단계 평가 (`#14` 작업할 때 합본).

---

## 인계 정보

- 작성: PC Claude Code 세션 (Opus 4.7), v0.1.4
- 위치: `docs/handovers/v0.1.4-next-session.md` (main에 push, 자동 sync)
- 갱신 시점: 다음 의미있는 마일스톤 (예: v0.1.5 또는 v0.2.0-alpha) 발행 직후
