기획 협업 스킬 가이드
기능 명세를 한 곳에서 만들고, 한 링크로 공유하고, 그 링크 위에서 함께 검토하는 방법.
이게 무엇인가
기획 산출물이 메신저·메일·개인 드라이브로 흩어지면 누구는 v1, 누구는 v2 를 본다.
이 레포는 명세를 한 곳(specs/)에 두고, 기능마다 영구 고정 링크 하나를
발급한다. 명세가 바뀌면 같은 주소의 내용이 갱신되므로 링크를 다시 뿌릴 일이 없다.
| 반복되던 문제 | 구조로 없앤 방법 |
|---|---|
| 누구는 v1, 누구는 v2를 본다 | 기능당 고정 URL 1개. 병합하면 CI가 같은 주소를 갱신하고, 화면 상단에 버전·상태·최종변경이 늘 떠 있다 |
| md는 읽기 어렵고 목업은 따로 논다 | 명세·화면·흐름도·점검·문의가 한 장에 목차로 묶인다 |
| 변경점을 못 찾는다 | 버전마다 스냅샷이 남고, as is ↔ to be 를 요구사항 단위로 대조해 준다 |
| 물어볼 데가 없어 메신저로 흩어진다 | 화면에서 바로 문의를 남기면 qna.md 에 커밋되고 담당자에게 이슈로 알림이 간다 |
### REQ-001,
목업의 data-req="REQ-001", 흐름도의 REQ 언급, 점검표의 ## REQ-001,
문의의 - 관련: REQ-001 이 같은 ID를 공유한다. 어긋나면 lint 가 잡는다.
1. 설정
팀원 — 쓰는 사람 (최초 1회, 5분)
레포 접근 권한을 받는다. 레포 소유자가 Settings → Collaborators 에서
Write 권한으로 추가한다.
클론하고 스킬이 잡히는지 확인한다.
git clone https://github.com/<소유자>/DaouClaude.git
cd DaouClaude
python3 .claude/skills/spec-hub/scripts/spechub.py version # 사본 위치·버전
스킬은 레포 안에 들어 있다(.claude/skills/). 설치 과정이 없고,
의존성은 python3 뿐이다. 클론한 디렉터리에서 Claude Code 를 열면
spec-hub · spec-review 스킬과 CLAUDE.md 규칙이 자동으로 잡힌다.
개인 스킬 사본이 있으면 지운다. Claude 설정에 개인적으로 올린
spec-hub 이 남아 있으면 그쪽이 실행될 수 있다. 업로드본은 git 을 따라가지
않아 갱신이 멈춘다. 위 version 이 찍는 경로로 지금 무엇이 도는지 확인한다.
읽기만 하는 사람
할 일이 없다. 링크만 받으면 된다. 레포 권한도, 계정 생성도 필요 없다. 사내 이메일로 접근이 걸러진다. 전체 목록 페이지를 받아 두면 기능이 늘어도 링크를 추가로 받을 필요가 없다.
관리자 — 레포당 1회
한 사람이 한 번만 하면 되고, 그 뒤로는 아무도 만지지 않는다.
호스팅 (Cloudflare Pages)
- Pages 프로젝트를 만들고
.spechub.json의base_url·project를 그 주소·이름으로 맞춘다. - GitHub Actions Secrets 에
CLOUDFLARE_ACCOUNT_ID·CLOUDFLARE_API_TOKEN을 넣는다. - 접근 제한이 필요하면 Cloudflare Access 로 도메인(
@daou.co.kr)을 건다.
화면에서 글을 쓰게 하려면 (문의·답변·점검 체크)
정적 페이지에는 저장할 곳이 없으므로, 같은 도메인의 Pages Function 이 받아 git 에 커밋한다. Cloudflare → Settings → Environment variables:
| 이름 | 값 | 유형 |
|---|---|---|
GITHUB_TOKEN | 이 레포의 Contents: Read and write 하나만 가진 Fine-grained PAT | Secret |
GITHUB_REPO | owner/repo | 일반 |
GITHUB_BRANCH | main | 일반 |
.spechub.json 은 레포에 커밋되는
파일이라 토큰을 넣으면 안 된다. 권한도 이 레포의 Contents 쓰기 하나로 최소화한다 —
권한이 넓으면 사고 범위도 넓어진다.
curl -s https://<도메인>/api/ask
# {"ok":true,"repo":"owner/repo","branch":"main"} ← 설정 확인 (값은 내보내지 않는다)
문의 알림 받을 사람
.spechub.json 의 notify 에 GitHub 계정을 적는다. 그 계정은
이 레포의 협업자여야 지정이 먹는다.
"notify": {
"assignees": ["Davidjeong1"],
"labels": ["문의"],
"by_feature": { "DOP-20230": ["gildong"] } // 기능별로 다르면
}
2. 실행
누구의 작업이든 끝은 커밋 · PR 이다. 수동 게시 단계는 없다.
요구사항을 쓰고, 화면 목업을 그리고, 버전을 올리고, 다른 부서 변경을 확인해 병합한다.
퍼블을 publish/ 에 넣는다. 목업과 파일명이 같으면 짝이 되어 퍼블 대조가 생긴다.
화면을 보며 점검 항목을 체크하고, 막히는 것은 문의로 남긴다. 둘 다 화면에서 바로 된다.
링크를 연다. 그게 전부다. 항상 최신이 보인다.
기획의 4단계 — 명세를 조금이라도 바꿨다면 끝까지 밟는다
소스 수정 — spec.md / mockups/ / qa.md
bump — 버전을 올리고 변경이력에 "무엇이 왜 바뀌었나" 를 REQ-ID 와 함께 적는다.
고칠 것을 다 고친 뒤 한 번만 한다(PR 올리기 직전).
lint — REQ-ID 정합성. 오류가 남아 있으면 안 된다. CI 도 같은 검사를 한다.
커밋 → PR → main 병합. 병합되면 CI 가 고정 링크를 갱신한다.
화면에서 바로 할 수 있는 것 세 가지
레포를 몰라도 된다. 링크를 연 사람이 그 자리에서 쓰고, 결과는 git 에 남는다.
| 화면 | 저장되는 곳 | 반영 |
|---|---|---|
| 문의 탭 → 문의 남기기 | qna.md 에 ## Q-00N | 커밋 → CI 재배포라 1~2분 |
| 문의 탭 → 답변 달기 | 그 문의 아래 ### 답변 + 상태 갱신 | |
| 개발기능점검 → 체크박스 | qa.md 의 [ ] ↔ [x] + 날짜 |
과거 버전 스냅샷에서는 전부 읽기 전용이다 — 지나간 시점에 글을 다는 것은 말이 되지 않는다.
명령어 (직접 돌릴 때)
S=".claude/skills/spec-hub/scripts/spechub.py" python3 $S new DOP-19102 "연차정책 관리" # 새 기능 폴더 + 로우파이 목업 템플릿 python3 $S status # 전체 현황 (버전·상태·점검·문의) python3 $S lint # REQ-ID 정합성 python3 $S build specs/<기능> # hub.html 미리보기 (배포 없이) python3 $S review specs/<기능> # 배포본과 지금 소스의 차이 python3 $S bump specs/<기능> --level minor --author 이름 --note "REQ-003 …" R=".claude/skills/spec-review/scripts/specreview.py" python3 $R pack # 검토 문서 한 번에 (CI 가 쓰는 것) python3 $R publish specs/<기능> # 퍼블 대조 (publish/ 가 있을 때) python3 $R diff specs/<기능> --from v0.7.0 --to v0.8.0 python3 $R check # 눌러야 아는 것 · 명세/점검 누락
3. 관리
버전과 스냅샷
변경이력의 각 버전은 그 시점 스냅샷({고정URL}/v0.6.0/)으로 남는다.
목업까지 그때 것이라 "그 버전에서 화면이 어땠는지" 를 눌러볼 수 있다. 스냅샷에는 과거
버전임을 알리는 배너가 뜬다 — 옛 명세를 최신으로 착각한 채 개발이 시작되는 것을 막는다.
검토 문서는 자동으로 붙는다
명세를 쓰면 spec-review 가 읽는 사람을 위한 문서를 만들어 같은 링크의 목차에
끼워 넣는다. 새 링크가 생기지 않는다.
목차는 기획 / 문서 / 바깥 문서 / 요구사항 네 묶음이고, 문서 는 다섯 자리로 고정되어 있다. 파일명 앞의 번호가 곧 그 자리다. 요구사항은 수십 개가 되기도 해서 접힌 채로 시작하고, 눌러서 펼친다(선택은 사람별로 기억된다).
| 자리 | 무엇 |
|---|---|
| 1. 기획 배경 및 영향범위 | 왜 이렇게 왔나. 처음 보는 사람이 여기부터 |
| 2. 기능정의서 | 바뀌는 화면을 실제 목업으로 깔고, 그 화면이 만드는 기능을 번호로 잇는다 |
| 3. 메뉴구조도 | 제품 메뉴의 어디에 붙는지 · 신설·이동 메뉴 |
| 4. 업무 프로세스 및 E2E 흐름도 | 명세 안의 mermaid 를 문서 한 장으로 |
| 5. 정책서 | 확정 규칙 전문. 개발·QA 가 근거로 삼는 원문 |
같은 번호로 파일을 직접 넣으면 그 자리는 생성물 대신 그것이 들어간다(생성물
표식이 없으면 덮어쓰지 않는다). 파일이 없는 자리는 목차에 준비 중 으로 남아,
무엇이 빠졌는지 그대로 보인다. 기능 지도·퍼블 대조·변경점·동작 점검표는 목차에 상시로
걸지 않는다 — 필요할 때 map·publish·diff·check
로 따로 뽑아 본다. 목차의 바깥 문서 에는 QA 진행 문서 링크가
걸린다 — 기능마다 다르면 spec.md 의 qa_url, 팀이 하나로
관리하면 .spechub.json 의 qa_url.
spec.md / mockups/ / qa.md 쪽이다.문의가 오면 담당자에게 알림이 간다
GitHub 은 커밋으로 알림을 보내지 않는다(레포를 Watch 해도 오는 것은 이슈·PR 뿐이다). 그래서 문의 커밋을 이슈로 옮긴다.
열린 이슈 목록이 곧 미답변 문의 목록이 된다. 따로 관리할 것이 없다. 알림이 오지 않으면 받는 사람의 GitHub → Settings → Notifications 에서 Participating 이 Email 로 켜져 있는지 본다.
CI 는 세 가지를 한다
| 언제 | 무엇 |
|---|---|
| PR 올릴 때 | 정합성 검사 + 빌드 검증. 요약란에 전체 현황과 변경 요약이 붙는다 — 기획은 이것만 보고 병합을 판단할 수 있다 |
| main 병합 | 검토 문서 생성 → 배포본 조립 → Cloudflare 배포. 고정 링크가 갱신된다 |
qna.md 변경 | 새 문의·답변을 가려 이슈를 만들거나 닫는다 |
main 브랜치에 Require a pull request before merging + 명세 검사를 필수 체크로 걸어 두면, 검사를 통과하지 않은 변경이 배포되는 일이 없어진다.
충돌은 두 곳에서만 난다
역할마다 만지는 파일이 달라 대체로 충돌이 없다. 예외 둘:
CHANGELOG.md— 새 항목이 늘 맨 위에 들어가 두 사람이 동시에bump하면 겹친다. 두 항목을 모두 남기고 버전 순서만 정리한 뒤spec.md의version을 맨 위 항목과 맞춘다.lint가 불일치를 잡는다.- 같은 요구사항 블록 — 도구가 아니라 오너가 정할 문제다.
owners.기획을 채워 두는 이유가 이것이다.
qna.md 는 묻는 쪽이 파일 끝에 이어 붙이고 기획이 그 아래 답을 다는
구조라 서로 다른 줄에 쓴다 — 위에 끼워 넣으면 그때부터 충돌이 난다.
스킬이 업데이트되면
스킬은 레포에 들어 있으므로 git pull 이 곧 업데이트다. 스킬만 바뀐 경우
(명세는 그대로인데 허브 화면 구성이 바뀐 경우)에는 bump 하지 않는다 —
기획 변경이 아니다. 병합하면 CI 가 다시 만들어 올린다.
문제 해결
| 증상 | 먼저 볼 곳 |
|---|---|
| 내가 올린 게 링크에 안 보인다 | main 에 병합됐는지. 브랜치 푸시만으로는 배포되지 않는다 → Actions 탭에서 배포 워크플로 성공 여부 |
| 목록에 내 기능이 없다 | specs/ 안에 있어야 한다. 레포 루트의 낱개 파일은 뜨지 않는다 |
| 문의를 남겼는데 오류가 난다 | /api/ask 를 열어 ok 값 확인 → Cloudflare 환경변수 3개 → 토큰의 Contents 권한 |
| 문의 알림이 안 온다 | 담당자가 레포 협업자인지 → 그 계정의 Notifications 설정 → Actions 에서 알림 워크플로 로그 |
| 체크했는데 잠시 뒤 풀린다 | 커밋 → 재배포에 1~2분 걸린다. 그 사이 새로고침하면 이전 상태가 보일 수 있다 |
| 기능정의서에서 기능이 흐리게 뜬다 | 그 화면에서 지금 보이지 않는다는 뜻이다. 목업에 data-req-reveal 로 여는 방법을 적으면 스스로 열어 짚어 준다 |
| 퍼블 대조에 "확인 필요" 가 뜬다 | 퍼블에 그 data-req 가 없다는 뜻이다. 요소가 빠졌는지, 태깅만 빠졌는지는 화면을 나란히 놓고 사람이 본다 |
| 셸에서 한글 폴더명이 안 잡힌다 | 파일명이 macOS 조합형으로 커밋돼 있다. 직접 타이핑하지 말고 자동완성 경로나 python 으로 처리한다 |
| Cloudflare 계정이 필요한가 | 아니다. 쓰는 사람은 GitHub 접근만 있으면 된다. Cloudflare 는 최초 설정한 한 사람만 만진다 |
지켜야 할 다섯 줄
- 요구사항 ID는 재사용하지 않는다. 없어진 요구사항은 지우지 말고
- 상태: 제외로 남긴다. 문의 번호도 같다(- 상태: 보류). - 목업의
data-req는 지우지 않는다. 그 속성 하나가 명세·흐름도·점검· 기능정의서·퍼블 대조를 잇는 유일한 연결점이다. 퍼블리셔에게도 미리 말해 둔다. - 목업은 로우파이(회색조·무장식)로 그린다. 색을 다듬으면 디자인이 확정된 것으로 읽히고 구조 논의가 밀린다. 새 화면은 템플릿을 복사해 지우는 쪽으로 만든다.
- 버전은 작업을 다 끝낸 뒤 한 번만 올린다. PR 올리기 직전이 그 시점이다.
- 생성물을 손으로 고치지 않는다. 고칠 것은 언제나
spec.md/mockups//qa.md쪽이다.
즉 읽기는 링크, 쓰기는 레포다. 그 두 줄만 지키면 나머지는 자동으로 따라온다.