# sori의 Claude Code 활용 기록 (공개 발췌판)

**이게 뭔가요** — 제 개인 위키(마크다운 지식 저장소)에서 스터디 공유 주제에 해당하는
글 3편을 추린 것입니다. Claude Code를 몇 달 쓰면서 부딪힌 문제들을 직접 풀어온 기록이에요:
① 대화에서 나온 지식이 휘발됨 → 개인 위키로 축적, ② 대화·기록이 흩어짐 → 폴더 단위
작업 공간 분리, ③ 같은 내용을 여러 곳에 적음 → 이중 기록 금지 규약, ④ 내 지시가
좋은지 피드백이 없음 → 매일 아침 자동 점검 루프.

**읽는 순서** — ① [좋은 스킬 설계](tools/skill-design.md): 가장 보편적, 스킬 8개를 감사해
164줄을 지운 사례 포함. ② [위키 공개판 미러](tools/wiki-public-mirror.md): 지금 이 문서가
여러분에게 전달되는 방식 그 자체. ③ [워크스페이스 레이아웃](tools/claude-workspace-layout.md):
개인 결정 기록이 섞여 있어 무겁습니다 — cwd 라우팅·temp→3회 승격·종별 분류 리트머스만
봐도 충분해요.

**낯선 이름들** — `cmux`: 제가 쓰는 AI 에이전트용 macOS 터미널(작업이 끝난 에이전트가
알림을 울림). `node2`: 제 작업용 리눅스 서버. `memomu`: 제가 만드는 메모 서비스(개인
프로젝트). `personal-wiki`: 위키 저장/조회 절차를 담은 제 스킬.

> 원본 위키에서 비공개 글로 가던 링크는 **(비공개)**로 표시했습니다.


<!-- FILE: index.md -->

# 공개판 색인

> ⚠ 공개용 사본 — 개인 위키에서 스터디 공유 주제 글만 추린 발췌판입니다.

읽는 순서대로:

1. [좋은 스킬 설계 (트리거·구조·유도·가지치기)](tools/skill-design.md)
2. [개인 위키 공개판 미러 (민감정보 치환 빌드)](tools/wiki-public-mirror.md)
3. [Claude Code 워크스페이스 레이아웃 (대화·지식·프로젝트 분리)](tools/claude-workspace-layout.md)


<!-- FILE: tools/skill-design.md -->

# 좋은 스킬 설계 (트리거·구조·유도·가지치기)

> Updated: 2026-07-12 · Topic: tools

출처: Matt Pocock(Total TypeScript), "How to write good skills".

스킬이 넘쳐나는데 좋은 스킬과 나쁜 스킬을 가를 **공유된 채점표가 없는** 상태를 스킬 헬이라 부른다.
아래 4단계가 그 채점표다.

## 1. 트리거 — 누가 부르는가

| 방식 | 비용 |
|---|---|
| 모델 호출 (에이전트가 알아서) | **컨텍스트 부하** — description이 매 요청마다 상주. 스킬 100개면 설명 100개가 항상 떠 있다. 게다가 **예측 불가능성** — description이 완벽해도 에이전트가 그냥 안 부를 수 있고, 그때부터 "제때 호출되는지"를 평가로 검증해야 한다. |
| 사용자 호출 (슬래시 명령) | **인지 부하** — 뭐가 있는지, 언제 뭘 부를지 내가 다 기억해야 한다. |

좋은 쪽을 고르는 게 아니라 **부하를 누구에게 지울지**의 트레이드오프.
Pocock은 대부분을 사용자 호출로 만든다 — 인지 부하를 본인이 지는 대신 예측 불가능성이라는 문제 종류를 통째로 없앤다.

## 2. 구조 — 절차 + 참고 자료

스킬 본문은 **절차**(에이전트가 밟을 순서)와 **참고 자료**(그 절차를 돕는 정보) 두 가지뿐이다.
본문은 최대한 작게: 작은 스킬은 고치기 쉽고, 감사하기 쉽고, 단어 하나마다 토큰이 준다.

