docs(commit-policy): 커밋 정책 스킬과 검증 절차를 정비한다
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -279,6 +279,5 @@ xcuserdata
|
||||
|
||||
.kiro/
|
||||
.junie/
|
||||
docs/
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/macos,xcode,appcode,swift,swiftpackagemanager,swiftpm,fastlane,cocoapods
|
||||
|
||||
21
.opencode/commands/commit.md
Normal file
21
.opencode/commands/commit.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
description: commit-policy 스킬을 로드해 커밋 메시지 생성과 전후 검증을 수행한다
|
||||
agent: build
|
||||
subtask: true
|
||||
---
|
||||
|
||||
작업 목표:
|
||||
현재 변경사항을 안전하게 커밋한다.
|
||||
|
||||
필수 시작 단계:
|
||||
1. `skill` 도구로 `commit-policy` 스킬을 먼저 로드한다.
|
||||
- `skill({ name: "commit-policy" })`
|
||||
|
||||
실행 단계:
|
||||
1. 로드한 `commit-policy` 스킬의 Hard Requirements와 Execution Flow를 그대로 수행한다.
|
||||
2. `AGENTS.md`의 최소 정책(형식/한글 description/검증 스크립트)을 항상 만족한다.
|
||||
3. `$ARGUMENTS`가 있으면 scope 또는 description 의도에 반영하되, 스킬 규칙과 형식을 깨지 않는다.
|
||||
4. 마지막에 실행 명령과 pre-check/post-check PASS/FAIL 핵심 결과를 간단히 보고한다.
|
||||
|
||||
추가 사용자 의도:
|
||||
$ARGUMENTS
|
||||
46
.opencode/skills/commit-policy/SKILL.md
Normal file
46
.opencode/skills/commit-policy/SKILL.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: commit-policy
|
||||
description: Apply this skill for any git commit task in this repository. It enforces commit message format and validation flow defined in AGENTS.md and work/scripts/check-commit-message-rules.sh, including pre-commit and post-commit verification.
|
||||
---
|
||||
|
||||
# Commit Policy Skill
|
||||
|
||||
Use this workflow whenever the task includes creating a commit.
|
||||
|
||||
## Required References
|
||||
|
||||
- `@AGENTS.md`
|
||||
- `@work/scripts/check-commit-message-rules.sh`
|
||||
|
||||
## Hard Requirements
|
||||
|
||||
1. Use commit subject format: `<type>(scope): <description>`.
|
||||
2. `type` must be lowercase (for example `feat`, `fix`, `chore`, `docs`, `refactor`, `test`).
|
||||
3. `description` must include Korean text and stay concise in imperative present tone.
|
||||
4. Optional footer must use `Refs: #123` or `Refs: #123, #456` format.
|
||||
5. Never commit secret files (`.env`, key/token/secret credential files).
|
||||
6. Never bypass hooks with `--no-verify`.
|
||||
|
||||
## Execution Flow
|
||||
|
||||
1. Inspect context with:
|
||||
- `git status`
|
||||
- `git diff --cached`
|
||||
- `git diff`
|
||||
- `git log -5 --oneline`
|
||||
2. Stage commit target files only. Exclude suspicious secret-bearing files.
|
||||
3. Draft commit message from the change intent (focus on why, not only what).
|
||||
4. Run pre-commit validation with the full draft message:
|
||||
- `./work/scripts/check-commit-message-rules.sh --message "<full message>"`
|
||||
5. If validation fails, revise message and re-run until PASS.
|
||||
6. Commit using the validated message.
|
||||
7. Run post-commit validation:
|
||||
- `./work/scripts/check-commit-message-rules.sh`
|
||||
8. Report executed commands and PASS/FAIL summary.
|
||||
|
||||
## Output Checklist
|
||||
|
||||
- Final commit subject.
|
||||
- Whether pre-check passed.
|
||||
- Whether post-check passed.
|
||||
- Any excluded files and reason.
|
||||
174
AGENTS.md
174
AGENTS.md
@@ -1,18 +1,160 @@
|
||||
질문에 대한 답변과 설명은 한국어로 한다.
|
||||
# AGENTS.md
|
||||
`SodaLive` 저장소에서 작업하는 에이전트 실행 가이드다.
|
||||
|
||||
## Quality Assurance Guidelines
|
||||
## 커뮤니케이션 규칙
|
||||
- **"질문에 대한 답변과 설명은 한국어로 한다."**
|
||||
- 사용자에게 전달하는 설명, 진행 상황, 결과 보고는 한국어로 작성한다.
|
||||
- 코드 식별자, 파일 경로, 명령어는 원문(영문) 그대로 유지한다.
|
||||
|
||||
### Commit Standards
|
||||
1. Write in Korean.
|
||||
2. Use the present tense in the subject line (e.g., "Add feature" not "Added feature").
|
||||
3. Keep the subject line to 50 characters or less.
|
||||
4. Add a blank line between the subject and body.
|
||||
5. Keep the body to 72 characters or less per line.
|
||||
6. Within a paragraph, only break lines when the text exceeds 72 characters.
|
||||
7. Describe changes to public API features and do not include implementation details such as package-private code.
|
||||
8. Do not mention test code in commit messages.
|
||||
9. Do not use any prefix (such as "fix:", "update:", "docs:", "feat:", etc.) in the subject line.
|
||||
10. Do not start the subject line with a lowercase letter unless the first word is a function name or another identifier that is conventionally lowercase and there is a clear, justifiable reason for the exception. Otherwise, always start with an uppercase letter.
|
||||
11. Do not include tool advertisements, branding, or promotional content in commit messages.
|
||||
12. Use separate git commands to stage files before committing.
|
||||
13. Always validate commits using `work/scripts/check-commit-message-rules.sh` and fix until validation passes.
|
||||
## 저장소 범위
|
||||
- 앱 소스: `SodaLive/Sources/**`
|
||||
- 프로젝트/스킴: `SodaLive.xcodeproj`, `SodaLive.xcworkspace`
|
||||
- 의존성 설정: `Podfile`, `Podfile.lock`
|
||||
- 운영 스크립트: `work/scripts/**`
|
||||
- 생성/외부 결과물: `Pods/**`, `generated/**`, `build/**`
|
||||
- 작업 계획 문서: `docs/**`
|
||||
|
||||
### 수정 우선순위
|
||||
- 기능 변경은 `SodaLive/Sources/**`에서 해결한다.
|
||||
- 프로젝트 설정 변경은 필요한 경우에만 수행한다.
|
||||
- `Pods/**`, `generated/**`는 직접 수정하지 않는다.
|
||||
- `build/**`는 빌드 산출물로 간주하며 수정 대상이 아니다.
|
||||
|
||||
## 빌드/테스트/검증 명령
|
||||
아래 명령은 현재 저장소에서 확인된 공식 진입점이다.
|
||||
|
||||
### 1) 의존성 설치
|
||||
- `pod install`
|
||||
- 근거: `Podfile`에 CocoaPods 타깃(`SodaLive`, `SodaLive-dev`) 정의.
|
||||
|
||||
### 2) 스킴/타깃 확인
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -list`
|
||||
- 근거: 공유 스킴 `SodaLive`, `SodaLive-dev` 존재.
|
||||
|
||||
### 3) 빌드
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`
|
||||
|
||||
### 4) 테스트(전체)
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test`
|
||||
|
||||
### 5) 단일 테스트 실행
|
||||
- 일반 형식(테스트 타깃이 있는 경우):
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -only-testing:"SodaLiveTests/TestClass/testMethod" test`
|
||||
- **현재 주의사항**:
|
||||
- `SodaLive.xcodeproj/project.pbxproj` 기준으로 앱 타깃 중심 구성이고 테스트 번들 타깃이 확인되지 않는다.
|
||||
- 따라서 현재 상태에서는 단일 테스트 지정이 실질적으로 동작하지 않을 수 있다.
|
||||
|
||||
### 6) 린트/포맷
|
||||
- 저장소에 공식 `swiftlint`/`swiftformat` 실행 스크립트는 확인되지 않았다.
|
||||
- `generated/*.generated.swift`에 `swiftlint:disable all` 주석은 존재하나, 이는 생성 코드 보호 목적이다.
|
||||
- 린트 도구를 도입/추가하면 본 문서 명령 섹션을 즉시 갱신한다.
|
||||
|
||||
## 코드 스타일 가이드
|
||||
|
||||
### 아키텍처/레이어
|
||||
- 기본 흐름은 `View -> ViewModel -> Repository -> Api(TargetType)`를 따른다.
|
||||
- API는 `enum ...Api: TargetType`, 저장소는 `final class ...Repository` 형태를 우선 사용한다.
|
||||
- 상태 모델은 `struct`/`enum` 중심으로 두고, 화면 상태는 `ObservableObject`에서 관리한다.
|
||||
|
||||
### 임포트 규칙
|
||||
- 시스템 프레임워크(`Foundation`, `SwiftUI`, `Combine`)를 먼저 배치한다.
|
||||
- 서드파티(`Moya`, `CombineMoya`, SDK들)는 이후 배치한다.
|
||||
- import 그룹 사이에는 한 줄 공백으로 의미 단위를 분리한다.
|
||||
|
||||
### 포맷/구조
|
||||
- 들여쓰기는 4칸 스페이스를 사용한다.
|
||||
- 프로퍼티 선언, 비즈니스 로직, 헬퍼 메서드는 공백 줄로 구획한다.
|
||||
- 클로저 체인은 줄바꿈해 가독성을 유지한다.
|
||||
|
||||
### 타입/상태 관리
|
||||
- ViewModel은 `final class ...: ObservableObject` 패턴을 우선한다.
|
||||
- View가 소유하는 객체는 `@StateObject`, 외부 주입 객체는 `@ObservedObject`를 사용한다.
|
||||
- 네트워크 반환은 `AnyPublisher<Response, MoyaError>` 패턴을 기본으로 따른다.
|
||||
|
||||
### 네이밍 규칙
|
||||
- 타입명은 PascalCase (`HomeViewModel`, `UserRepository`, `UserApi`).
|
||||
- 변수/함수는 camelCase (`errorMessage`, `getMemberInfo`).
|
||||
- 역할을 이름에 반영한다 (`*View`, `*ViewModel`, `*Repository`, `*Api`, `*Request`, `*Response`).
|
||||
|
||||
### 비동기/Combine 규칙
|
||||
- 비동기 처리는 Combine의 `sink`, `receiveValue`, `.store(in: &subscription)` 패턴을 따른다.
|
||||
- `sink` 완료 블록에서 `.failure`를 반드시 처리한다.
|
||||
- 클로저 캡처는 상황에 맞게 `[weak self]` 또는 `[unowned self]`를 선택한다.
|
||||
|
||||
### 에러 처리 규칙
|
||||
- 사용자 노출 오류는 `errorMessage`와 팝업 플래그(`isShowPopup`)로 일관되게 처리한다.
|
||||
- JSON 파싱은 `do/catch + JSONDecoder` 패턴을 따른다.
|
||||
- **신규 코드에서 빈 `catch`는 금지**하고, 최소한 로깅 또는 명시적 무시 사유를 남긴다.
|
||||
|
||||
### 로깅 규칙
|
||||
- 디버그 로그는 `DEBUG_LOG`, 오류 로그는 `ERROR_LOG`를 사용한다.
|
||||
- `print`는 임시 디버깅 목적 외 신규 코드에서 지양한다.
|
||||
|
||||
### 네트워크/헤더 규칙
|
||||
- 공통 Moya 플러그인(`AuthPlugin`, `AcceptLanguagePlugin`) 흐름을 유지한다.
|
||||
- 언어 헤더는 `LanguageHeaderProvider.current`를 기준으로 사용한다.
|
||||
|
||||
### 문자열/다국어
|
||||
- 신규 사용자 노출 문자열은 가능하면 `I18n` 경로를 우선 사용한다.
|
||||
- 다국어 기능 수정 시 `Settings/Language` 모듈과 `Accept-Language` 헤더 흐름을 함께 점검한다.
|
||||
|
||||
### 주석/문서화
|
||||
- 자명한 코드에는 주석을 남기지 않는다.
|
||||
- 복잡한 분기, 외부 제약, 부작용이 있는 로직에만 주석을 추가한다.
|
||||
|
||||
## Cursor/Copilot 규칙 반영
|
||||
- 아래 파일 존재 여부를 확인해 AGENTS와 함께 유지한다.
|
||||
- `.cursor/rules/**`
|
||||
- `.cursorrules`
|
||||
- `.github/copilot-instructions.md`
|
||||
- 현재 저장소에서는 위 파일들이 확인되지 않았다.
|
||||
- 추후 파일이 추가되면 AGENTS.md에 요약 규칙을 동기화한다.
|
||||
- 충돌 우선순위 기본값:
|
||||
- 범위가 더 구체적인 규칙이 우선한다(경로 특화 > 저장소 전역).
|
||||
- Cursor: `.cursor/rules/**` > `.cursorrules` > `AGENTS.md`
|
||||
- Copilot: `.github/instructions/**`(존재 시) > `.github/copilot-instructions.md` > `AGENTS.md`
|
||||
|
||||
## 커밋 메시지 규칙 (표준 Conventional Commits)
|
||||
- 커밋 상세 가이드/절차는 `.opencode/skills/commit-policy/SKILL.md`를 단일 기준으로 사용한다.
|
||||
- 커밋 작업 시작 시 `skill` 도구로 `commit-policy`를 먼저 로드한다.
|
||||
- 기본 형식은 `<type>(scope): <description>`를 사용한다.
|
||||
- `type`은 소문자(`feat`, `fix`, `chore`, `docs`, `refactor`, `test`)를 사용한다.
|
||||
- 제목(description)은 한글로 작성하고, 명령형/간결한 현재형으로 작성한다.
|
||||
- 이슈 참조 footer는 `Refs: #123` 또는 `Refs: #123, #456` 형식을 사용한다.
|
||||
|
||||
### 커밋 메시지 검증 절차
|
||||
- `git commit` 직후 `work/scripts/check-commit-message-rules.sh`를 실행해 규칙 준수 여부를 확인한다.
|
||||
- 스크립트 결과가 `[FAIL]`이면 커밋 메시지를 수정한 뒤 다시 검증한다.
|
||||
|
||||
## 작업 절차 체크리스트
|
||||
- 변경 전: 유사 기능 코드를 먼저 찾아 네이밍/예외/응답 패턴을 맞춘다.
|
||||
- 변경 중: 공개 API 스키마를 임의 변경하지 말고 작은 단위로 안전하게 수정한다.
|
||||
- 변경 후: 영향 범위 파일에 대해 빌드/테스트/로그/다국어 키를 점검한다.
|
||||
- 커밋 직후: `commit-policy` 스킬을 로드하고 메시지 검증 스크립트를 실행한다.
|
||||
|
||||
## 작업 계획 문서 규칙 (docs)
|
||||
- 모든 작업 시작 전에 `docs` 폴더 아래 계획 문서를 먼저 생성하고, 해당 문서를 기준으로 구현한다.
|
||||
- 계획 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다.
|
||||
- 날짜는 `YYYYMMDD` 8자리 숫자를 사용한다.
|
||||
- 구현 항목은 기능/작업 단위 체크박스(`- [ ]`)로 작성하고 완료 즉시 `- [x]`로 갱신한다.
|
||||
- 작업 도중 범위가 변경되면 계획 문서 체크리스트를 먼저 업데이트한 뒤 구현한다.
|
||||
- 결과 보고 시 문서 하단에 검증 기록(무엇/왜/어떻게, 실행 명령, 결과)을 한국어로 남긴다.
|
||||
- 후속 수정이 발생해도 기존 검증 기록은 삭제/덮어쓰기 없이 누적한다.
|
||||
|
||||
## 문서 유지보수 규칙
|
||||
- 불확실한 규칙은 추측으로 채우지 말고 근거 파일 경로를 먼저 확인한다.
|
||||
- 에이전트 안내 문구는 한국어 중심으로 유지한다.
|
||||
- 명령/경로/타깃명이 바뀌면 본 문서를 즉시 업데이트한다.
|
||||
|
||||
## 에이전트 동작 원칙
|
||||
- 추측하지 말고 근거 파일을 읽고 결정한다.
|
||||
- 기존 관례를 깨는 변경은 이유가 명확할 때만 수행한다.
|
||||
- 불필요한 리팩터링 확장은 피하고 요청 범위를 우선 충족한다.
|
||||
- 결과 보고 시 무엇을, 왜, 어떻게 검증했는지 한국어로 간단히 남긴다.
|
||||
|
||||
## 설정/보안 유의사항
|
||||
- 토큰/키/개인정보를 코드/로그/문서에 하드코딩하지 않는다.
|
||||
- 인증 관련 헤더/토큰 처리 로직(`AuthPlugin`, `UserDefaultsKey.token`) 수정 시 회귀 위험을 함께 점검한다.
|
||||
- 외부 SDK 키 변경 시 빌드 설정과 런타임 초기화 지점을 함께 검토한다.
|
||||
|
||||
53
docs/20260225_AGENTS가이드보강.md
Normal file
53
docs/20260225_AGENTS가이드보강.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 20260225 AGENTS 가이드 보강
|
||||
|
||||
## 작업 목표
|
||||
- 저장소 실행/검증 명령을 근거 기반으로 정리한다.
|
||||
- 코드 스타일 가이드를 실제 코드 관례 기반으로 정리한다.
|
||||
- Cursor/Copilot 규칙 파일 존재 시 AGENTS.md에 반영한다.
|
||||
|
||||
## 체크리스트
|
||||
- [x] 저장소 빌드/린트/테스트 명령 근거 수집
|
||||
- [x] 단일 테스트 실행 명령(가능한 범위) 정리
|
||||
- [x] 코드 스타일 관례(임포트/포맷/타입/네이밍/에러처리) 추출
|
||||
- [x] Cursor/Copilot 규칙 파일 반영
|
||||
- [x] `AGENTS.md`를 약 150줄 내외로 보강
|
||||
- [x] 검증 로그 추가
|
||||
|
||||
## 검증 기록
|
||||
- 2026-02-25: 작업 시작. 근거 파일 탐색 진행 중.
|
||||
- 2026-02-25:
|
||||
- 무엇: 빌드/테스트/의존성 명령 근거를 확인했다.
|
||||
- 왜: AGENTS.md에 실행 가능한 공식 명령만 기재하기 위해서다.
|
||||
- 어떻게:
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -list`
|
||||
- `read Podfile`
|
||||
- `read SodaLive.xcodeproj/xcshareddata/xcschemes/SodaLive.xcscheme`
|
||||
- `read SodaLive.xcodeproj/xcshareddata/xcschemes/SodaLive-dev.xcscheme`
|
||||
- `grep project.pbxproj "PBXNativeTarget|Tests|SWIFT_VERSION|IPHONEOS_DEPLOYMENT_TARGET"`
|
||||
- 결과: 스킴 `SodaLive`, `SodaLive-dev`를 확인했고, 테스트 번들 타깃 부재로 단일 테스트 실행은 제한될 수 있음을 문서화했다.
|
||||
- 2026-02-25:
|
||||
- 무엇: 코드 스타일 규칙(임포트/아키텍처/타입/네이밍/에러처리/로깅/비동기)을 추출했다.
|
||||
- 왜: 에이전트가 기존 관례를 깨지 않고 수정하도록 하기 위해서다.
|
||||
- 어떻게:
|
||||
- `read SodaLive/Sources/User/UserApi.swift`
|
||||
- `read SodaLive/Sources/User/UserRepository.swift`
|
||||
- `read SodaLive/Sources/User/Login/LoginViewModel.swift`
|
||||
- `read SodaLive/Sources/Extensions/MoyaProviderExtension.swift`
|
||||
- `read SodaLive/Sources/Utils/Log.swift`
|
||||
- `ast_grep_search "do { $$$ } catch { $$$ }"`
|
||||
- 결과: `View -> ViewModel -> Repository -> Api` 레이어와 `DEBUG_LOG/ERROR_LOG`, `sink + .store(in:)` 패턴을 AGENTS.md에 반영했다.
|
||||
- 2026-02-25:
|
||||
- 무엇: Cursor/Copilot 규칙 파일 존재 여부를 점검했다.
|
||||
- 왜: 요청사항(룰 파일 반영)을 누락 없이 처리하기 위해서다.
|
||||
- 어떻게:
|
||||
- `glob .cursor/rules/**/*`
|
||||
- `glob .cursorrules`
|
||||
- `glob .github/copilot-instructions.md`
|
||||
- 결과: 현재 저장소에는 해당 파일이 없어, AGENTS.md에 "미존재/추후 동기화" 정책을 기재했다.
|
||||
- 2026-02-25:
|
||||
- 무엇: AGENTS.md 최종 라인 수와 섹션 충족 여부를 확인했다.
|
||||
- 왜: 요청 조건(약 150줄, 빈 섹션 채우기) 충족 검증을 위해서다.
|
||||
- 어떻게:
|
||||
- `read AGENTS.md`
|
||||
- `wc -l AGENTS.md`
|
||||
- 결과: 총 160줄로 확인되었고, 기존 빈 섹션(저장소 범위/코드 스타일)을 포함해 전 섹션을 채웠다.
|
||||
21
docs/20260225_커밋메시지사후검증전환.md
Normal file
21
docs/20260225_커밋메시지사후검증전환.md
Normal file
@@ -0,0 +1,21 @@
|
||||
- [x] `check-commit-message-rules.sh`의 인자 지원 방식 확인
|
||||
- [x] `AGENTS.md` 커밋 메시지 검증 절차를 커밋 후 검증 전용으로 수정
|
||||
- [x] 변경 내용 검증 및 결과 기록
|
||||
|
||||
## 검증 기록
|
||||
- 2026-02-25: 작업 시작
|
||||
- 무엇/왜/어떻게: 커밋 전 `--message` 검증 가능 여부를 스크립트 소스 기준으로 확인.
|
||||
- 실행 명령: `read work/scripts/check-commit-message-rules.sh`
|
||||
- 결과: 사용법이 `[commit-hash]`만 정의되어 있어 커밋 전 메시지 직접 검증은 미지원.
|
||||
- 실행 명령: `./work/scripts/check-commit-message-rules.sh --message`
|
||||
- 결과: `git log`에서 `fatal: 알 수 없는 인자: --message`가 발생해도 스크립트는 성공으로 끝나므로 사전 검증 용도로 사용할 수 없음.
|
||||
|
||||
- 2026-02-25: AGENTS 문구 정정
|
||||
- 무엇/왜/어떻게: 스크립트 실제 동작과 문서 지침을 일치시키기 위해 커밋 검증 시점을 사후 전용으로 수정.
|
||||
- 실행 명령: `apply_patch AGENTS.md`
|
||||
- 결과: `git commit` 직전/직후 안내를 `git commit` 직후 안내로 변경하고, 체크리스트의 `커밋 전/후`를 `커밋 직후`로 정정.
|
||||
|
||||
- 2026-02-25: 변경 검증
|
||||
- 무엇/왜/어떻게: 문구가 완전히 전환되었는지와 문서 진단 오류 유무를 확인.
|
||||
- 실행 명령: `grep "직전/직후|커밋 전/후|--message" AGENTS.md`, `lsp_diagnostics AGENTS.md`, `lsp_diagnostics docs/20260225_커밋메시지사후검증전환.md`
|
||||
- 결과: AGENTS.md에서 구문 미검출(No matches), 두 파일 모두 진단 오류 없음(No diagnostics found).
|
||||
Reference in New Issue
Block a user