# Merge Check

> PR을 머지해도 되는지 판단하는 머지 전 최종 리뷰. PR이 무엇을 했는지 먼저 요약하고, 기존에 잘 동작하던 기능이 깨지지 않았는지(회귀)를 가장 꼼꼼히 검증한 뒤, 동작 정확성·코드 스타일·CI까지 점검해 머지 가능/불가를 판정하고, `yarn dev`로 직접 열어봐야 할 화면 목록까지 알려줍니다. "머지해도 되나", "머지 전에 봐줘", "이 PR 리뷰해줘", "PR 괜찮은지 확인", "approve해도 되나", "머지 전에 뭘 확인해야 하나" 같은 요청이나, 사용자가 PR 링크만 던져줄 때 반드시 이 스킬을 사용하세요. 현재 브랜치에 연결된 PR이 있으면 링크 없이도 동작합니다.

- Skill: `pinpoint-apm/merge-check` (Agent Skill)
- Install (CLI): `npx skillmds@latest add pinpoint-apm/merge-check`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pinpoint-apm/merge-check/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: pinpoint-apm (https://skillmd.com/u/pinpoint-apm)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/pinpoint-apm/merge-check

---


# 머지 전 최종 리뷰 (merge-check)

**이 스킬의 목적은 "머지 버튼을 눌러도 안전한가"에 답하는 것입니다.**

가장 중요한 판단 기준은 하나입니다: **기존에 잘 동작하던 기능이 그대로 동작하는가.**
새 기능이 조금 부족한 건 다음 PR에서 고칠 수 있지만, 잘 쓰던 기능이 깨지면 사용자가 바로 피해를 봅니다.
그래서 이 스킬은 "새로 추가된 코드가 예쁜가"보다 **"이 변경이 무엇을 건드렸고, 그것을 쓰던 곳들이 아직 멀쩡한가"**에 시간을 더 씁니다.

## 절대 하지 않는 것

- **머지하지 않습니다.** `gh pr merge`는 어떤 경우에도 실행하지 않습니다. 이 스킬은 판단만 하고, 머지는 사용자가 합니다.
- **코드를 고치지 않습니다.** 문제를 찾으면 보고합니다. 고치는 건 별개 작업(`/apply-review`)입니다.
- **GitHub에 아무것도 쓰지 않습니다.** 결과는 대화창에만 한국어로 보고합니다. PR 코멘트나 Approve는 사용자가 명시적으로 요청할 때만, 확인을 받고 남깁니다.
- **확인하지 않은 것을 확인한 척하지 않습니다.** 못 본 건 "확인 못 함"으로 적습니다. 근거 없는 ✅ 는 이 스킬을 쓰는 의미를 지웁니다.

## 0단계: 어떤 PR인지 확정 + 작업 중인 내용 보호

```bash
git branch --show-current
git status --porcelain          # 커밋 안 된 작업이 있는지 먼저 확인
git rev-parse HEAD              # 로컬이 보고 있는 코드
gh pr view --json number,title,url,headRefName,headRefOid,baseRefName,state,mergeable,author
```

**대상 PR 정하기**

- `gh pr view`가 PR을 찾으면 → 그 PR이 대상입니다. 링크를 따로 받지 않습니다.
- 못 찾거나 현재 브랜치가 `master`이면 → **멈추고 PR 링크를 요청**합니다. 추측하지 않습니다.
  예: "현재 브랜치에 연결된 PR을 찾지 못했어요. 리뷰할 PR 링크를 알려주세요."
- 사용자가 링크를 줬으면 항상 그 링크가 우선입니다. 링크에서 `{owner}/{repo}`와 PR 번호를 파싱합니다.

**내가 읽는 코드가 정말 그 PR의 코드인가 (놓치기 쉬움)**

`git rev-parse HEAD`와 PR의 `headRefOid`가 다르면, **로컬에서 보고 있는 코드가 PR에 올라간 코드가
아닙니다.** 리베이스했지만 아직 푸시하지 않은 경우가 흔합니다. 이때 그냥 리뷰하면 "PR을 검증했다"고
말할 수 없습니다. 두 커밋의 코드가 실제로 같은지 확인하세요:

```bash
git diff --stat {headRefOid} HEAD    # 비어 있으면 코드는 동일하고 베이스만 다르다
```

- **차이가 없거나 무관한 파일뿐이면** → 그대로 진행하고, 보고에 "로컬이 리베이스로 앞서 있으나 코드는
  동일"이라고 한 줄 적습니다.
- **차이가 있으면** → 어느 쪽을 리뷰할지 사용자에게 확인합니다. 로컬만 있는 수정은 PR에 없으므로,
  그것까지 통과 판정에 넣으면 실제 머지될 코드와 어긋납니다.

**사용자의 작업 보호**

검증을 위해 브랜치를 옮겨야 할 수도 있습니다. 다만 항상 위험한 건 아니니 구분하세요:

- **이미 그 PR의 브랜치에 있으면** 체크아웃이 필요 없습니다. 그냥 진행합니다.
- **untracked 파일(`??`)만 있으면** 체크아웃·머지가 그 파일을 건드리지 않으므로 그대로 진행합니다.
  (보고에 한 줄 언급만)
- **수정·스테이징된 변경(`M`, `A` 등)이 있으면** 체크아웃하지 말고 사용자에게 먼저 묻습니다:
  "커밋되지 않은 변경이 있어요. ① 코드 읽기만으로 리뷰 ② stash 후 진행 — 어느 쪽으로 할까요?"

브랜치를 옮겼다면 **리뷰가 끝나고 반드시 원래 브랜치로 돌려놓고**, 그 사실을 보고에 적습니다.

## 1단계: 이 PR이 무엇을 했는지 먼저 요약한다

판정보다 요약이 먼저입니다. **무엇을 하려던 PR인지 모르면 "제대로 했는지"도 판단할 수 없습니다.**

```bash
gh pr view {number} --repo {owner}/{repo} --json title,body,commits,files,additions,deletions

# 변경 규모는 git으로 봅니다. (`gh pr diff`에는 --stat이 없는 버전이 있어 그대로 쓰면 실패합니다.)
git fetch upstream master
git diff --stat upstream/master...HEAD          # 세 점: 공통 조상부터 이 브랜치까지
```

읽을 것:

- **PR 제목·본문·연결된 이슈** — 이 PR이 풀려던 문제가 무엇인가
- **커밋 메시지들** — 어떤 순서로 무엇을 했는가
- **변경 파일 목록과 규모** — 어디를 건드렸는가

여기서 나오는 요약은 사용자에게 보여주는 첫 항목이며, **의도(PR 본문)와 실제(diff)가 어긋나는지**를 보는 기준이기도 합니다.
"본문에는 A만 고쳤다고 썼는데 diff에는 B도 바뀌어 있다" — 이건 그 자체로 리뷰 대상입니다.
의도하지 않은 파일이 섞여 들어온 것일 수 있고, 그게 회귀의 흔한 원인입니다.

## 2단계: 실제로 빌드·테스트를 돌린다

기본 동작은 **실제 실행**입니다. 코드를 읽어서 "괜찮아 보인다"와 빌드가 통과하는 것은 다른 증거입니다.
(사용자가 "빠르게 봐줘"라고 했다면 이 단계를 건너뛰고 CI 결과 조회로 대체하되, **보고에 "직접 실행하지 않음"을 명시**합니다.)

검증은 **머지된 뒤의 코드**에 대해 해야 의미가 있습니다. PR 브랜치 단독으로 통과해도,
그 사이 master에 들어간 다른 변경과 부딪히면 머지 직후에 깨집니다. 그래서 합쳐 놓고 돌립니다.

```bash
gh pr checkout {number} --repo {owner}/{repo}
git fetch upstream master
git merge --no-commit --no-ff upstream/master   # 커밋하지 않고 합친 상태만 만든다
```

- **충돌이 나면** → `git merge --abort` 후, 충돌 파일을 보고 항목으로 올립니다(조건부 또는 머지 불가 사유).
  이후 리뷰는 PR 브랜치 상태로 코드 읽기 중심으로 이어갑니다.
- **깨끗하게 합쳐지면** → 그 상태(= 머지 후 master의 모습)에서 검증을 돌립니다.

```bash
# web-frontend/src/main/v3 에서
yarn build      # TypeScript 검사 + 프로덕션 빌드
yarn test       # 전체 워크스페이스 테스트
yarn lint
```

검증이 끝나면 `git merge --abort`로 합친 상태를 되돌립니다. (머지 결과를 남기지 않습니다.)

- **빌드 실패 → 무조건 머지 불가.** 더 볼 것 없습니다.
- **테스트 실패 → 실패한 테스트가 이 PR 때문인지 확인.** upstream/master에서도 같은 테스트가 실패하면 기존 문제입니다.
  그 구분을 하지 않고 "테스트 실패"라고만 보고하면 사용자가 헛수고합니다.
- **CI 결과도 함께 봅니다.** `gh pr checks`는 실패 여부만 알려주고 이유를 말해주지 않으니,
  실패한 것이 있으면 반드시 내용까지 읽습니다. (품질 게이트 실패는 저장소 자체의 머지 기준입니다.)

```bash
gh pr checks {number} --repo {owner}/{repo}

# 실패한 검사의 실제 사유 (예: SonarCloud 품질 게이트가 무엇을 걸었는지)
gh api repos/{owner}/{repo}/commits/{headRefOid}/check-runs \
  --jq '.check_runs[] | select(.conclusion=="failure") | "\(.name) | \(.output.title) | \(.output.summary)"'
```

## 3단계: 기존 기능 회귀 점검 — 이 스킬의 핵심

여기에 가장 많은 시간을 씁니다. 방법이 중요합니다. diff를 위에서 아래로 훑어 읽는 것은
**추가된 코드**를 보게 만들 뿐이고, 회귀는 거의 항상 **추가가 아니라 변경과 삭제**에서 나옵니다.

### 3a. PR을 만든 뒤 master가 얻은 변경과 부딪히는지 본다

**이건 이 PR의 diff만 봐서는 절대 보이지 않습니다.** PR 브랜치 안에서는 완벽한 코드가, 그사이 master에
들어온 다른 변경과 만나 깨질 수 있습니다. 머지 리뷰가 일반 코드 리뷰와 다른 지점이 바로 여기입니다.

```bash
# 이 PR의 베이스 이후 master가 새로 얻은 커밋
git log --oneline $(git merge-base HEAD upstream/master)..upstream/master
```

커밋 목록을 **읽고**, 이 PR이 건드린 영역과 겹치는 것이 있으면 그 커밋의 diff를 직접 확인합니다.
특히 백엔드 변경은 프론트와 계약으로 연결돼 있어 겹치기 쉽습니다:

- **API 응답·상태 코드가 바뀌었나** — 프론트가 특정 상태 코드(404 등)나 필드를 보고 분기한다면,
  그 규칙이 아직 유효한지 확인합니다. (실제로 "없는 이름은 404" 프론트 + "400을 반환" 백엔드가
  같은 시점에 올라온 적이 있습니다.)
- **필수 파라미터가 늘었나** — 프론트가 그 값 없이 보내는 경로가 있으면 머지 직후 400이 됩니다.
- **조용히 넘어가던 것이 예외가 되었나** — 기본값으로 대체되던 동작이 오류로 바뀌면, 그에 의존한
  화면이 깨집니다.

겹치는 것이 없으면 "master의 새 커밋 N개, 이 PR과 겹치는 영역 없음"이라고 적고 넘어갑니다.

### 3b. "위험한 변경"만 골라낸다

diff에서 다음을 뽑아 목록으로 만듭니다. 추가만 된 코드는 회귀 위험이 낮으니 뒤로 미룹니다.

```bash
git diff upstream/master...HEAD          # 전체 diff를 실제로 읽습니다
```

| 위험 신호 | 왜 위험한가 |
|---|---|
| 지워진 줄 / 삭제된 파일 · export | 쓰던 곳이 남아 있으면 그대로 깨집니다 |
| 함수 시그니처 · props · 반환 타입 변경 | 호출자가 옛 계약을 기대합니다 |
| 기본값 변경, optional ↔ required 변경 | 인자를 안 넘기던 호출자의 동작이 조용히 바뀝니다 |
| 조건문(`if`, 삼항, `&&`) 수정 | 기존 경로가 새 조건에 걸려 빠질 수 있습니다 |
| 이름 변경 (rename) | 참조를 하나라도 놓치면 깨집니다 |
| 공용 파일 수정 (hooks/api, atoms, constants, utils) | 소비자가 많아 파급이 큽니다 |

### 3c. 목록의 항목마다 "쓰던 곳 전부"를 찾아 확인한다

**이게 핵심 작업입니다.** 변경된 심볼 하나하나에 대해:

```bash
git grep -n "심볼이름" -- '*.ts' '*.tsx'      # 사용처 전부. 개수를 셉니다
```

그리고 **사용처를 샘플링하지 말고 전부 확인합니다.** 3곳뿐이면 3곳 다, 20곳이면 20곳 다.
너무 많아 전부 못 봤으면 **몇 곳 중 몇 곳을 봤는지 숫자로 보고**합니다 ("18곳 중 12곳 확인").
"대충 괜찮아 보인다"는 이 스킬에서 가장 위험한 문장입니다.

각 사용처에서 확인할 것: **이번 변경 후에도 이 호출이 예전과 같은 결과를 내는가.**
타입 체크만 통과하는 것으로는 부족합니다 — 타입은 맞는데 동작만 달라지는 변경이 제일 잡기 어렵습니다
(기본값 변경, 조건 뒤집힘, 정렬 순서 변경, 캐시 키 변경 등).

`.claude/rules/code-review-policy.md`의 영향 분석 절차를 그대로 따릅니다.

### 3d. Pinpoint에서 실제로 회귀가 났던 자리들

이 프로젝트에서 조용히 깨지기 쉬운 지점입니다. 해당하는 변경이 있으면 반드시 확인합니다.

- **설정 플래그 분기** — `experimental.enableServiceMap` 같은 플래그. **플래그가 꺼진 기존 사용자의 경로가
  그대로인가**를 별도로 확인합니다. 켠 쪽만 확인하고 넘어가는 실수가 흔합니다. 그 기능에 대한 규칙
  문서가 `.claude/rules/`에 있으면 함께 읽습니다.
- **Jotai 아톰** — 아톰은 화면 remount로 지워지지 않습니다. 아톰을 추가·수정했으면 **읽는 모든 컴포넌트**와
  **초기화 시점**을 확인합니다. 안 지워진 옛 값으로 조회가 나가 400을 받는 사고가 실제로 있었습니다.
- **React Query 쿼리 키** — 키가 바뀌면 캐시 무효화가 깨지거나, 다른 데이터가 같은 키에 섞입니다.
- **라우트 경로 / URL 파라미터** — 경로 형태가 바뀌면 기존 링크·북마크가 죽습니다. 로더의 검증·리다이렉트가
  옛 형태도 받아주는지 확인합니다.
- **i18n 키** — 제거·이름 변경된 키를 다른 화면이 아직 쓰고 있지 않은지 `git grep`으로 확인합니다.
- **컴포넌트 props** — 렌더하는 모든 부모가 유효한 props를 넘기는지 확인합니다.
- **API 엔드포인트 · 응답 타입** — Java 쪽이 함께 바뀌었으면, 프론트가 기대하는 필드·형태와 맞는지 대조합니다.
  (백엔드 코드는 이 계약 부분만 봅니다. 그 외 Java 내부 로직은 이 스킬의 범위가 아니라고 밝히세요.)

### 3e. 판단이 안 서면 "모르겠다"가 정답이다

코드만으로 확신이 안 서면 **추측으로 ✅ 하지 말고** 그 항목을 "확인 필요"로 남기고,
사용자가 무엇을 어떻게 확인하면 되는지 알려줍니다 (예: "dev 서버에서 A 화면 → B 클릭 순서로 확인").
머지 여부를 잘못 통과시키는 비용이, 한 번 더 확인하는 비용보다 훨씬 큽니다.

## 4단계: PR이 의도한 동작을 정확히 하는가

1단계 요약에서 정리한 "이 PR이 풀려던 문제"를 다시 꺼내 대조합니다.

- 이슈에 적힌 증상이 이 변경으로 **실제로** 해소되는가 (코드를 따라가며 확인)
- 해피 패스뿐 아니라 **빈 데이터 · 로딩 · 오류 · 경계값**에서도 의도대로 동작하는가
- 문제를 근본에서 고쳤는가, 증상만 가렸는가
- 놓친 케이스가 있는가 (예: 한 화면만 고치고 같은 문제를 가진 다른 화면은 그대로)

깊은 동작 QA가 필요하면 `/qa-pr` 의 체크리스트(엣지 케이스, 상태 무결성, 컴포넌트 상호작용)를 활용합니다.

## 5단계: 그 밖에 머지 전에 봐야 하는 것들

- **코드 스타일 일관성** — `.claude/rules/code-style.md`, `/review-code` 체크리스트 기준.
  포맷팅뿐 아니라 **주변 코드와 같은 방식으로 쓰였는가**를 봅니다 (같은 일을 다른 패턴으로 하는 코드가
  섞이면 다음 사람이 어느 쪽을 따라야 할지 모르게 됩니다).
- **아키텍처 위치** — 라우팅은 `apps/web`, 나머지는 `packages/ui`. 훅·아톰·상수가 제자리에 있는가.
- **남아 있는 디버그 코드** — `console.log`, 주석 처리된 코드, `TODO`, 임시 하드코딩:
  ```bash
  git diff upstream/master...HEAD -- '*.ts' '*.tsx' | grep -nE '^\+.*(console\.(log|debug)|debugger|FIXME|XXX)'
  ```
- **커밋 메시지 규약** — `[#issue_number] Description`, 영어 (`.claude/rules/git-workflow.md`)
- **PR 범위** — 이슈와 무관한 변경이 섞여 있지 않은가
- **테스트** — 아톰·유틸·API 훅·라우트 로더가 바뀌었는데 테스트가 없으면 지적합니다 (핵심 경로)
- **타입 안전성** — 새로 들어온 `any`, 위험한 단언(`as`), 무시된 null 체크
- **성능** — 불필요한 리렌더, 누락된 `useEffect` 클린업, 큰 목록의 비효율 처리

## 6단계: 직접 눈으로 확인할 화면 목록을 만든다 (필수)

코드 추적·빌드·테스트로는 **실제로 화면에 무엇이 그려지는지**를 알 수 없습니다. 그래서 이 스킬은
"확인 못 했다"로 끝내지 않고, **사용자가 `yarn dev`로 무엇을 열어 무엇을 봐야 하는지**를 항상
목록으로 내놓습니다. 목록이 없으면 사용자는 어디서부터 봐야 할지 몰라 결국 아무것도 확인하지 않습니다.

```bash
yarn dev     # 포트 3000. /api/*는 localhost:8080(백엔드)로 프록시되므로 백엔드가 떠 있어야 데이터가 보인다
```

### 화면 목록을 뽑는 방법

변경된 파일에서 **화면까지 거슬러 올라갑니다.** 컴포넌트·훅은 그 자체로 화면이 아니므로, 사용처를
따라 `pages/`와 라우트까지 올라가야 어떤 주소를 열어야 할지 나옵니다.

```bash
# 변경된 컴포넌트/훅을 누가 쓰는지 → 그 사용처를 또 누가 쓰는지 (pages/ 까지)
git grep -n "변경된컴포넌트\|변경된훅" -- '*.tsx' '*.ts'
```

주소는 `packages/ui/src/constants/path.ts`의 `APP_PATH`에서 확인합니다.

### 목록에 반드시 들어가야 하는 것

1. **기존 화면 (회귀 확인)** — 이번에 바뀐 공용 코드를 쓰는 **모든** 기존 화면. 새 기능 화면보다
   **먼저** 적습니다. 사용자가 제일 걱정하는 건 "잘 쓰던 게 깨졌나"입니다.
   공용 코드(`hooks/api`, `atoms`, `utils`, 공유 컴포넌트)를 건드렸다면 소비 화면이 여러 개일 테니
   샘플링하지 말고 다 적습니다.
2. **새 기능 화면 (의도 확인)** — 이 PR이 만든 동작. PR 본문의 테스트 계획에 있으면 그것을 재사용합니다.
3. **설정 플래그가 있으면 양쪽 다** — 켠 상태와 **끈 상태**. 끈 쪽이 기존 사용자의 화면이므로 더 중요합니다.
4. **코드로 확신이 안 섰던 항목** (3e에서 남긴 것) — 그게 바로 눈으로 봐야 하는 것입니다.

각 항목은 **"무엇을 보면 정상인지"**까지 적습니다. "servermap 확인" 같은 문장은 도움이 안 됩니다.
"노드를 클릭하면 오른쪽 패널에 그 노드 이름과 차트가 뜨는지" 처럼 판정 가능한 문장으로 씁니다.
브라우저 개발자도구 네트워크 탭에서 볼 것이 있으면(400 응답, 중복 요청 등) 그것도 적습니다.

## 7단계: 보고 (대화창, 한국어)

**항상 이 구조로** 보고합니다. 요약이 판정보다 먼저 오는 순서를 지킵니다 —
사용자는 "무엇을 한 PR인지" 이해한 뒤에 판정을 봐야 그 판정을 신뢰할 수 있습니다.

```markdown
## 1. 이 PR이 한 일
- **목적**: (이슈/PR 본문 기준, 한두 문장)
- **바꾼 것**: (파일 N개 / +A −B 줄, 핵심 변경 3~5개를 쉬운 말로)
- **의도와 diff의 차이**: (없으면 "없음")

## 2. 검증 결과
| 항목 | 결과 |
|---|---|
| upstream/master 병합 | 충돌 없음 / 충돌 (파일) |
| yarn build | 통과 / 실패 |
| yarn test | 통과 / 실패 (N건, 이 PR 때문인지 여부) |
| yarn lint | 통과 / 실패 |
| CI | 상태 |

## 3. 기존 기능 회귀 점검 (가장 중요)
**master의 새 변경과의 충돌**: 새 커밋 N개 → 겹치는 것마다 판단 + 근거 (없으면 "겹침 없음")
**위험 변경마다**: (항목) — 사용처 N곳 중 M곳 확인 → 판단 + 근거 (`파일:라인`)
**확인하지 못한 것**: (항목) — 왜 확인 못 했는지 (→ 6번 목록으로 넘긴다)

## 4. 동작 정확성
- 의도한 문제가 해소되는가: 판단 + 근거
- 엣지 케이스: 확인 결과

## 5. 그 외 (스타일 · 구조 · 기타)
심각도 순으로: Critical / Warning / Suggestion

## 6. 직접 확인할 화면 (`yarn dev`)
기존 화면 — 회귀 확인:
| 화면 | 주소 | 무엇을 보면 정상인지 |
|---|---|---|
| (화면 이름) | `/경로/...` | (판정 가능한 문장) |

새 기능 — 의도 확인:
| 화면 | 주소 | 무엇을 보면 정상인지 |
|---|---|---|

## 7. 판정
**✅ 머지 가능** / **⚠️ 조건부** / **❌ 머지 불가**
- 이유: (한두 문장)
- 머지 전에 해야 할 일: (있으면 목록)
```

### 판정 기준

- **❌ 머지 불가** — 빌드·테스트 실패, 기존 기능이 깨진 것을 **확인**했음, 머지 충돌 미해결
- **⚠️ 조건부** — 회귀 위험이 있는데 코드만으로는 확정할 수 없음, CI 검사(품질 게이트 등)가 빨간불,
  또는 고쳐야 할 문제가 남았지만 치명적이지 않음.
  **무엇을 확인·수정하면 ✅ 가 되는지 반드시 적습니다.**
- **✅ 머지 가능** — 검증·CI 통과 + 위험 변경의 사용처를 확인했고 문제 없음

> 6번의 화면 목록은 판정과 무관하게 **항상** 내놓습니다. ✅ 라도 "코드로는 문제를 못 찾았다"는
> 뜻이지 "화면을 봤다"는 뜻은 아니고, 그 차이를 사용자가 알아야 스스로 판단할 수 있습니다.

> 애매하면 ✅ 를 주지 마세요. ⚠️ 는 사용자가 5분 더 확인하게 만들지만, 잘못된 ✅ 는 깨진 코드를 배포합니다.
> 다만 근거 없이 ⚠️ 를 남발하는 것도 도움이 되지 않습니다 — ⚠️ 에는 항상 "무엇을 확인해야 하는지"가 붙어야 합니다.

### 마지막 정리

- 브랜치를 옮겼다면 원래 브랜치로 복귀했는지 확인하고 보고에 한 줄 적습니다.
- `git merge --abort`, stash 복원 등 임시 상태가 남지 않았는지 확인합니다.
- 사용자가 PR 코멘트나 Approve를 원하면 그때 확인을 받고 남깁니다. 본문은 **영어**입니다
  (`.claude/rules/git-workflow.md`).