**가르는 기준은 경로.** 특정 경로에서만 필요한 참고 자료는 별도 파일로 빼고 본문엔 "이게 필요하면 이 파일을 봐라" 한 줄만 남긴다.
매번 쓰는 자료는 본문에, 가끔 쓰는 자료는 문 뒤에.

## 3. 유도 — 강한 단어를 심는다

에이전트가 스킬대로 안 움직이는 건 **문장이 부족해서가 아니라 단어가 약해서**다.

- 큰 작업을 주면 층별로 코딩한다(DB 다 짜고 → API 다 짜고 → 마지막에 화면). "층별로 하지 마"를 길게 쓰는 대신 **`vertical slice`** 한 단어를 심는다. 개발 문화에서 수십 년 쓰인 용어라 모델이 이미 학습했고, 단어 하나가 그 행동 방식 전체를 불러온다.
- **검증법:** 에이전트의 사고 과정(reasoning trace)에 그 단어가 다시 나타나면 먹힌 것. 안 나타나면 더 강한 단어로 바꾼다.

**미래 숨기기.** 플랜 모드가 질문을 대충 하고 계획서로 직행하는 건 최종 목표가 보이기 때문이다.
스킬을 단계별로 쪼개서 다음 단계를 모르게 만들면 지금 단계에 발품을 다 쓴다.
목표를 보여주면 서두르고, 가리면 파고든다.

## 4. 가지치기 — 삭제 테스트

거대한 스킬은 병이 아니라 **증상**이다. 안에서 세 가지가 썩고 있다:

1. **중복** — 모든 내용엔 정답 위치가 딱 한 곳이어야 한다.
2. **퇴적물** — 여러 사람이 자기 것만 추가하고 남의 건 무서워서 못 지운 죽은 층.
3. **무동작** — 있어 보이는데 에이전트 행동을 하나도 안 바꾸는 문장. **가장 흔하고 가장 중요하다.**

> **삭제 테스트:** 문단을 통째로 지워 보라. 에이전트가 다르게 행동하는가?
> 아니라면 그 문장은 처음부터 없었던 것이다 — 토큰만 내고 아무 일도 안 하고 있었다.

판별 기준: 그 지시가 **모델의 기본 행동을 밀어내는가**, 아니면 기본값을 재진술할 뿐인가.
전자만 토큰값을 한다. 예) "커밋 메시지를 자세히 써라"는 무동작 — 안 써도 에이전트는 잘 쓴다.

## 2층 구조

Pocock의 레포에서 제일 인기 있는 스킬 `grill-me`의 본문은 **한 문장**("그릴링 세션을 실행하라"), 프론트매터 포함 20단어다.
가능한 이유:

- **위층** — 사용자 호출용 한 문장짜리 호출 버튼. 컨텍스트 부하 0.
- **아래층** — 재사용되는 규율(모델 호출). 실제 인터뷰 규칙은 `grilling` 스킬에 있다.
- **규칙** — 위층은 아래층만 부를 수 있고, 위층끼리는 절대 못 부른다.

## 고전이 곧 강한 단어의 재고

그의 스킬엔 새로운 개념이 거의 없다. 인터뷰로 요구사항 좁히기, 테스트 먼저 쓰기, 용어집 만들기, 코드 스멜로 리뷰하기 —
전부 『실용주의 프로그래머』, DDD, 『리팩터링』에서 온 것이다.
우연이 아니다: **고전의 용어야말로 모델이 가장 깊게 학습한 단어**다.
그러니 스킬 작성법을 연습하는 것보다 고전의 **용어 재고**를 늘리는 게 더 큰 지렛대다.

사고 순서:
> 에이전트의 실패를 관찰 → 고전에서 처방을 찾음 → 모델이 아는 단어로 압축 → 최소한으로 적음 → 사고 과정 보며 확인 → 계속 지움

## 스킬의 정의

> 스킬은 **확률적인 시스템에서 예측 가능성을 짜내는 장치**다.
> 매번 같은 답을 내라는 게 아니라, 매번 같은 **방식**으로 일하게 만드는 것.

