베이스 업데이트 받기
라이선시 fork는 한 번 받고 끝이 아닙니다. 베이스(ddakit/chrome-ext-base)가 새 스킬을 추가하거나, 훅 동작을 고치거나, AI_AUTOMATION.md 의 도메인 규칙을 갱신할 때마다 그 변경이 fork에 도달해야 라이선스 가치가 유지됩니다. 이 자리는 git rebase 모르고도 안전하게 받게 해주는 /update-from-base 가 어떤 가정 위에서 동작하는지를 정리합니다.
자동 적용 가능, 절대 안 건드림, 사람이 결정. 이 셋의 분기가 핵심입니다.
영역별 owner
섹션 제목: “영역별 owner”업데이트가 무엇을 덮어쓰고 무엇을 그대로 두는지는 파일 자리로 결정됩니다.
base-owned — 자동 갱신 대상
섹션 제목: “base-owned — 자동 갱신 대상”베이스가 SSOT인 자리. 사용자가 편집해도 다음 update에서 베이스 버전으로 돌아갑니다.
| 경로 | 무엇 |
|---|---|
.claude/skills/{base-skill-name}/ | 베이스 스킬 정의 |
.claude/agents/*.md | 베이스 agent 정의 |
.claude/hooks/*.sh + .claude/hooks/README.md | 베이스 훅 |
.claude/settings.json | 베이스 훅 등록 |
AI_AUTOMATION.md | 도메인 SSOT |
베이스 스킬 본문은 직접 수정하지 않는 것이 원칙입니다. 자기 스킬을 추가하고 싶으면 별도 디렉토리(예: .claude/skills/my-team-{name}/)에 만듭니다. base-owned 영역에 새 스킬이 추가되어도 사용자 자기 디렉토리는 영향받지 않습니다.
user-owned — 절대 안 건드림
섹션 제목: “user-owned — 절대 안 건드림”| 경로 | 무엇 |
|---|---|
src/ | 사용자 소스 |
manifest.config.ts | 사용자 manifest |
package.json | 사용자 의존성 |
docs/design/extension-spec.md | 사용자 작성 사양 |
docs/adr/*.md (README.md 제외) | 사용자 결정 기록 |
docs/distribution/* | build 산출 |
.claude/state/*, .claude/session-state/*, .claude/agent-memory/* | 런타임, 세션, 메모리 |
LICENSE, COMMERCIAL-LICENSE.md | 라이선스 |
라이선스 파일은 베이스가 갱신해도 자동으로 덮어쓰지 않습니다. 베이스에서 갱신이 있었다면 안내만 띄우고 사용자가 수동 결정합니다.
mixed — 3-way 안내
섹션 제목: “mixed — 3-way 안내”CLAUDE.md, README.md, AGENTS.md 셋. 베이스와 사용자 양쪽 편집이 동시에 들어갈 수 있는 자리라서 자동 갱신하지 않고 diff만 보여주고 묻습니다.
옵션 셋:
- 베이스 버전으로 통째 덮기. 사용자 편집은 사라집니다
- 3-way merge.
git merge-file로 합치고 충돌이 나면 직접 풉니다 - 미루기. 다음 호출까지 그대로 둡니다
사전 셋업 — 한 번만
섹션 제목: “사전 셋업 — 한 번만”베이스를 git remote 로 등록합니다.
git remote add base https://github.com/ddakit/chrome-ext-base.gitgit remote -vgit remote -v 출력에 base 가 fetch URL로 두 줄 보이면 정상입니다. 첫 /update-from-base 호출이 이 단계를 자동으로 안내하므로 미리 칠 필요는 없습니다.
상태 파일은 .claude/state/base-upstream.json 에 들어갑니다.
{ "remote": "base", "branch": "main", "last_synced_commit": "<hash>", "last_synced_at": "<ISO>"}last_synced_commit 부터 base/main 까지의 변경분만 보면 되니, 처음 한 번 채워지고 나면 다음부터는 도구가 알아서 잡습니다.
한 사이클
섹션 제목: “한 사이클”/update-from-base 또는 자연어로 “베이스 업데이트 받아줘” 라고 부르면 다음을 거칩니다.
git status --porcelain으로 dirty 검사. 저장 안 된 변경이 있으면git stash권유git fetch base maingit diff --name-status <last_synced_commit>..base/main로 변경 파일을 영역별로 분류- base-owned 변경 요약 출력. 새 스킬 N개, 갱신된 훅 M개, AI_AUTOMATION.md 갱신 여부 한 줄씩
- 사용자 yes 시
git checkout base/main -- .claude/skills/ .claude/agents/ .claude/hooks/ .claude/settings.json AI_AUTOMATION.md - mixed 파일은 한 개씩 옵션 셋 중 골라 적용
- 적용 후 검증.
.sh파일에chmod +x,settings.jsonJSON 파싱, 새 스킬의 trigger 키워드 나열 .claude/state/base-upstream.json갱신- commit 권유. 메시지는
chore(base): sync to {short-hash} ({N}개 파일)
기본 흐름은 30초에서 2분 사이로 끝납니다. mixed 파일 결정에 시간이 더 걸리는 한 분기가 있습니다.
베이스 스킬을 본인이 수정한 흔적이 있을 때
섹션 제목: “베이스 스킬을 본인이 수정한 흔적이 있을 때”.claude/skills/{base-skill}/ 안 파일을 사용자가 commit으로 수정한 적이 있으면 (git log 로 감지) 그 파일은 base-owned 가 아니라 mixed 로 처리됩니다. 자동 덮어쓰면 사용자 작업이 사라지기 때문입니다.
이걸 피하고 싶으면 베이스 스킬을 직접 수정하지 말고, 같은 trigger 키워드를 가진 별도 스킬을 자기 디렉토리에 만듭니다. 두 스킬이 같이 있으면 매뉴얼이 같은 키워드로 자기 쪽 스킬을 부릅니다. 베이스가 그 스킬을 갱신해도 자기 스킬은 그대로 살아있습니다.
베이스가 force-push 했을 때
섹션 제목: “베이스가 force-push 했을 때”last_synced_commit 이 base/main 히스토리에 더 이상 없으면 (force-push 된 경우) 도구는 자동 적용을 멈추고 안내만 띄웁니다. 일반 케이스는 아닙니다. 베이스가 sensitive 한 commit을 지웠거나 라이선스 위반 콘텐츠를 빼야 했을 때 발생합니다.
복구는 손작업입니다.
- 사용자 영역(
src/,docs/design/,docs/adr/,manifest.config.ts,package.json)을 본인 브랜치로 빼 둡니다 - 베이스를
base/main으로 reset 받아 새 베이스 위에 자기 작업을 다시 올립니다 - cherry-pick 또는 직접 복사로 사용자 영역을 복원합니다
이 자리는 /recover-from-blocked 가 다루는 영역이 아닙니다. force-push 가 실제로 일어나면 베이스 메인테이너가 별도로 안내합니다.
왜 자동 적용이 아닌 영역 분류인가
섹션 제목: “왜 자동 적용이 아닌 영역 분류인가”가장 단순한 설계는 git pull base main 한 줄입니다. 그렇게 하지 않은 이유 둘.
라이선시는 자기가 산 시점의 코드 위에 자기 작업을 쌓은 사람입니다. git pull 은 베이스 변경과 사용자 변경을 같은 레이어로 보고 merge commit을 만듭니다. 비개발자에게는 그 merge commit과 그 뒤에 따라오는 충돌 해결이 그대로 막히는 자리입니다.
base-owned 영역은 베이스가 SSOT라는 합의가 있습니다. 그 합의가 있는 자리만 자동 덮어쓰는 게 안전합니다. 합의가 없는 자리(mixed)는 사람이 결정하게 둡니다. fork 가 진화하지 않으면 베이스 가치가 한 번 산 시점에서 멈추고, fork 가 무방비로 진화하면 사용자 작업이 날아갑니다. /update-from-base 는 그 둘 사이에 박은 채널입니다.
인접 자리
섹션 제목: “인접 자리”- 비개발자 호흡으로 같은 절차를 따라가는 자리는 비개발자용 매뉴얼 업데이트 에 있습니다
- 이 스킬이 베이스 thesis 와 라이선스 모델 양쪽의 안전망인 이유는 intro 의 “지금 빠져 있는 것” 단락 옆에 두고 같이 봅니다