diff --git a/.codex/skills/README.md b/.codex/skills/README.md new file mode 100644 index 0000000..7068b0d --- /dev/null +++ b/.codex/skills/README.md @@ -0,0 +1,22 @@ +# Skills + +이 디렉터리는 `git-ranker` backend repo에서만 쓰는 repo-local skill을 관리한다. + +## Canonical Ownership + +- backend behavior, package structure, runtime config는 `AGENTS.md`, `README.md`, `src/main/`이 canonical source다. +- build/test baseline과 verification lane은 `build.gradle`, `.github/workflows/ci.yml`, `.github/workflows/deploy.yml`이 canonical source다. +- skill은 위 문서를 대체하지 않고, 반복되는 TDD turn의 역할과 handoff만 고정한다. + +## Registry Status + +- `red`: failing test로 behavior slice를 잠그는 첫 TDD turn +- `green`: red에서 잠근 failing test를 최소 production 변경으로 통과시키는 turn +- `refactor`: green을 유지한 채 구조와 중복만 정리하는 turn + +## Recommended Use + +1. `git-ranker`에서 테스트 코드를 추가하거나 backend 기능을 TDD로 구현할 때는 기본적으로 `red -> green -> refactor` 순서를 따른다. +2. 각 turn은 현재 slice 하나만 다루고, 다음 turn의 역할을 침범하지 않는다. +3. 현재 baseline에 필요한 test dependency, `src/test` bootstrap, verification lane 변경이 보이면 그 범위를 approved spec에 먼저 잠근다. +4. repo baseline이 아직 build-only인 상태이므로, skill은 test infra drift를 숨기지 말고 드러내야 한다. diff --git a/.codex/skills/green/SKILL.md b/.codex/skills/green/SKILL.md new file mode 100644 index 0000000..714f6ce --- /dev/null +++ b/.codex/skills/green/SKILL.md @@ -0,0 +1,41 @@ +--- +name: green +description: `git-ranker`에서 red turn으로 잠근 failing test를 최소 production-side 변경으로 통과시키는 green turn을 수행한다. Spring Boot production code를 좁은 범위로 수정하고 같은 command를 green으로 바꿔야 할 때 이 skill을 사용한다. +--- + +# Green Turn + +이 turn의 목적은 pass를 만드는 것이다. 설계 정리나 다음 기능을 같이 하지 말고, red에서 잠근 slice만 green으로 닫는다. + +## 먼저 확인할 것 + +- red turn의 failing evidence +- approved spec +- target test file과 failure reason +- 관련 production package under `src/main/java` + +## 작업 방식 + +1. red command를 다시 실행해 같은 failure가 재현되는지 확인한다. +2. 현재 slice를 통과시키는 최소 production-side 변경만 적용한다. 기본 대상은 `src/main/java`이며, 현재 behavior contract에 꼭 필요한 경우에만 `src/main/resources`를 건드린다. +3. test file은 그대로 둔다. passing을 위해 assertion, fixture, mock, request payload를 뒤로 숨겨 바꾸지 않는다. +4. Spring Boot에서는 가능한 한 가장 안쪽 계층부터 해결한다. domain/service 수정만으로 닫을 수 있으면 controller/config까지 넓히지 않는다. +5. 같은 targeted command를 다시 실행해 green을 만든다. +6. 영향 범위가 바로 옆 클래스나 slice test에 걸치면 작은 인접 suite까지만 추가 확인한다. green turn을 verification rebuild 작업으로 확장하지 않는다. +7. 남은 냄새, 중복, 이름 문제를 짧게 정리해 `refactor`로 넘긴다. + +## 결과 + +- green command +- pass evidence +- 변경한 production path +- refactor candidate +- next handoff: `refactor` + +## 피해야 할 것 + +- test file을 수정해 red를 없애는 것 +- refactor 성격의 cleanup을 섞는 것 +- 현재 failing slice와 무관한 새 behavior를 같이 구현하는 것 +- 더 작은 수정으로 닫을 수 있는데 구조 개편이나 새 의존성 도입으로 넓히는 것 +- green 과정에서 spec drift나 infra gap이 드러났는데도 그대로 진행하는 것 diff --git a/.codex/skills/red/SKILL.md b/.codex/skills/red/SKILL.md new file mode 100644 index 0000000..d8ddc44 --- /dev/null +++ b/.codex/skills/red/SKILL.md @@ -0,0 +1,48 @@ +--- +name: red +description: `git-ranker`에서 테스트 코드 작성이나 TDD 기반 기능 구현을 시작할 때 첫 red turn을 수행한다. Java/Spring Boot behavior slice를 failing test로 고정하고, 최소 test level과 실패 원인을 잠가야 할 때 이 skill을 사용한다. +--- + +# Red Turn + +이 turn의 목적은 기대 동작을 failing test 하나로 잠그는 것이다. production pass를 만들지 말고, 구현 공백이나 contract mismatch 때문에 실패하는 상태로 끝낸다. + +## 먼저 확인할 것 + +- approved spec +- `AGENTS.md` +- `build.gradle` +- target production package under `src/main/java` +- existing `src/test/` tree와 test dependency 존재 여부 + +## Test Level 선택 순서 + +1. pure JUnit + Mockito: 서비스, 계산기, orchestrator처럼 collaborator 경계가 분명할 때 +2. `@WebMvcTest`: controller, request validation, response contract를 잠글 때 +3. `@DataJpaTest`: repository query, entity mapping, persistence behavior를 잠글 때 +4. `@SpringBootTest`: 더 좁은 slice로 behavior를 표현할 수 없을 때만 + +## 작업 방식 + +1. behavior slice를 하나로 줄인다. 메서드 하나, 엔드포인트 한 규칙, 배치 step 한 조건처럼 지금 turn에서 green으로 닫을 수 있는 범위만 잡는다. +2. production package를 미러링하는 test file 하나를 만든다 또는 수정한다. +3. assertion은 기대 contract를 직접 드러내게 쓴다. TODO, placeholder, 너무 넓은 smoke assertion으로 숨기지 않는다. +4. 새 기능을 TDD로 시작하는 경우, 의도적으로 없는 public API를 참조한 compile failure도 red evidence가 될 수 있다. 단, failure가 현재 slice를 명확히 설명해야 한다. +5. 현재 repo에 최소 test runtime이 없으면, approved spec이 허용한 범위 안에서만 가장 작은 test-side bootstrap을 추가한다. 예: `spring-boot-starter-test`, `src/test/resources/application-test.yml`. 이 bootstrap은 failing test를 실행 가능하게 만드는 목적만 가져야 한다. +6. 가장 좁은 명령으로 red를 확인한다. 예: `./gradlew test --tests com.gitranker.api.domain.ranking.RankingServiceTest` +7. 실패 원인이 missing behavior인지, infra drift인지, spec drift인지 구분해 기록한다. infra drift가 주요 원인이면 green으로 밀어붙이지 말고 spec을 다시 연다. + +## 결과 + +- failing test path +- red command +- expected failure reason +- next handoff: `green` + +## 피해야 할 것 + +- production code를 수정하는 것 +- 한 turn에 test file 여러 개를 만드는 것 +- 더 좁은 slice가 가능한데 곧바로 `@SpringBootTest`로 가는 것 +- green을 쉽게 만들기 위해 assertion을 약하게 쓰는 것 +- approved spec에 없는 test infra rebuild를 red에 숨겨 섞는 것 diff --git a/.codex/skills/refactor/SKILL.md b/.codex/skills/refactor/SKILL.md new file mode 100644 index 0000000..6b2ffbe --- /dev/null +++ b/.codex/skills/refactor/SKILL.md @@ -0,0 +1,39 @@ +--- +name: refactor +description: `git-ranker`에서 green 상태의 TDD slice를 유지한 채 구조만 정리하는 refactor turn을 수행한다. Java/Spring Boot production/test code의 중복 제거, 이름 개선, helper 추출 같은 정리를 하고 같은 verification을 green으로 끝내야 할 때 이 skill을 사용한다. +--- + +# Refactor Turn + +refactor는 의미를 바꾸지 않는 정리다. contract나 observable behavior가 달라질 것 같으면 refactor를 멈추고 slice를 다시 나눈다. + +## 먼저 확인할 것 + +- green evidence +- current slice의 남은 smell +- approved spec +- 방금 green으로 만든 test command + +## 작업 방식 + +1. 줄일 냄새를 먼저 하나로 적는다. 예: 중복된 mapping, 읽기 어려운 메서드 이름, 테스트 setup 잡음, fixture 반복. +2. observable behavior를 바꾸지 않는 범위에서 production code와 test code를 정리한다. +3. test code를 건드린다면 의미 변경 없는 cleanup으로 한정한다. helper 추출, builder 정리, 중복 제거는 가능하지만 assertion intent나 시나리오 범위를 바꾸지 않는다. +4. 같은 targeted command를 다시 실행해 green을 유지한다. +5. shared area를 건드렸다면 가장 가까운 작은 suite만 추가 확인한다. 현재 repo baseline이 build-only라고 해서 refactor turn을 전체 verification rebuild로 넓히지 않는다. +6. 이번 slice가 끝났는지, 다음 red slice가 남았는지 짧게 정리한다. + +## 결과 + +- 제거한 smell +- rerun command와 green evidence +- 정리한 path +- next slice 또는 stop signal + +## 피해야 할 것 + +- 새 behavior를 추가하는 것 +- bug fix를 refactor로 위장하는 것 +- assertion 의미나 public contract를 바꾸는 것 +- 현재 slice와 무관한 넓은 architecture cleanup으로 번지는 것 +- green이 깨진 상태로 turn을 끝내는 것 diff --git a/AGENTS.md b/AGENTS.md index 0de3e6d..8dc80d6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,14 +7,16 @@ 1. `README.md`에서 프로젝트 목적과 high-level overview를 확인한다. 2. `build.gradle`, `settings.gradle`에서 모듈 구조, 의존성, verification task를 확인한다. 3. `.github/workflows/ci.yml`, `.github/workflows/deploy.yml`에서 CI verification lane과 pre-deploy gate를 확인한다. -4. 현재 `src/test/` tree는 baseline reset 상태이므로, follow-up verification rebuild 전까지는 `build.gradle`과 workflow가 retained build-only lane을 어떻게 고정하는지 먼저 본다. -5. `src/main/java/`, `src/main/resources/`에서 실제 구현과 runtime config를 읽는다. +4. 테스트 코드 작성이나 TDD 기반 기능 구현 요청이면 `.codex/skills/README.md`와 `red`, `green`, `refactor` skill을 먼저 확인한다. +5. 현재 `src/test/` tree는 baseline reset 상태이므로, follow-up verification rebuild 전까지는 `build.gradle`과 workflow가 retained build-only lane을 어떻게 고정하는지 먼저 본다. +6. `src/main/java/`, `src/main/resources/`에서 실제 구현과 runtime config를 읽는다. ## Source Of Truth - repo overview: `README.md` - build and verification entrypoint: `build.gradle` - CI / deploy gate: `.github/workflows/ci.yml`, `.github/workflows/deploy.yml` +- repo-local TDD workflow: `.codex/skills/README.md`, `.codex/skills/red/SKILL.md`, `.codex/skills/green/SKILL.md`, `.codex/skills/refactor/SKILL.md` - backend behavior and contracts: `src/main/java/`, `src/main/resources/` - runtime container surface: `Dockerfile`, `docker-compose.yml` @@ -25,4 +27,8 @@ - 현재 verification baseline command set은 `./gradlew build`다. - current baseline에는 dedicated test/integration lane이 없다. follow-up rebuild가 필요하면 `build.gradle`, workflow YAML, `AGENTS.md`를 함께 갱신한 뒤 repo-local baseline으로 다시 도입한다. - verification lane이나 deploy gate를 바꾸면 `build.gradle`, workflow YAML, `AGENTS.md`를 함께 맞춘다. -- 현재 repo-local `.codex/skills/`는 없다. 별도 skill이 없을 때는 이 문서와 nearest code/test를 먼저 읽고 진행한다. +- repo-local TDD workflow는 `.codex/skills/red`, `.codex/skills/green`, `.codex/skills/refactor`가 소유한다. +- 테스트 코드 작성 요청이나 TDD 기반 기능 구현 요청이 들어오면 기본 순서를 `red -> green -> refactor`로 고정한다. +- `red`는 failing test와 현재 slice를 잠그고, `green`은 최소 production 변경으로 pass를 만들고, `refactor`는 green을 유지한 채 구조만 정리한다. +- 현재 baseline이 build-only 상태이므로, test dependency 추가나 verification lane rebuild가 필요하면 그 범위를 spec에 먼저 잠그고 `build.gradle`, workflow YAML, `AGENTS.md`를 함께 갱신한다. +- repo-local skill로 해결되지 않는 작업만 이 문서와 nearest code/test를 추가로 읽고 진행한다.