"스킬 하나만 더 있으면 될 것 같은" 순간에 필요한 건 새 스킬이 아니라, **지금 있는 스킬을 열어서 지워보는 눈**이다.

## 내 환경에 적용한 것

**이미 맞게 되어 있던 것:** node2의 `~/.claude/CLAUDE.md`는 11줄뿐이고, `personal-wiki` 스킬을 가리키기만 한다.
정확히 위 2층 구조 — 얇은 상시 레이어 + 규율은 스킬에.

**프롬프트 리뷰 루프 (2026-07-12 구축, node2):** 삭제 테스트와 강한 단어 사용을 습관화하기 위한 피드백 장치.

| 경로 | 역할 |
|---|---|
| `~/.claude/prompt-review/run-review.sh` | cron이 매일 06:00 KST 실행 (시스템이 UTC라 crontab엔 21:00, 스크립트에 `TZ=Asia/Seoul` 고정). `~/.claude/history.jsonl`에서 지난 24시간 프롬프트를 뽑아 `claude -p`로 리뷰 |
| `~/.claude/prompt-review/review-prompt.md` | 리뷰 기준 (약한 단어 / 반복=승격 후보 / 목표 노출 / 무동작) |
| `~/.claude/prompt-review/session-start.sh` | SessionStart 훅. `.last-shown` 마커로 **그날 첫 세션에만** 리포트를 컨텍스트에 주입 |
| `~/.claude/prompt-review/reports/` | 날짜별 리포트 아카이브 |

핵심: `history.jsonl`이 이미 `project`(WORKDIR) + `display`(프롬프트) + `timestamp`를 기록하고 있어 **별도 로깅 훅이 필요 없었다.**
새 장치를 만들기 전에 기존 걸 열어보는 것 — 삭제 테스트의 정신이 설계 단계에도 적용된다.
1회차 루프 완주 확인: 2026-07-12 (cron 리포트 생성 → 첫 세션 주입까지).
리포트에는 **"오늘의 강한 단어"** 섹션이 있다 — 추천된 강한 용어의 뜻·딸려오는 절차·예문을 매일 1~3개씩 학습(용어 재고 늘리기의 실행 장치).

**Extend-first 게이트 (2026-07-12, skill-creator에 추가):** "스킬 하나만 더 있으면 될 것 같은" 순간을 위한 장치.
새 스킬 초안을 잡기 전에 기존 스킬을 **inventory**하고 가장 가까운 것을 열어본 뒤,
"확장 vs 신규" 판정과 근거를 사용자에게 제시하고 동의받아야 진행한다.
같은 날 위키에서 같은 원리가 실증됨 — 워크스페이스 레이아웃을 새 글로 만들 뻔했지만
`personal-wiki`의 기존 규칙("이미 문서가 있으면 병합 — a wiki accumulates, it doesn't fork")이 병합으로 유도했다.

## 내 스킬 8개 감사 결과 (2026-07-12, node2)

체크리스트를 내 `~/.claude/skills/`에 실제로 적용한 첫 회차. **164줄 삭제, 121개 파일 이동.**

