Files
clean-architecture-backend-…/AGENTS.md
T

249 lines
14 KiB
Markdown

# AGENTS.md
## 프로젝트 정체성
이 저장소는 단순한 예제 블로그 애플리케이션이 아니라, Java 21 + Spring Boot 4.0.0 + Gradle 멀티모듈 기반의 Clean Architecture 템플릿이다.
기본 패키지는 `dev.caskeleton`이며, 예시 도메인은 production 모듈이 아니라 `sample-portfolio` 모듈(WorkLog 엔지니어링 작업 기록 게시판)에 격리한다. 새 프로젝트를 시작할 때는 도메인 이름, 패키지, 엔티티, 유스케이스를 교체할 수 있지만, 모듈 경계와 의존성 방향은 유지해야 한다.
## Prime Directive
에이전트는 속도보다 아키텍처 보존을 우선한다.
동작하는 코드라도 HARD-STOP 조건을 하나라도 위반하면 완료된 작업이 아니다.
다음 HARD-STOP 8개 항목이 이 저장소의 정본(canonical) 로컬 정책 권위이자 SSOT다.
1. `domain-core`가 framework, transport, database, cloud 의존성을 가진다.
2. controller가 repository, Spring Data interface, persistence entity를 직접 사용한다.
3. inbound DTO가 `application-core` 또는 `domain-core`로 유출된다.
4. 비즈니스 규칙이 mapper, filter, configuration, settings, controller로 이동한다.
5. 프로젝트 의존성이 `src/config/architecture/modules.json` 또는 Gradle 의존성 검증을 위반한다.
6. 관련 검증 없이, 또는 실행하지 못한 이유를 밝히지 않고 완료를 주장한다.
7. 결론의 범위와 위험에 맞는 증거 없이 repository/corpus 전체 결론을 내린다.
8. 의미 있는 작업을 필수 LLM Wiki capture 또는 명시한 capture 차단 사유 없이 종료한다.
root `CLAUDE.md`는 이 목록의 동기화된 요약이다. 두 문서가 어긋나면 이 `AGENTS.md` 목록이
우선한다. 자동 강제 범위는 아래 Gradle 정책 권위와 ArchUnit/Test가 담당한다.
## Superpowers Workflow
이 프로젝트에서 에이전트는 관련 Superpowers 스킬을 먼저 확인하고, 작업 성격에 맞는 스킬을 사용한다. 사용자 지시와 이 `AGENTS.md`가 로컬 프로젝트의 최상위 규칙이며, Superpowers는 그 규칙을 실행하기 위한 작업 방식이다.
사용 가능한 주요 스킬과 트리거:
- `superpowers:using-superpowers`: 대화나 작업을 시작할 때 관련 스킬을 확인한다.
- `superpowers:brainstorming`: 기능 설계, 구조 변경, 동작 변경, 새 문서 정책 수립 전에 사용한다.
- `superpowers:writing-plans`: 승인된 설계가 있고 작업이 여러 단계로 나뉠 때 사용한다.
- `superpowers:executing-plans`: 작성된 계획을 현재 세션에서 순차 실행할 때 사용한다.
- `superpowers:subagent-driven-development`: 계획을 작업 단위로 나누어 독립 에이전트에게 맡길 때 사용한다.
- `superpowers:dispatching-parallel-agents`: 서로 독립적인 조사나 구현을 병렬로 진행할 때 사용한다.
- `superpowers:test-driven-development`: 기능 추가와 버그 수정을 테스트 우선으로 진행할 때 사용한다.
- `superpowers:systematic-debugging`: 버그, 실패한 테스트, 예상 밖 동작을 다룰 때 사용한다.
- `superpowers:verification-before-completion`: 완료, 수정됨, 통과함을 주장하기 전에 사용한다.
- `superpowers:requesting-code-review`: 의미 있는 구현을 마친 뒤 병합 또는 PR 전에 사용한다.
- `superpowers:receiving-code-review`: 리뷰 피드백을 적용하기 전에 사용한다.
- `superpowers:finishing-a-development-branch`: 구현과 검증이 끝난 브랜치를 정리할 때 사용한다.
- `superpowers:using-git-worktrees`: 격리된 작업 공간이 필요할 때 사용한다.
- `superpowers:writing-skills`: 스킬을 만들거나 수정할 때 사용한다.
## Gradle 정책 권위
- `src/config/architecture/modules.json`: 정확히 19개 leaf의 ID, repository-relative 소스 경로,
Gradle path, 허용 production project dependency edge
- `src/settings.gradle`: registry를 fail-closed로 검증하고 등록된 Gradle project를 include/mapping
- `src/build.gradle`: 같은 registry를 읽는 `verifyCleanArchitectureDependencies`와 그 밖의
architecture-wide verification task
작업 파일의 소유 leaf는 registry의 `source_path`로 판단하고 가장 가까운 `src/**/CLAUDE.md`
함께 읽는다. focused test는 registry의 `gradle_path`에서
`./gradlew <gradle-path>:test --console=plain` 형태로 파생한다. 파일 수만으로 위험을 판단하지 않고,
변경한 경계와 런타임·보안·데이터 영향에 맞춰 설계·리뷰·검증 강도를 높인다.
commit 정책은 모든 플랫폼에서 `human-only`이며 agent는 stage/commit/amend/push하지 않는다.
## LLM Wiki 캡처 워크플로우
구현, 아키텍처, 빌드, 테스트, 런타임, 문서 워크플로우 변경처럼 의미 있는 작업을 끝낸 뒤에는 최종 응답 전에 LLM Wiki 기록을 갱신한다.
기준 vault:
```text
/home/donghyeon/workspace/ai-tool/llm-wiki-private/
```
에이전트는 해당 vault의 `AGENTS.md`, `CLAUDE.md`, `rules/`, `.agents/`, `.claude/`, `.codex/` 지침을 확인한 뒤 작성한다.
필수 순서:
1. `/home/donghyeon/workspace/ai-tool/llm-wiki-private/raw/branch-notes/<branch-name>.md`를 생성하거나 갱신한다.
2. 구현 내용, 변경 파일, 의사결정, 검증 명령, 실패/차단 사항, 증거 등급을 branch-note에 기록한다.
3. 실제로 파생 자료가 있으면 다음 raw 문서를 생성하거나 갱신한다.
- `raw/errors/`: 오류, 실패한 테스트, 샌드박스/도구 문제, 재발 가능한 트러블슈팅
- `raw/interviews/`: 이 작업에서 정직하게 뽑을 수 있는 면접 질문
- `raw/blog-topics/`: 채용공고가 아닌 구현·설계·트러블슈팅 기반 블로그 글감
4. 파생 문서는 `## Parent`에서 branch-note로 upward link하고, branch-note의 `## Cluster / 묶음`에는 파생 문서 wikilink를 되돌려 적는다.
5. canonical 추출 요청이 없는 한 `wiki/blog/`, `wiki/interview/`, `wiki/portfolio/`, `wiki/concepts/`, `wiki/projects/`를 바로 만들지 않는다.
파생 문서가 필요 없을 때도 그냥 생략하지 말고, branch-note의 cluster 섹션에 "없음" 또는 "추출할 별도 글감 없음"처럼 판단 결과를 남긴다.
## 강제 수준
이 문서는 에이전트와 개발자가 따라야 할 작업 규칙을 정의하지만, 그 자체로 빌드나 테스트를 실패시키는 자동 강제 장치는 아니다.
이 프로젝트의 규칙은 세 단계로 관리한다.
1. `AGENTS.md`: 에이전트와 개발자가 따라야 할 아키텍처, 작업 순서, 검증 원칙을 정의한다.
2. ArchUnit/Gradle/Test: 모듈 의존성, 계층 침범, 설정 바인딩, 동작 회귀를 자동으로 탐지한다.
3. Code Review/CI: 문서와 자동 검증이 놓친 설계 품질, 운영 위험, 템플릿 일관성을 최종 확인한다.
에이전트는 `AGENTS.md`를 따라 작업해야 하며, 현업 수준의 스켈레톤 완성도는 반드시 자동 검증과 리뷰로 보강해야 한다.
## 모듈 책임
19개 leaf 모듈의 ID, 실제 소스 경로, Gradle path, 허용 production 의존성은
`src/config/architecture/modules.json`이 SSOT다. focused test는 소유 leaf의 `gradle_path`에서
파생한다. 이 문서는 leaf 목록을 복제하지 않고 family 책임만 정의한다. 작업 파일에서는 가장 가까운
`src/**/CLAUDE.md`를 함께 읽는다.
- `domain-core`: 순수 도메인 모델, 불변식, 이벤트, port. Spring/JPA/transport/IO 타입 금지.
- `application-core`: command, use case, application policy, transaction port, application 예외.
inbound DTO, persistence entity, adapter 타입 금지.
- `adapter:inbound:*`: HTTP/gRPC/GraphQL/WebSocket transport, DTO, validation, 인증·인가 매핑,
error mapping. repository 직접 호출과 비즈니스 정책 금지.
- `adapter:outbound:persistence-*`: JPA/PostgreSQL 또는 MongoDB persistence 구현과 mapping,
migration/vendor 동작. 유스케이스 정책 금지.
- 그 밖의 `adapter:outbound:*`: support, messaging, cache, notification, object storage,
file server, HTTP client, identifier 능력을 port 뒤에서 구현한다. adapter 간 허용 edge는
registry만 따른다.
- `shared-contract`: skeleton-wide 운영 계약. business/domain 개념 저장 금지.
- `sample-portfolio`: 샘플/fixture consumer. production leaf가 의존하면 안 된다.
- `app-bootstrap`: Spring Boot entrypoint와 composition root. 비즈니스 유스케이스 금지.
## 의존성 방향
family 수준 기본 방향:
```text
app-bootstrap -> adapter:inbound:* -> application-core -> domain-core
app-bootstrap -> adapter:outbound:* -> application-core -> domain-core
runtime modules -> shared-contract
sample-portfolio -> registered runtime leaves (fixture consumer only)
```
개별 edge는 `src/config/architecture/modules.json``allowed_dependencies`가 유일한 목록이다.
Gradle 의존성 검증도 같은 registry를 읽는다. root 문서나 기억에서 leaf edge를 추론하지 않는다.
## 기능 개발 프로토콜
새 기능이나 동작 변경은 다음 순서로 진행한다.
1. 요구사항을 읽고 소유 계층을 판단한다.
2. 구조나 동작이 바뀌면 `superpowers:brainstorming`으로 설계를 먼저 확정한다.
3. 여러 단계의 작업이면 `docs/superpowers/specs/`에 설계 문서를 남긴다.
4. 구현 전 `docs/superpowers/plans/`에 실행 계획을 작성한다.
5. 동작 변경은 테스트를 먼저 작성한다.
6. 새 비즈니스 개념은 `domain-core`에 먼저 둔다.
7. 유스케이스는 `application-core` command와 use case/service method로 표현한다.
8. 외부 연동은 registry가 가리키는 `adapter:outbound:*` leaf에서 port 구현으로 추가한다.
9. endpoint는 마지막에 해당 `adapter:inbound:*` leaf에서 얇게 연결한다.
10. focused test를 먼저 돌리고, 가능한 경우 전체 Gradle test를 돌린다.
11. LLM Wiki branch-note와 필요한 파생 raw 문서를 갱신한다.
12. 완료 응답에는 변경 파일, 검증 결과, Wiki capture 결과를 포함한다.
## 테스트 전략
계층별 테스트 기준:
- `domain-core`: Spring 없이 순수 unit test로 도메인 규칙을 검증한다.
- `application-core`: fake/in-memory port를 사용해 유스케이스 흐름을 검증한다.
- `adapter:inbound:*`: transport validation, auth mapping, status/response contract를 검증한다.
- `adapter:outbound:persistence-*`: persistence mapping, repository adapter, vendor/migration 동작을 검증한다.
- 그 밖의 `adapter:outbound:*`: external capability adapter contract를 검증한다.
- `app-bootstrap/settings`: configuration binding, validation, logging 설정을 검증한다.
검증 원칙:
- 완료를 주장하기 전에 `superpowers:verification-before-completion`을 사용한다.
- 실행한 명령과 결과를 최종 응답에 적는다.
- 테스트를 실행하지 못했다면 이유와 남은 위험을 솔직히 적는다.
권장 절차:
```bash
cd src
./gradlew <owner-gradle-path>:test --console=plain
./gradlew test
./gradlew check # check 가 verifyCleanArchitectureDependencies + verifyEnvKeys 2종을 전이 실행한다 (src/build.gradle)
./gradlew verifyCleanArchitectureDependencies
./gradlew verifyPublicPathSnapshot
./gradlew verifyEnvKeys
```
소유 leaf의 정확한 Gradle path는 `src/config/architecture/modules.json`에서 읽고 focused test
명령을 파생한다. root 문서에 19개 명령 목록을 복제하지 않는다.
## 설정과 런타임
설정 규칙:
- secrets를 코드, 테스트 fixture, 문서 예시에 하드코딩하지 않는다.
- 새 설정 그룹은 typed settings class로 만든다.
- 흩어진 `@Value`보다 configuration properties와 settings class를 선호한다.
- `.env.local`은 로컬 오버라이드로 취급한다.
- `application.yml`은 환경별로 안전한 기본값과 명확한 placeholder만 담는다.
- 새 settings class를 만들면 binding/validation 테스트를 추가한다.
Docker/runtime 규칙:
- Dockerfile 변경 시 build context와 runtime env 요구사항을 함께 확인한다.
- container 안에서 필요한 profile, port, env var를 문서나 예시 설정에 반영한다.
- local-only 경로와 운영 경로를 섞지 않는다.
## 템플릿 재사용 체크리스트
이 저장소를 새 프로젝트 시작점으로 사용할 때:
1. `src/settings.gradle``rootProject.name`을 새 프로젝트명으로 바꾼다.
2. Java package `dev.caskeleton`을 새 organization/project package로 바꾼다.
3. `CaSkeletonApplication` 이름을 새 애플리케이션 이름으로 바꾼다.
4. production 모듈에는 목표 도메인의 entity, repository port, use case, adapter만 추가하고, 예시 코드는 `sample-portfolio`에 격리한다.
5. 모듈 이름과 경계는 유지한다.
6. Docker image/application 이름을 새 프로젝트 기준으로 수정한다.
7. `.env`, `.env.local`, `application.yml`의 예시 값을 새 런타임 요구사항에 맞춘다.
8. README와 운영 문서를 새 프로젝트 설명으로 갱신한다.
9. 전체 테스트를 실행한다.
```bash
cd src
./gradlew test
```
## 금지된 지름길
에이전트는 다음을 하지 않는다.
- `domain-core`에 Spring/JPA annotation 추가
- controller에서 repository 직접 호출
- application method가 web request DTO를 인자로 받게 만들기
- application이나 domain에서 JPA entity 반환
- mapper에 비즈니스 정책 넣기
- filter/config/settings class에 유스케이스 넣기
- 요청 범위 밖의 대규모 리팩터링
- 사용자 변경사항 되돌리기
- 명시적 요청 없는 destructive git command 실행
- 테스트 미실행 상태에서 "완료"라고 말하기
## 작업 보고 규칙
최종 응답에는 다음을 포함한다.
- 변경한 파일
- 핵심 변경 내용
- 실행한 검증 명령
- 실패하거나 실행하지 못한 검증
- LLM Wiki branch-note와 파생 문서 캡처 결과
- 남은 위험 또는 후속 작업
짧은 작업이라도 검증 여부는 생략하지 않는다.