diff --git a/AGENTS.md b/AGENTS.md index 904e63b5..4b71ab32 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,172 +1,135 @@ # AGENTS.md `SodaLive` 저장소에서 작업하는 에이전트 실행 가이드다. +## 실행 우선순위 및 통합 정책 +- 충돌 시 아래 우선순위가 높은 지시를 항상 우선 적용한다. +- 우선순위는 다음과 같다. + 1. 사용자 직접 지시 + 2. `AGENTS.md` + 3. 프로젝트별 제약 조건 + 4. oh-my-openagent 플러그인의 agents / workflows / hooks + 5. superpowers skills + 6. 기본 모델 동작 +- plugin / skill / workflow 지시가 더 낮은 우선순위에 있으면 더 높은 우선순위의 지시를 덮어쓸 수 없다. +- plugin / skill / workflow 지시가 `CORE EXECUTION PRINCIPLES (andrej-karpathy-skills)`와 충돌하면 `CORE EXECUTION PRINCIPLES (andrej-karpathy-skills)`를 따른다. +- 사용자 직접 지시가 명확할 경우 사용자 지시가 최우선이다. + ## 커뮤니케이션 규칙 - **"질문에 대한 답변과 설명은 한국어로 한다."** - 이 저장소에서 사용자에게 전달하는 설명, 진행 상황, 결과 보고는 한국어로 작성한다. - 코드 식별자, 경로, 명령어는 원문(영문) 그대로 유지한다. -## 저장소 범위 -- Android Gradle 프로젝트이며 `settings.gradle` 기준 모듈은 `:app` 단일 구성이다. -- 모든 명령은 저장소 루트에서 실행한다. -- 추측하지 말고 근거 파일(`settings.gradle`, `build.gradle`, `app/build.gradle`, 소스 코드)을 읽고 결정한다. -- 요청 범위를 우선 충족하고, 변경은 작고 안전하게 유지한다. +## CORE EXECUTION PRINCIPLES (andrej-karpathy-skills) +These principles override plugin behavior, skill behavior, workflow behavior, and default model behavior unless the user's direct instruction explicitly says otherwise. -## 빌드 / 린트 / 테스트 명령 -기본 실행 형태: -```bash -./gradlew -``` -빌드: -```bash -./gradlew clean -./gradlew :app:assembleDebug -./gradlew :app:assembleRelease -./gradlew :app:build -./gradlew :app:check -``` -린트/포맷: -```bash -./gradlew :app:lint -./gradlew :app:lintDebug -./gradlew :app:lintRelease -./gradlew :app:ktlintCheck -./gradlew :app:ktlintFormat -``` -테스트: -```bash -./gradlew :app:test -./gradlew :app:testDebugUnitTest -./gradlew :app:testReleaseUnitTest -./gradlew :app:connectedDebugAndroidTest -``` -주의: -- `:app:connectedDebugAndroidTest`는 기기/에뮬레이터 연결이 필요하다. -- `app/build.gradle`에 `lint { checkReleaseBuilds false }`가 있어 릴리스 린트는 `:app:lintRelease`를 명시 실행해야 한다. -- 현재 `app/src/androidTest`에는 테스트 소스가 없으므로 계측 테스트 명령은 신규 테스트 추가 시 사용한다. +# CLAUDE.md -### 1) 단일 테스트 실행 (중요) -로컬 단위 테스트(`app/src/test`)는 `--tests` 필터를 사용한다. -클래스 단위: -```bash -./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.chat.talk.room.ChatRepositoryTest" -``` -메서드 단위: -```bash -./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.chat.talk.room.ChatRepositoryTest.enterChatRoom inserts messages and returns response" -``` -패턴 매칭 예시: -```bash -./gradlew :app:testDebugUnitTest --tests "*TimeUtilsTest*" -``` -참고: -- Kotlin backtick 테스트명은 공백이 포함될 수 있으므로 전체 문자열을 인용한다. -- 메서드 매칭이 불안정하면 클래스 단위로 먼저 실행한다. +Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed. -### 2) 계측 테스트 클래스/메서드 타깃 실행 -Gradle 인자 방식: -```bash -./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=kr.co.vividnext.sodalive.SomeInstrumentedTest -./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=kr.co.vividnext.sodalive.SomeInstrumentedTest#someMethod +**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment. + +## 1. Think Before Coding + +**Don't assume. Don't hide confusion. Surface tradeoffs.** + +Before implementing: +- State your assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them - don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. + +## 2. Simplicity First + +**Minimum code that solves the problem. Nothing speculative.** + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios. +- If you write 200 lines and it could be 50, rewrite it. + +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +## 3. Surgical Changes + +**Touch only what you must. Clean up only your own mess.** + +When editing existing code: +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it - don't delete it. + +When your changes create orphans: +- Remove imports/variables/functions that YOUR changes made unused. +- Don't remove pre-existing dead code unless asked. + +The test: Every changed line should trace directly to the user's request. + +## 4. Goal-Driven Execution + +**Define success criteria. Loop until verified.** + +Transform tasks into verifiable goals: +- "Add validation" → "Write tests for invalid inputs, then make them pass" +- "Fix the bug" → "Write a test that reproduces it, then make it pass" +- "Refactor X" → "Ensure tests pass before and after" + +For multi-step tasks, state a brief plan: ``` -ADB 대안: -```bash -adb shell am instrument -w -e class kr.co.vividnext.sodalive.SomeInstrumentedTest#someMethod / +1. [Step] → verify: [check] +2. [Step] → verify: [check] +3. [Step] → verify: [check] ``` -## 코드 스타일 가이드 -### 1) 포맷/기본 규칙 -- `.editorconfig` 기준을 준수한다. -- 인덴트: 공백 4칸, 줄바꿈: LF, 최대 라인 길이: 130. -- 파일 끝 개행 유지, trailing whitespace 제거. -- Kotlin/KTS에서 `import-ordering` ktlint 규칙은 비활성화되어 있으므로 기존 파일 정렬 스타일을 우선 따른다. +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification. -### 2) import 규칙 -- 신규 코드에서는 와일드카드 import(`*`)를 기본적으로 지양한다. -- 사용하지 않는 import를 남기지 않는다. -- import alias(`as`)는 필요한 경우(이름 충돌 회피) 최소 범위로만 사용한다. -- 기존 파일에 와일드카드/alias가 있으면 대규모 정렬 리팩터링 없이 주변 스타일에 맞춘다. +--- -### 3) 네이밍/레이어 -- UI: `*Activity`, `*Fragment`, dialog/sheet suffix -- 상태/도메인: `*ViewModel` (주로 `BaseViewModel` 상속) -- 데이터 계층: `*Repository`, Retrofit `*Api` -- DTO: `data class` + `*Request`, `*Response` suffix -- 레이어 흐름: `Api` -> `Repository` -> `ViewModel` -> `Activity`/`Fragment` -- DI는 `app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt`의 Koin 구성을 따른다. +**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes. -### 4) 타입/계약/에러 처리 -- nullability와 제네릭 타입을 의미가 바뀌지 않게 유지한다. -- 공개 API/스키마/리소스 계약은 요청 없이 변경하지 않는다. -- 응답 처리 시 기존 `ApiResponse`와 Rx 타입(`Single`, `Flowable`)을 우선 재사용한다. -- 빈 `catch` 블록을 새로 추가하지 않는다. -- 예외를 조용히 삼키지 않고 로그/주석/대체 흐름 중 하나를 남긴다. +## 실행 원칙 및 계층 사용 정책 +- 불확실하거나 모호한 경우 추측하지 말고 확인하거나, 가능한 최소 범위의 안전한 조치를 취한다. -### 5) 테스트 관례 -- 단위 테스트는 `app/src/test`에 위치하며 클래스명은 `*Test`를 사용한다. -- 기본 스택은 JUnit4 + MockK/Mockito다. -- 테스트 추가 시 단일 실행 명령 예시도 본 문서에 갱신한다. +### 기본 모드: 보수적 실행 +- 최소 변경 +- 단순한 구현 +- 검증 가능한 결과 -### 6) 주석 -- 의미 단위별로 주석을 작성한다. -- 주석은 한 문장으로 간결하게 작성한다. -- 주석은 코드의 의도와 구조를 설명한다. -- 주석은 코드 변경 시 업데이트를 잊지 않는다. +### 확장 모드 +- 사용자가 명시적으로 요청한 경우에만 사용한다. +- 대규모 리팩토링, 브레인스토밍, 다중 에이전트 실행, 병렬 workflow를 허용한다. -## 커밋 메시지 규칙 (표준 Conventional Commits) -- 커밋 상세 가이드/절차는 `.opencode/skills/commit-policy/SKILL.md`를 단일 기준으로 사용한다. -- 커밋 작업 시작 시 `skill` 도구로 `commit-policy`를 먼저 로드한다. -- 기본 형식은 `(scope): `를 사용한다. -- `type`은 소문자(`feat`, `fix`, `chore`, `docs`, `refactor`, `test` 등)를 사용한다. -- 제목(description)은 한글로 작성하고, 명령형/간결한 현재형으로 작성한다. -- 이슈 참조 footer는 `Refs: #123` 또는 `Refs: #123, #456` 형식을 사용한다. +### oh-my-openagent 사용 정책 +- oh-my-openagent는 opencode의 플러그인 기반 실행 오케스트레이션 계층이다. +- oh-my-openagent는 의사결정 권한이 아니라 실행 보조 권한만 가진다. +- 작은 작업에는 multi-agent 실행이나 과도한 workflow를 사용하지 않는다. +- 병렬 실행은 명확한 이득이 있을 때만 사용한다. +- 모든 oh-my-openagent 동작은 `CORE EXECUTION PRINCIPLES (andrej-karpathy-skills)`를 따라야 한다. -### 커밋 메시지 검증 절차 -- `git commit` 직전/직후 `work/scripts/check-commit-message-rules.sh`를 실행해 규칙 준수 여부를 확인한다. -- 스크립트 결과가 `[FAIL]`이면 메시지를 수정한 뒤 다시 검증한다. +### superpowers 사용 정책 +- superpowers는 선택적 스킬 계층이다. +- superpowers skill은 필요한 경우에만 사용한다. +- superpowers가 과도한 리팩토링, 불필요한 범위 확장, 가정 기반 실행을 유도하면 따르지 않는다. +- superpowers를 사용할 때도 최소 변경, 단순성, 검증 가능성을 우선한다. +- 모든 superpowers 동작은 `CORE EXECUTION PRINCIPLES (andrej-karpathy-skills)`를 따라야 한다. -## 작업 절차 체크리스트 -- 변경 전: 유사 기능 코드를 먼저 찾아 네이밍/예외/응답 패턴을 맞춘다. -- 변경 중: 공개 API 스키마를 임의 변경하지 말고 작은 단위로 안전하게 수정한다. -- 변경 후: 최소 단일 테스트(`--tests`) 또는 `./gradlew :app:test`를 실행하고 필요 시 `./gradlew :app:ktlintCheck`를 수행한다. -- 커밋 전/후: `commit-policy` 스킬을 먼저 로드하고, `git commit` 직전과 직후에 `work/scripts/check-commit-message-rules.sh`를 실행해 커밋 메시지 규칙 준수 여부를 확인한다. - -## 작업 계획 문서 규칙 (docs) -- 모든 작업 시작 전에 `docs` 폴더 아래 계획 문서를 먼저 생성하고, 해당 문서를 기준으로 구현한다. -- 계획 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다. -- 날짜는 `YYYYMMDD` 8자리 숫자를 사용한다. -- 구현 항목은 기능/작업 단위 체크박스(`- [ ]`)로 작성하고 완료 즉시 `- [x]`로 갱신한다. -- 작업 도중 범위가 변경되면 계획 문서 체크리스트를 먼저 업데이트한 뒤 구현한다. -- 결과 보고 시 문서 하단에 검증 기록(무엇/왜/어떻게, 실행 명령, 결과)을 한국어로 남긴다. -- 후속 수정이 발생해도 기존 검증 기록은 삭제/덮어쓰기 없이 누적한다. - -## Cursor/Copilot 규칙 반영 현황 -- 확인 경로: `.cursor/rules/**`, `.cursorrules`, `.github/copilot-instructions.md` -- 현재 저장소에는 위 파일이 존재하지 않는다. -- 추후 규칙 파일이 추가되면 본 문서에 즉시 반영한다. - -## 문서 유지보수 규칙 -- `build.gradle`/`app/build.gradle`/`settings.gradle` 변경 시 실행 명령 섹션을 함께 갱신한다. -- 테스트 클래스 추가/이동 시 단일 테스트 실행 예시를 최신 상태로 유지한다. -- `.editorconfig` 변경 시 포맷 규칙 섹션을 동기화한다. -- 문서 변경 후 최소 한 번 `./gradlew tasks --all`로 명령 유효성을 확인한다. -- 불확실한 규칙은 추측으로 채우지 말고 근거 파일 경로를 먼저 확인한다. -- 에이전트 안내 문구는 한국어 중심으로 유지한다. - -## 에이전트 동작 원칙 +### 에이전트 동작 원칙 - 추측하지 말고 근거 파일을 읽고 결정한다. - 기존 관례를 깨는 변경은 이유가 명확할 때만 수행한다. - 불필요한 리팩터링 확장은 피하고 요청 범위를 우선 충족한다. -- 결과 보고 시 무엇을, 왜, 어떻게 검증했는지 한국어로 간단히 남긴다. -## 설정/보안 유의사항 -- `local.properties`, 키스토어(`*.jks`, `*.keystore`, `*.p12`, `*.pem`, `*.key`)는 생성/수정 여부와 관계없이 커밋하지 않는다. -- `app/src/debug/google-services.json`, `app/src/release/google-services.json`은 민감 구성으로 취급하고 외부 공유/로그 출력 금지한다. -- `app/build.gradle`의 `buildConfigField` 값(토큰/앱키/시크릿 유사 값)은 신규 하드코딩을 추가하지 않는다. +## 저장소 범위 +- Android Gradle 프로젝트이며 `settings.gradle` 기준 모듈은 `:app` 단일 구성이다. +- 모든 명령은 저장소 루트에서 실행한다. +- 요청 범위를 우선 충족하고, 변경은 작고 안전하게 유지한다. + +## 상세 참조 문서 +- 빌드/린트/테스트/코드 스타일은 `docs/agent-guides/build-test-style.md`를 참고한다. +- 작업 절차/docs/커밋 규칙은 `docs/agent-guides/workflow-docs-commits.md`를 참고한다. +- 저장소 세부 규칙/보안/Git 안전 수칙은 `docs/agent-guides/safety-repo-rules.md`를 참고한다. + +## 핵심 금지사항 +- `local.properties`, 키스토어, Google Services 파일, 비밀값은 커밋하거나 외부에 노출하지 않는다. - `BuildConfig` 값(키/토큰/URL)을 로그, Toast, 크래시 메시지에 직접 노출하지 않는다. -- 네트워크 로깅은 `AppDI.kt` 패턴을 유지한다(디버그만 BODY, 릴리스는 NONE). -- 서명/배포 설정(Crashlytics, Google Services, Proguard, signing)은 요청 없이 변경하지 않는다. -- `AndroidManifest.xml` 권한은 민감 영역이므로 신규 추가/확장은 사유와 영향도를 확인한 뒤 반영한다. -- `applicationId`, `namespace`, OAuth Client ID, 딥링크 호스트는 요청 없이 변경하지 않는다. -- 문서/이슈/PR 본문에 비밀값을 남기지 말고 필요 시 마스킹(`***`) 처리한다. - Git 작업은 비파괴 명령을 기본으로 사용하고, 강제 푸시/히스토리 재작성은 명시 요청이 있을 때만 수행한다. diff --git a/docs/20260429_AGENTS정리.md b/docs/20260429_AGENTS정리.md new file mode 100644 index 00000000..4573fea7 --- /dev/null +++ b/docs/20260429_AGENTS정리.md @@ -0,0 +1,88 @@ +# 20260429 AGENTS 정리 + +## 개요 +- `AGENTS.md`를 정비한 전체 작업 이력을 하나로 합친 문서다. +- 작업 범위는 다음 3단계였다. + - `oh-my-openagent`, `superpowers`, `andrej-karpathy-skills` 통합 + - 우선순위 기준 재배치 및 중복 정리 + - 핵심 규칙 중심 경량화 및 세부 문서 분리 +- 현재 기준의 관련 세부 문서는 아래와 같다. + - `docs/agent-guides/build-test-style.md` + - `docs/agent-guides/workflow-docs-commits.md` + - `docs/agent-guides/safety-repo-rules.md` + +## 작업 체크리스트 +- [x] 기존 `AGENTS.md` 구조와 중복 규칙을 분석한다. +- [x] 공식 `andrej-karpathy-skills` 원문 `CLAUDE.md`를 확인하고 통합한다. +- [x] 우선순위/충돌 해결/실행 모드 정책을 추가한다. +- [x] 우선순위 기준으로 섹션을 재배치하고 중복 표현을 줄인다. +- [x] `AGENTS.md`에는 핵심 규칙만 남기고 세부 규칙은 참조 문서로 분리한다. +- [x] 관련 작업 문서를 하나로 통합하고 중복 문서를 정리한다. + +## 결과 요약 +### 1) 통합 +- `AGENTS.md`에 `CORE EXECUTION PRINCIPLES (andrej-karpathy-skills)`를 공식 원문 그대로 포함했다. +- `oh-my-openagent`, `superpowers`, 프로젝트 지침 사이의 우선순위와 충돌 해결 규칙을 추가했다. + +### 2) 재배치 +- 우선순위가 높은 정책을 상단으로 이동했다. +- `충돌 해결 규칙`은 `실행 우선순위 및 통합 정책`에 통합했다. +- 실행 모드/실행 계층/에이전트 동작 규칙은 하나의 묶음으로 정리했다. + +### 3) 경량화 +- `AGENTS.md`에는 핵심 원칙, 저장소 요약, 참조 문서 링크, 핵심 금지사항만 남겼다. +- 빌드/테스트/스타일, 작업 절차/커밋, 보안/저장소 세부 규칙은 `docs/agent-guides/` 아래 별도 문서로 분리했다. + +## 검증 기록 +- 2026-04-29 + - 무엇/왜/어떻게: 기존 `AGENTS.md`의 구조와 중복 규칙을 먼저 확인한 뒤, 공식 `andrej-karpathy-skills` 원문을 raw URL에서 검증하고, 기존 유용한 규칙은 유지한 채 상단에 우선순위/통합 정책 섹션을 추가했다. + - 실행 명령/도구: + - `read(AGENTS.md)` + - `grep("oh-my-openagent|openagent|superpowers|andrej|karpathy|plugin|workflow|우선순위|priority", include="AGENTS.md")` + - `webfetch("https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md")` + - `task(subagent_type="explore", run_in_background=true)` + - `task(subagent_type="librarian", run_in_background=true)` + - `apply_patch` + - 결과: + - 기존 `AGENTS.md`에는 `oh-my-openagent`, `superpowers`, `andrej-karpathy-skills` 관련 명시 섹션이 없음을 확인했다. + - 공식 raw `CLAUDE.md` 원문을 확인했고, 영문 본문은 변경 없이 `CORE EXECUTION PRINCIPLES (andrej-karpathy-skills)` 섹션에 삽입했다. + - 우선순위 체계, oh-my-openagent 정책, superpowers 정책, 충돌 해결 규칙, 실행 모드를 한국어로 추가했다. + +- 2026-04-29 + - 무엇/왜/어떻게: `AGENTS.md`를 읽고 배경 탐색 결과를 합쳐, 우선순위가 높은 정책을 앞에 배치하고 중복되던 충돌 규칙/실행 계층/에이전트 동작 문장을 상위 섹션으로 흡수하는 방향으로 재배치를 수행했다. + - 실행 명령/도구: + - `read(AGENTS.md)` + - `grep("^## |^### |추측하지 말고|요청 범위를 우선|최소 변경|검증 가능한 결과|commit-policy|한국어|oh-my-openagent|superpowers|CORE EXECUTION PRINCIPLES", include="AGENTS.md")` + - `task(subagent_type="explore", run_in_background=true)` x2 + - `apply_patch` + - `grep("^## |^### ", include="AGENTS.md")` + - 결과: + - `실행 우선순위 및 통합 정책`을 최상단으로 올리고 `충돌 해결 규칙`을 해당 섹션에 통합했다. + - `실행 모드`, `oh-my-openagent 사용 정책`, `superpowers 사용 정책`, `에이전트 동작 원칙`을 `실행 원칙 및 계층 사용 정책` 아래로 묶었다. + - 중복되던 문장을 줄이고 운영성 정보의 배치를 정리했다. + +- 2026-04-29 + - 무엇/왜/어떻게: `AGENTS.md`는 핵심 정책만 남기고, 긴 운영 규칙은 별도 문서로 분리하기 위해 본문과 배경 탐색 결과를 합쳐 인라인 유지 항목과 분리 항목을 나눈 뒤, 3개 참조 문서와 링크 구조로 재구성했다. + - 실행 명령/도구: + - `read(AGENTS.md)` + - `grep("^## |^### ", include="AGENTS.md")` + - `glob("docs/*.md")` + - `task(subagent_type="explore", run_in_background=true)` x2 + - `apply_patch` + - `read(수정된 AGENTS.md 및 분리 문서)` + - 결과: + - `AGENTS.md`에는 우선순위, 커뮤니케이션, `CORE EXECUTION PRINCIPLES`, 실행 계층 정책, 저장소 요약, 참조 문서 링크, 핵심 금지사항만 남겼다. + - 빌드/린트/테스트/스타일은 `docs/agent-guides/build-test-style.md`로 분리했다. + - 작업 절차/docs/커밋 규칙은 `docs/agent-guides/workflow-docs-commits.md`로 분리했다. + - 저장소 세부 규칙/보안/Git 안전 수칙은 `docs/agent-guides/safety-repo-rules.md`로 분리했다. + +- 2026-04-29 + - 무엇/왜/어떻게: `AGENTS.md` 관련 작업 문서가 3개로 쪼개져 있어 관리 비용이 생겨, 같은 날의 연속 작업 이력을 하나의 문서로 합치고 중복 문서를 제거했다. + - 실행 명령/도구: + - `read(docs/20260429_AGENTS통합정리.md)` + - `read(docs/20260429_AGENTS재배치정리.md)` + - `read(docs/20260429_AGENTS경량화정리.md)` + - `apply_patch` + - 결과: + - 세 문서의 개요/체크리스트/검증 기록을 하나의 이력 문서로 통합했다. + - 중복되던 계획 생성 기록은 단일 문서 기준으로 정리했다. diff --git a/docs/agent-guides/build-test-style.md b/docs/agent-guides/build-test-style.md new file mode 100644 index 00000000..03fe97d8 --- /dev/null +++ b/docs/agent-guides/build-test-style.md @@ -0,0 +1,116 @@ +# build-test-style + +`SodaLive` 저장소에서 빌드, 테스트, 린트, 코드 스타일 관련 세부 규칙을 정리한 문서다. + +## 저장소 범위 보충 +- 추측하지 말고 근거 파일(`settings.gradle`, `build.gradle`, `app/build.gradle`, 소스 코드)을 읽고 결정한다. + +## 빌드 / 린트 / 테스트 명령 +기본 실행 형태: +```bash +./gradlew +``` + +빌드: +```bash +./gradlew clean +./gradlew :app:assembleDebug +./gradlew :app:assembleRelease +./gradlew :app:build +./gradlew :app:check +``` + +린트/포맷: +```bash +./gradlew :app:lint +./gradlew :app:lintDebug +./gradlew :app:lintRelease +./gradlew :app:ktlintCheck +./gradlew :app:ktlintFormat +``` + +테스트: +```bash +./gradlew :app:test +./gradlew :app:testDebugUnitTest +./gradlew :app:testReleaseUnitTest +./gradlew :app:connectedDebugAndroidTest +``` + +주의: +- `:app:connectedDebugAndroidTest`는 기기/에뮬레이터 연결이 필요하다. +- `app/build.gradle`에 `lint { checkReleaseBuilds false }`가 있어 릴리스 린트는 `:app:lintRelease`를 명시 실행해야 한다. +- 현재 `app/src/androidTest`에는 테스트 소스가 없으므로 계측 테스트 명령은 신규 테스트 추가 시 사용한다. + +### 1) 단일 테스트 실행 (중요) +로컬 단위 테스트(`app/src/test`)는 `--tests` 필터를 사용한다. + +클래스 단위: +```bash +./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.chat.talk.room.ChatRepositoryTest" +``` + +메서드 단위: +```bash +./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.chat.talk.room.ChatRepositoryTest.enterChatRoom inserts messages and returns response" +``` + +패턴 매칭 예시: +```bash +./gradlew :app:testDebugUnitTest --tests "*TimeUtilsTest*" +``` + +참고: +- Kotlin backtick 테스트명은 공백이 포함될 수 있으므로 전체 문자열을 인용한다. +- 메서드 매칭이 불안정하면 클래스 단위로 먼저 실행한다. + +### 2) 계측 테스트 클래스/메서드 타깃 실행 +Gradle 인자 방식: +```bash +./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=kr.co.vividnext.sodalive.SomeInstrumentedTest +./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=kr.co.vividnext.sodalive.SomeInstrumentedTest#someMethod +``` + +ADB 대안: +```bash +adb shell am instrument -w -e class kr.co.vividnext.sodalive.SomeInstrumentedTest#someMethod / +``` + +## 코드 스타일 가이드 +### 1) 포맷/기본 규칙 +- `.editorconfig` 기준을 준수한다. +- 인덴트: 공백 4칸, 줄바꿈: LF, 최대 라인 길이: 130. +- 파일 끝 개행 유지, trailing whitespace 제거. +- Kotlin/KTS에서 `import-ordering` ktlint 규칙은 비활성화되어 있으므로 기존 파일 정렬 스타일을 우선 따른다. + +### 2) import 규칙 +- 신규 코드에서는 와일드카드 import(`*`)를 기본적으로 지양한다. +- 사용하지 않는 import를 남기지 않는다. +- import alias(`as`)는 필요한 경우(이름 충돌 회피) 최소 범위로만 사용한다. +- 기존 파일에 와일드카드/alias가 있으면 대규모 정렬 리팩터링 없이 주변 스타일에 맞춘다. + +### 3) 네이밍/레이어 +- UI: `*Activity`, `*Fragment`, dialog/sheet suffix +- 상태/도메인: `*ViewModel` (주로 `BaseViewModel` 상속) +- 데이터 계층: `*Repository`, Retrofit `*Api` +- DTO: `data class` + `*Request`, `*Response` suffix +- 레이어 흐름: `Api` -> `Repository` -> `ViewModel` -> `Activity`/`Fragment` +- DI는 `app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt`의 Koin 구성을 따른다. + +### 4) 타입/계약/에러 처리 +- nullability와 제네릭 타입을 의미가 바뀌지 않게 유지한다. +- 공개 API/스키마/리소스 계약은 요청 없이 변경하지 않는다. +- 응답 처리 시 기존 `ApiResponse`와 Rx 타입(`Single`, `Flowable`)을 우선 재사용한다. +- 빈 `catch` 블록을 새로 추가하지 않는다. +- 예외를 조용히 삼키지 않고 로그/주석/대체 흐름 중 하나를 남긴다. + +### 5) 테스트 관례 +- 단위 테스트는 `app/src/test`에 위치하며 클래스명은 `*Test`를 사용한다. +- 기본 스택은 JUnit4 + MockK/Mockito다. +- 테스트 추가 시 단일 실행 명령 예시도 본 문서에 갱신한다. + +### 6) 주석 +- 의미 단위별로 주석을 작성한다. +- 주석은 한 문장으로 간결하게 작성한다. +- 주석은 코드의 의도와 구조를 설명한다. +- 주석은 코드 변경 시 업데이트를 잊지 않는다. diff --git a/docs/agent-guides/safety-repo-rules.md b/docs/agent-guides/safety-repo-rules.md new file mode 100644 index 00000000..d4b16744 --- /dev/null +++ b/docs/agent-guides/safety-repo-rules.md @@ -0,0 +1,19 @@ +# safety-repo-rules + +`SodaLive` 저장소의 저장소 세부 규칙, 보안 유의사항, Git 안전 원칙을 정리한 문서다. + +## 저장소 범위 보충 +- Android Gradle 프로젝트이며 `settings.gradle` 기준 모듈은 `:app` 단일 구성이다. +- 모든 명령은 저장소 루트에서 실행한다. + +## 설정/보안 유의사항 +- `local.properties`, 키스토어(`*.jks`, `*.keystore`, `*.p12`, `*.pem`, `*.key`)는 생성/수정 여부와 관계없이 커밋하지 않는다. +- `app/src/debug/google-services.json`, `app/src/release/google-services.json`은 민감 구성으로 취급하고 외부 공유/로그 출력 금지한다. +- `app/build.gradle`의 `buildConfigField` 값(토큰/앱키/시크릿 유사 값)은 신규 하드코딩을 추가하지 않는다. +- `BuildConfig` 값(키/토큰/URL)을 로그, Toast, 크래시 메시지에 직접 노출하지 않는다. +- 네트워크 로깅은 `AppDI.kt` 패턴을 유지한다(디버그만 BODY, 릴리스는 NONE). +- 서명/배포 설정(Crashlytics, Google Services, Proguard, signing)은 요청 없이 변경하지 않는다. +- `AndroidManifest.xml` 권한은 민감 영역이므로 신규 추가/확장은 사유와 영향도를 확인한 뒤 반영한다. +- `applicationId`, `namespace`, OAuth Client ID, 딥링크 호스트는 요청 없이 변경하지 않는다. +- 문서/이슈/PR 본문에 비밀값을 남기지 말고 필요 시 마스킹(`***`) 처리한다. +- Git 작업은 비파괴 명령을 기본으로 사용하고, 강제 푸시/히스토리 재작성은 명시 요청이 있을 때만 수행한다. diff --git a/docs/agent-guides/workflow-docs-commits.md b/docs/agent-guides/workflow-docs-commits.md new file mode 100644 index 00000000..5ac4dd04 --- /dev/null +++ b/docs/agent-guides/workflow-docs-commits.md @@ -0,0 +1,37 @@ +# workflow-docs-commits + +`SodaLive` 저장소에서 작업 절차, docs 계획 문서 규칙, 커밋 규칙을 정리한 문서다. + +## 커밋 메시지 규칙 (표준 Conventional Commits) +- 커밋 상세 가이드/절차는 `.opencode/skills/commit-policy/SKILL.md`를 단일 기준으로 사용한다. +- 커밋 작업 시작 시 `skill` 도구로 `commit-policy`를 먼저 로드한다. +- 기본 형식은 `(scope): `를 사용한다. +- `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 스키마를 임의 변경하지 말고 작은 단위로 안전하게 수정한다. +- 변경 후: 최소 단일 테스트(`--tests`) 또는 `./gradlew :app:test`를 실행하고 필요 시 `./gradlew :app:ktlintCheck`를 수행한다. + +## 작업 계획 문서 규칙 (docs) +- 모든 작업 시작 전에 `docs` 폴더 아래 계획 문서를 먼저 생성하고, 해당 문서를 기준으로 구현한다. +- 계획 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다. +- 날짜는 `YYYYMMDD` 8자리 숫자를 사용한다. +- 구현 항목은 기능/작업 단위 체크박스(`- [ ]`)로 작성하고 완료 즉시 `- [x]`로 갱신한다. +- 작업 도중 범위가 변경되면 계획 문서 체크리스트를 먼저 업데이트한 뒤 구현한다. +- 결과 보고 시 문서 하단에 검증 기록(무엇/왜/어떻게, 실행 명령, 결과)을 한국어로 남긴다. +- 후속 수정이 발생해도 기존 검증 기록은 삭제/덮어쓰기 없이 누적한다. + +## 문서 유지보수 규칙 +- `build.gradle`/`app/build.gradle`/`settings.gradle` 변경 시 실행 명령 섹션을 함께 갱신한다. +- 테스트 클래스 추가/이동 시 단일 테스트 실행 예시를 최신 상태로 유지한다. +- `.editorconfig` 변경 시 포맷 규칙 섹션을 동기화한다. +- 문서 변경 후 최소 한 번 `./gradlew tasks --all`로 명령 유효성을 확인한다. +- 불확실한 규칙은 추측으로 채우지 말고 근거 파일 경로를 먼저 확인한다. +- 에이전트 안내 문구는 한국어 중심으로 유지한다.