| 스킬 | 판정 | 조치 |
|---|---|---|
| `cmux-markdown-remote` (52줄) | ✅ 모범 | 전부 모델이 모르는 정보(릴레이 CLI 제약, rsync 미러). 지울 게 없음 |
| `personal-wiki` (106줄) | ✅ 모범 | 두 하드 룰(READ=명시적만 / SAVE=먼저 확인)이 모델 기본값을 **밀어냄** |
| `cmux-browser` (141줄) | ✅ KEEP | 본문=절차, 세부=참조 파일 뒤. 구조 교과서적 |
| `cmux` 84→81 | ⚠️ 퇴적물 | 통합되며 사라진 `cmux-workspace`/`cmux-settings`/`cmux-markdown`을 아직 가리키던 **깨진 링크 3줄** 삭제 |
| `skill-creator` 485→434 | ⚠️ 무동작 | `Claude.ai-specific`/`Cowork-Specific`/`present_files` 섹션 51줄 — Claude Code엔 `present_files`가 없어 **절대 안 도는 죽은 코드** |
| `find-skills` 142→32 | ❌ 무동작 60%+ | "구체적 키워드를 써라", "도메인을 파악하라", 검색어 예시 표, 예시 응답 블록 = 전부 모델 기본. 남긴 것: `npx skills` 명령어 + **품질 검증 기준**(1K+ 설치, <100 스타 회의적) |
| `karpathy-llm-wiki` (187줄) | ❌ 중복 | `personal-wiki`와 트리거 경합("위키에 저장"). **`skillOverrides: user-invocable-only`로 모델 시야에서 제거** — `/karpathy-llm-wiki`로만 호출 |
| `personal-wiki-workspace` (121파일) | ❌ 스킬 아님 | `SKILL.md`가 없어 **로드조차 안 됨.** skill-creator의 eval 산출물이 `skills/`에 눌러앉아 있었음 → `~/claude/skill-dev/`로 이동 |

### 여기서 배운 것

**줄 수를 줄인다고 상시 컨텍스트가 주는 게 아니다.**
매 요청마다 상주하는 건 **description뿐**이고, 본문은 그 스킬이 발동할 때만 로드된다. 그래서 효과가 갈린다:

- **상시 컨텍스트를 실제로 깎은 것** — `karpathy-llm-wiki` 하나. `skillOverrides`로 모델 시야에서 뺐다.
- **발동 시 페이로드를 깎은 것** — 나머지 164줄.
- **`personal-wiki-workspace`는 토큰을 1도 안 먹고 있었다.** 줄인 건 토큰이 아니라 **인벤토리의 혼란** — "내 스킬이 몇 개지?"에 답하지 못하던 상태. 스킬 헬의 본질은 토큰이 아니라 이것이다.

**`skillOverrides`가 2층 구조보다 싸다.** 모델 호출 스킬을 사용자 호출로 내리고 싶을 때, 스킬을 두 겹으로 쪼갤 필요 없이 `~/.claude/settings.json` 한 줄이면 된다:

```json
"skillOverrides": { "<skill>": "user-invocable-only" }
```
`name-only`(설명 없이 이름만 노출), `off`(양쪽에서 숨김)도 있다.

## See also
- [Claude Code 워크스페이스 레이아웃](claude-workspace-layout.md)
- Claude Code 폴더별 에이전트 운용(비공개)


<!-- FILE: tools/wiki-public-mirror.md -->

# 개인 위키 공개판 미러 (민감정보 치환 빌드)

> Updated: 2026-07-12 · Topic: tools

개인 위키를 공개 URL로 미러링해서 **다른 사람의 클로드가 읽게** 하는 패턴.
사람용 발표 자료를 만드는 대신 지식 원본을 서빙하고, 소화(요약·눈높이 조절·적용법)는
읽는 쪽의 AI가 담당한다. 스터디 공유용으로 구축 (2026-07-12).

## 공유 3단계 설계

| 레벨 | 방법 | 받는 사람이 하는 것 |
|---|---|---|
| 요약 | 합본 `wiki.md` URL 하나를 클로드에 전달 | "이 URL 읽고 요약해줘" |
| 질문 | 같은 컨텍스트에서 이어서 질문 | "윈도우인 내 환경에 맞는 것만 골라줘" |
| 복제판 | `starter.md`(설치 지시서)를 클로드에 전달 | 위키+personal-wiki 스킬이 로컬에 설치돼 내 사용 경험을 그대로 체험 |

핵심 장치 둘:
- **합본 파일 + `<!-- FILE: <경로> -->` 마커** — 클로드의 웹 읽기는 링크를 타지 않고
  한 URL만 읽으므로, 전체를 한 파일로 합치되 마커로 원 폴더 구조를 복원 가능하게 한다.
- **starter.md는 사람이 아니라 클로드가 읽는 문서** — 설치 절차·분할 스크립트·스킬
  원문을 담아, 받는 쪽은 "이 URL 읽고 설치해줘" 한 줄이면 된다.

