---
name: commit-convention
description: Use when creating any meaningful git commit (checkpoint 깔끔저장, 게이트·설정 변경, 사용자가 커밋을 요청할 때) — type(scope) 헤더 + Why/How 본문 + Refs 푸터 규약. 임시저장(핑퐁 checkpoint)은 경량 형식을 유지한다.
---

# Commit Convention — 커밋 메시지 규약

커밋 히스토리는 사람과 AI가 변경 맥락을 이해하는 데이터다. "무엇을 바꿨는지"는 diff가 말하니, 메시지는 **왜(Why)와 어떻게(How)**를 남긴다. (원본: 팀 공통 커밋 규칙 — 이 템플릿에선 git이 Claude 내부 도구라 승인 게이트 없이 자동 적용하고, 사용자에게 git 용어를 노출하지 않는다.)

## 형식

```
type(scope): subject

- Why: 왜 이 변경이 필요했나 — 문제·요구·리스크
- How: 핵심 접근과 트레이드오프

Refs: PROJ-1234
Co-Authored-By: Claude <noreply@anthropic.com>
```

- header / body / footer는 빈 줄로 구분한다.
- **type** (소문자만): `feat` `fix` `refactor` `perf` `test` `docs` `chore` `build` `ci` `revert`
- **scope**: 지배적 변경 영역 하나 — FSD 슬라이스명(`pages/deals/**` → `deals`, `shared/**` → `shared`). 여러 영역에 걸치면 핵심 하나 또는 생략. 소문자·숫자·`-`만.
- **subject**: 명령형, 마침표 없음, ~50자. 한국어 가능(회사 관행). 티켓 키를 헤더에 넣지 않는다.
- **body**: 2~6줄, Why/How 중심. 파일 목록 나열 금지 — diff 재설명은 가치가 없다.
- **Refs**: 기획서·티켓에서 시작한 작업이면 티켓 키(`PROJ-1234` 등 `[A-Z]+-\d+`)나 원문 아카이브 경로(`docs/specs/<slug>.md`)를 남긴다. 티켓 키는 브랜치명·아카이브 문서에서 찾는다.
- **Co-Authored-By 트레일러는 모든 커밋에 필수** — AI가 보조한 이력을 투명하게 남긴다.

## 적용 범위 (checkpoint 스킬의 2단 저장과 맞물림)

- **깔끔저장(하드 관문)·의미 있는 변경**: 이 규약 전체 — Why/How 본문 필수.
- **임시저장(핑퐁 checkpoint)**: 경량 유지 — `chore: checkpoint <무엇이 있던 상태>` + 트레일러만. 핑퐁 속도가 우선이라 본문을 요구하지 않는다.

## 커밋 전 안전 검사

1. staged에 시크릿류가 있으면 커밋하지 않는다: `.env`·`.env.*`·`*.pem`·`*.key`·`id_rsa*`·`credentials*.json` — 발견하면 `.gitignore`부터 고치고 unstage한다.
2. staged diff에 `console.log(`·`debugger;`가 남아 있으면 지우고 커밋한다.
3. 서로 무관한 변경이 섞여 있으면 나눠 커밋한다 — 한 커밋 = 화면으로 확인받은 한 단위(checkpoint 규칙). 뭉치면 "그것만 되돌려줘"가 불가능해진다.

## 실행

`-m`을 반복하면 빈 줄이 자동 삽입된다:

```bash
git commit \
  -m "feat(deals): 리드 목록에 상태 다중선택 필터 추가" \
  -m "- Why: 팀별 상태 체계가 달라 단일 셀렉트로는 걸러볼 수 없었음
- How: 상태 집합을 팀 설정에서 파생해 다중선택 팝오버로, 선택값은 URL에 저장" \
  -m "Refs: PROJ-686" \
  -m "Co-Authored-By: Claude <noreply@anthropic.com>"
```

- 훅(pre-commit)이 실패하면 `--no-verify`로 우회하지 않는다 — `fix-error`로 고치고 재시도한다.
- amend는 쓰지 않는다(이력 보존 — checkpoint 되돌리기의 전제).

## 예시

좋은 예:

```
feat(applicants): 지원자 목록에 이름 검색 추가

- Why: 지원자가 50명을 넘으면서 스크롤로 찾기 어렵다는 요청
- How: 검색어를 URL에 저장해 새로고침·공유에도 유지, 표와 카운트가 같은 파생값을 공유

Refs: docs/specs/applicant-list.md
Co-Authored-By: Claude <noreply@anthropic.com>
```

나쁜 예: `update stuff` (type 없음) · 본문 없는 feat · `Feat(Web): Add filters.` (대문자·마침표)