## 내 셋업 (런북)

- 입구: `https://artifact.memomu.uk/claude-code-study/` (3단계 사용법 + 복사 버튼)
- 합본: `/wiki.md` · 개별: `/wiki/<topic>/<slug>.md` · 설치 지시서: `/starter.md`
- 소스: `~/claude/artifacts/artifact-hub/` — `build-wiki.py`(빌드) + `site/`(배포물)
- 호스팅: cloudflare-pages-direct-upload(비공개) 참조 (Pages 프로젝트 `artifact-hub`)

**갱신 절차** (위키 수정 후):

```bash
cd ~/claude/artifacts/artifact-hub
python3 build-wiki.py          # 치환 + 검증 + site/wiki* 재생성
export CLOUDFLARE_API_TOKEN=$(cat <토큰파일>)
npx wrangler@3 pages deploy site --project-name artifact-hub
```

## 공개 범위 — 화이트리스트가 1차 게이트 (2026-07-12 전환)

처음엔 전체 공개(치환판)로 갔다가 **화이트리스트 방식으로 전환**: `build-wiki.py`의
`INCLUDE` 목록에 적은 글만 빌드된다. **새 글은 기본 비공개** — 공유 주제와 무관한
곁가지(다계정 셋업, 인프라 상세 등)가 자동으로 따라 나가는 사고를 구조적으로 차단.
색인도 원본 index.md 대신 포함 글 기준으로 자동 생성한다.

2차 게이트는 민감정보 치환: 치환 규칙(전역 + 파일별)과 **금지 패턴 목록**이 있고,
치환 후에도 금지 패턴이 남으면 빌드가 실패한다. 치환 대상의 종류:
- 이메일 · 조직/계정 식별자 · 계정명
- 외부 서비스 앱 ID (GitHub App 등)
- **키 백업·토큰 파일의 실제 경로** (존재만 알리고 위치는 비공개)
- 실서비스 운영 URL (Jenkins 등 — 공격 표면 노출 방지)

**⚠ 운영 주의 — 글을 공개 목록에 올릴 때가 검토 시점이다.**
`INCLUDE`에 추가하기 전에 그 글을 민감정보 관점으로 훑고, 새 종류의 식별자·경로·URL이
있으면 `FILE_RULES`/`FORBIDDEN`에 규칙을 먼저 추가할 것.

**⚠ 공개 범위를 줄일 때** — 파일을 빼고 재배포해도 즉시 사라지지 않는다:
① Cloudflare Pages는 `404.html`이 없으면 없는 경로에도 index.html을 **200**으로 돌려주고(SPA 폴백 착시),
② 이미 캐시된 URL은 엣지 캐시(s-maxage 7일)가 옛 내용을 계속 서빙할 수 있다.
삭제 반영 확인은 캐시 우회 쿼리(`?x=1`)로, 즉시 제거는 zone cache purge(별도 토큰 권한)로.

## 이중 기록 주의

- `starter.md`에는 personal-wiki 스킬(SKILL.md) 사본이 인라인으로 들어 있다 —
  **스킬 원본을 수정하면 starter.md에도 반영 필요** (알려진 이중 기록 지점).
- 위키 글 자체는 이중 기록 아님: 공개판은 원본에서 빌드로 파생되는 산출물이다.

## See also

- Cloudflare Pages Direct Upload(비공개) — 이 미러가 올라가는 호스팅 셋업 (artifact-hub 런북)
- [좋은 스킬 설계](skill-design.md) — 공유하는 지식(스킬·위키 규율)의 원 출처


<!-- FILE: tools/claude-workspace-layout.md -->

# Claude Code 워크스페이스 레이아웃 (대화·지식·프로젝트 분리)

> Updated: 2026-07-12 · Topic: tools

Claude와의 대화 폴더, 개인 위키, 실제 프로젝트 레포들을 어떻게 배치하고 기록을
어디에 남길지에 대한 결정 (2026-07-11). 핵심 원칙: **cwd가 곧 라우팅** — 대화
주제가 사는 폴더에서 `claude`를 켠다. 컨텍스트(CLAUDE.md 계층·WORK-LOG·세션
히스토리)가 전부 제자리에 쌓인다.

## 구조 — 3계층, 부트스트랩 레포는 ①·② 두 개 (레포 경계 = 소유권 경계)

```
~/claude/
├── temp/                  # 기본 입구 — 소속 없는 대화·실험 (소모품; 결론은 위키/TASK로 승격 후 버림)
├── ops/                   # 운영·인프라 대화방 (grafana/, kube/) — 산출물이 레포가 아니라 "돌아가는 시스템"인 것
├── artifacts/             # 대화방 아님 — 대용량 번들·tar.gz 등 산출물 보관 (airgap 번들 등)
├── skill-dev/             # Claude 환경 자체를 다루는 작업장 (스킬 eval 산출물 등)
├── knowledge/             # 개인 위키 vault (git repo)
└── project/               # ★ git repo ① 워크스페이스 부트스트랩
    ├── CLAUDE.md          #   ✅ 매니페스트: 제품 목록 + 한 줄 설명 (10줄 내)
    ├── setup.sh           #   ✅ 제품 부트스트랩 클론 후 각자의 setup.sh 재귀 호출 (멱등)
    ├── .gitignore         #   memomu/ infra/ 통째 무시
    ├── memomu/            # ★ git repo ② 제품 부트스트랩
    │   ├── CLAUDE.md      #   ✅ 제품 수준: 레포 관계·배포 구조 (상세는 위키 포인터)
    │   ├── setup.sh       #   ✅ backend/frontend/cd 클론 스펙 = "형제 배치" 규약의 보증
    │   ├── .gitignore     #   backend/ frontend/ cd/ 통째 무시
    │   ├── backend/       # git repo ③ 코드 레포. 각각 CLAUDE.md + WORK-LOG.md + TASK-*.md
    │   ├── frontend/
    │   └── cd/            # memoBlog_cd
    └── infra/             # git repo ②' 제품 무관 공용 (클러스터·관측 스택·MinIO). 소비자 2+ 이면 여기로 승격
```

모든 층위가 같은 한 가지 규칙: **"자기 메타(CLAUDE.md·setup.sh)는 자기가 추적하고,
자식 폴더는 통째로 무시한다."** 레벨은 워크스페이스①–제품②–코드③ 셋에서 재귀 종료
(코드 레포 아래에 부트스트랩 없음). submodule은 쓰지 않는다 (커밋 고정 포인터라
작업 체크아웃에 부적합 — 매니페스트/setup.sh 방식이 커뮤니티 표준).

- **왜 제품마다 레포인가**: 단일 부트스트랩이 `memomu/CLAUDE.md`를 추적하면 제품
  메타의 커밋 히스토리가 개인 워크스페이스 레포에 종속되고(소유권 위반), `memomu/*`
  + `!memomu/CLAUDE.md` 같은 gitignore 예외 트릭이 필요해져 파일이 늘수록 애매해짐.
  제품별 레포는 이 둘을 동시에 해소. 상위 레포가 제품에 대해 가진 건 URL 참조뿐이라
  종속이 아님 (package.json이 의존성 이름을 적는 것과 같은 성질).
- **팀 공유 경로**: 제품에 협업자가 생기면 그 제품 부트스트랩 레포(②)만 그대로 전달.
- **비용**: 제품 메타 수정 시 커밋할 레포가 제품 수만큼 늘어남. 제품 2~3개 규모에선
  소유권 정합 + 예외 트릭 제거가 이 비용을 이긴다고 판단 (2026-07-11).

- Claude Code는 실행 시 cwd에서 루트까지 **상위 CLAUDE.md를 전부 로드**하고
  (공식: "Parent directories: useful for monorepos"), 하위 폴더 CLAUDE.md는 그
  폴더 파일을 만질 때 lazy 로드. 제품 수준 컨텍스트를 레이어마다 복붙할 필요 없음.
- `~/claude/`와 `~/claude/temp/`에는 CLAUDE.md를 두지 않는다 (전 폴더에 새어 들어감).
  전역 규칙은 `~/.claude/CLAUDE.md`.

## 대화방 신설 규칙 — temp 기본, 3회째 승격 (2026-07-12)

폴더 경계 = **컨텍스트 경계**: 주제가 달라서가 아니라 CLAUDE.md에 적을 규칙이
갈릴 때 방을 나눈다. 미리 만들지 않는다 (스킬 추가 예산제와 같은 원리).

1. 새 주제는 폴더 고민 없이 **temp에서 시작**한다.
2. 같은 주제를 temp에서 **세 번째** 꺼내게 되면 그때 방을 만든다 — 마찰이 증명된 뒤.
3. 방을 만드는 날 **CLAUDE.md 한 줄이라도 쓴다**. 적을 규칙이 없다면 아직 temp로
   충분하다는 신호다.

카테고리 공통 규칙이 생기면 부모(예: `ops/CLAUDE.md`)에 한 번만 — 상위 CLAUDE.md
자동 로드를 활용하고, 방마다 복붙하지 않는다.

## 지식 배치 — 종(種)별 분류와 리트머스 (이중 기록 방지)

판별 질문: **"이 정보가 바뀌면 몇 군데를 고쳐야 하나?"** 2 이상이면 주인을 하나
정하고 나머지는 포인터. 얽힘의 원인은 글 하나가 서로 다른 종의 지식을 묶는 것 —
모듈화 단위는 글이 아니라 지식의 종이다 (2026-07-11).

| 종 | 성질 | 주인 → 자리 |
|---|---|---|
| 사실 (구조·파이프라인 등 정본) | 제품이 바뀌면 같이 바뀜 | 제품 → `②/docs/` |
| 결정 기록 (무엇을 왜 택했나) | 시점 고정·불변 | 제품 → `②/docs/adr/` (업계 표준 ADR) |
| 교훈·개념 (프로젝트 무관 원칙) | 영구 | 나 → vault (개념 제목, 프로젝트는 본문 사례로 강등) |
| 상태 (진행·대기) | 매주 바뀜 | 폴더 → `WORK-LOG.md` / `TASK-*.md` |
| 에이전트 운영 지침 | 짧고 매 세션 필요 | 폴더 `CLAUDE.md` |

리트머스: **"제목에서 제품명을 빼도 글이 성립하는가?"** 성립하면 개념 지식(vault),
안 하면 제품 자료(②/docs·adr 또는 WORK-LOG). vault에 제품명 제목의 글이 쌓이는 것
자체가 위반 신호.

- 참조는 **vault→제품 단방향**: vault 글이 제품 docs/ADR을 사례로 링크하는 건 자유
  (개인 파일이니 어떤 경로든 가능), 제품 docs가 vault를 링크하는 건 금지 (제품이
  개인 환경에 종속됨). 팀 공유 시점엔 ② 안 CLAUDE.md의 위키 포인터(개인 경로)도 걷어낸다.
- 프로젝트 CLAUDE.md에는 위키/docs 내용 복사 대신 **포인터 한 줄**.
  위키 글에는 진행 상태를 적지 않는다 ("후속은 backend/WORK-LOG.md 참조" 한 줄).
- **제3의 기록소 주의**: Claude Code 자동 메모리(`~/.claude/projects/<slug>/memory/`)는
  Claude의 개인 노트로 방치하고, 사람과 공유하는 원장은 WORK-LOG 하나로 유지.
  폴더 CLAUDE.md에 "durable한 발견은 WORK-LOG에 기록" 규칙을 명시해 흡수.
- 기존 혼합 글은 **게으르게 이관** (손댈 때 종별로 분해). 첫 사례 완료 (2026-07-11):
  memomu 스토리지 글 → 단일 소비자 조기 분리 함정(비공개)(개념)
  + memomu②/docs/adr/001(결정) + backend/WORK-LOG.md(상태), 원본 삭제.

## 경로 레이어 규칙 — "이 파일 누가 보지?"

- **git 커밋되어 공유되는 파일**(레포 안 CLAUDE.md 등): **레포 상대경로만**.
  개인 경로(`~/claude/...`) 금지. 형제 레포는 `../frontend` 같은 상대경로.
- **개인 레이어**(레포 밖 상위 CLAUDE.md, `CLAUDE.local.md`, `~/.claude/CLAUDE.md`):
  개인 경로 포인터 허용. 커밋 CLAUDE.md에서 `@~/.claude/...` 홈 기준 import도 가능.
- 상대경로를 **스펙으로 고정**하는 장치가 제품 부트스트랩 레포(②): "backend/frontend/cd는
  형제" 규약을 memomu/setup.sh가 보장하므로 CLAUDE.local.md로 사람마다 배치가 갈라질
  일이 없음. local.md는 진짜 개인 취향용으로만.
- 실행 스펙(레포 URL→경로, 셋업 명령)은 부트스트랩 레포에, 결정·근거는 위키에.
  위키는 명시 요청 시에만 읽는 원칙이라 셋업 에이전트가 자동으로 못 보기도 함.

## 크로스-레포 작업

읽기는 넓게, 쓰기는 한 레포 (공식 large-codebases 문서 권장):

```bash
cd ~/claude/project/memomu/backend
claude --add-dir ../frontend    # 형제 읽기 권한만 부여
```

진짜 여러 레포를 고치는 작업은 공유 브리프 문서 하나 + 레포별 세션으로 분할.

## 검토에서 나온 보완 규칙 (2026-07-11)

1. **에이전트 작업 파일의 git 소속**: WORK-LOG/TASK가 제품 레포 안에 있으면 —
   내 솔로 레포면 그냥 커밋(단순), 팀 공유 레포면 커밋 오염이므로 레포 밖 형제
   파일(제품 부트스트랩②이 추적)이나 `.git/info/exclude`로. 규칙: "레포 주인이 나면 커밋".
2. **secrets는 매니페스트로 재현 안 됨**: setup.sh는 클론까지만. `.env`·자격증명의
   출처(패스워드 매니저 등)를 부트스트랩 CLAUDE.md에 수동 단계로 문서화.
3. **settings/skills/agents는 상위 탐색 비보장**: CLAUDE.md의 부모 탐색은 공식
   명시돼 있으나 `.claude/settings.json` 발견 메커니즘은 문서 미기재 (2026-07 확인).
   부트스트랩 루트에 훅/권한을 두고 하위 레포 적용을 기대하지 말 것 — 권한·훅은
   레포별 `.claude/settings.json`, 공통은 `~/.claude/settings.json`.
4. **worktree 규약**: 병렬 세션용 워크트리는 `<repo>.worktrees/` 형제 폴더로
   (제품 부트스트랩② gitignore에 추가). 규약 없으면 project/ 아래가 어지러워짐.
5. **원격 필수**: 부트스트랩(①·② 전부)·knowledge 레포는 private 원격이 있어야
   "새 머신 재현"이 성립. temp는 백업 불필요.
6. **고정 절대경로의 부수 효과**: `~/.claude/projects` 세션 슬러그가 절대경로
   기반이라, 배치 고정은 세션 resume 안정성도 준다 (다계정 심링크 구조와 맞물림).

## See also
- [좋은 스킬 설계](skill-design.md) — 상위 CLAUDE.md를 얇게 유지하는 근거: 2층 구조(얇은 상시 레이어 → 스킬)와 삭제 테스트
- Claude Code 폴더별 에이전트 운용(비공개) — 각 레이어 폴더를 에이전트 홈으로 쓰는 패턴 (CLAUDE.md+WORK-LOG+TASK, headless/resume)
- Claude Code 다계정 OAuth 토큰 전환(비공개) — projects/history 심링크 공유: 고정 경로와 함께 세션 resume이 유지되는 배경
- memomu 허브(비공개) — 이 레이아웃이 실제 적용된 첫 제품
- 단일 소비자 서비스의 조기 분리 함정(비공개) — 종별 분해 첫 사례에서 추출된 개념 글
