Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 18 additions & 35 deletions .agents/rules/commits.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,30 @@
## Commit Units

- 개발 작업은 가능한 한 작은 독립 단위로 나눈다.
- 하나의 commit은 하나의 명확한 목적만 담는다.
- commit은 가능하면 독립적으로 리뷰 가능해야 한다.
- commit은 가능하면 독립적으로 되돌릴 수 있어야 한다.
- 큰 작업도 여러 개의 작은 commit으로 나눠 진행한다.
- 인터페이스 정의, 구현체 추가, 테스트 추가, 문서 반영은 가능한 분리하되, 하나의 의미 있는 작업 단위가 깨질 정도로 과하게 쪼개지 않는다.
- 하나의 commit은 하나의 목적만 담고, 독립적으로 리뷰·revert 가능해야 한다.
- 큰 작업도 작은 commit으로 나눈다. 단, 의미 있는 작업 단위가 깨질 정도로 쪼개지 않는다.
- 각 commit 시점에 빌드와 테스트가 통과해야 한다 (AGENTS.md의 Verify 게이트).

## Feature-scoped Commit Workflow
## Feature-scoped Workflow

- 구현은 기능 단위(feature scope)로 나눈다.
- 각 기능 단위는 구현을 먼저 커밋하고, 테스트는 별도 커밋으로 분리할 수 있다. 단, 인터페이스 변경 시에는 인터페이스 정의와 해당 contract test를 같은 커밋에 포함한다 (testing.md 선행 규칙 준수).
- 구현을 먼저 커밋하고 테스트는 별도 commit으로 분리할 수 있다. 단, 인터페이스를 바꿀 때는
인터페이스 정의와 contract test를 같은 commit에 넣는다 (`testing.md`의 선행 규칙).
- 기능 단위 간 의존성이 있으면 의존되는 쪽을 먼저 커밋한다.
- 각 커밋 후 빌드와 기존 테스트가 통과해야 한다.
- 코드와 직접 연결된 문서 변경은 같은 commit 또는 바로 이어지는 commit에 넣는다.

## Message Format

- commit message 형식은 `type: commit message`로 통일한다.
- 권장 type: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`
- `commit message`는 무엇을 바꿨는지 짧고 구체적으로 적는다.
- 메시지에는 실제 변경 내용을 담는다. 작업 과정이나 도구 이름을 메시지로 쓰지 않는다 (예: ✗ "codex review 반영", ✗ "리뷰 수정", ✓ "리뷰 중단 기준에 순환 판단 조건 추가").
- `type: message` 또는 `type(scope): message`. type은 `feat`, `fix`, `refactor`, `test`, `docs`, `chore`.
- 무엇을 바꿨는지 짧고 구체적으로 쓴다.
- 작업 과정이나 도구 이름을 메시지에 쓰지 않는다
(✗ "codex review 반영", ✗ "리뷰 수정", ✓ "리뷰 중단 기준에 순환 판단 조건 추가").

## Pre-commit Checks
## History

- commit 전에는 빌드 검증과 해당 변경 범위 테스트를 수행한다.
- 작업이 끝나기 전에도 의미 있는 milestone마다 commit을 남긴다.
- commit history만 읽어도 구현 순서와 의도를 따라갈 수 있어야 한다.
- 나중에 squash할 생각의 임시 잡탕 commit보다 읽히는 history를 우선한다.

## History Quality
## Branch

- 작업 완료 전에도 의미 있는 하위 milestone마다 commit을 남긴다.
- 구현 순서가 commit history만 봐도 따라갈 수 있게 유지한다.
- 문서 변경이 코드 변경과 직접 연결되면 같은 commit 또는 바로 이어지는 commit으로 남긴다.
- 작업 종료 시 commit history만 읽어도 구현 순서와 의도를 따라갈 수 있어야 한다.
- 나중에 squashing을 기대한 임시 잡탕 commit보다 읽히는 history를 우선한다.

## Branch Strategy

- feature 단위로 브랜치를 생성한다.
- 브랜치 네이밍: `type/short-description` (e.g., `feat/user-auth`, `fix/token-expiry`)
- type은 commit message와 동일한 set을 사용한다: feat, fix, refactor, test, docs, chore
- main에 직접 커밋은 문서만 변경하거나 설정 수정 등 단순 변경에 한한다.

## Prohibited

- 하나의 commit에는 하나의 목적에 해당하는 변경만 포함한다.
- 각 작업 단위는 별도 commit으로 분리한다.
- 완료 commit은 빌드와 테스트가 통과하는 상태여야 한다.
- 브랜치 네이밍: `type/short-description` (예: `feat/user-auth`, `fix/token-expiry`). type set은 위와 같다.
- 기본 브랜치(`dev`)에 직접 커밋은 문서·설정 등 단순 변경에 한한다.
37 changes: 10 additions & 27 deletions .agents/rules/dependencies.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
## Library Selection
## Selecting

- 구현 계획 수립 시 필요한 라이브러리를 조사하고, 선정 결과를 설계 문서(architecture 등)에 확정한다.
- 후보 라이브러리를 비교할 때 **웹 검색으로 최신 정보를 확인한다**. 지식 컷오프 기준의 정보만으로 판단하지 않는다.
- 공식 SDK 또는 공식 권장 라이브러리인지
- 커뮤니티 채택도 (GitHub stars, 주간 다운로드 수, 사용 사례) — 검색으로 현재 수치 확인
- 프로젝트의 언어/프레임워크와의 호환성
- 최근 릴리스 활동과 이슈 대응 상태 — 저장소 또는 패키지 페이지에서 확인
- 공식 라이브러리 또는 커뮤니티에서 널리 채택된 라이브러리를 우선 선택한다.
- 선정 근거(왜 이 라이브러리인지, 비교한 대안)를 문서에 함께 기록한다.
- 새 의존성 전에 stdlib 또는 이미 있는 의존성으로 되는지 먼저 확인한다.
- 후보 비교는 **웹 검색으로 현재 정보를 확인한다**. 지식 컷오프 기준으로 판단하지 않는다.
공식/권장 여부, 채택도, 최근 릴리스·이슈 대응, 라이선스, transitive dependency 규모를 본다.
- 공식 또는 널리 채택된 쪽을 우선한다.
- 선정 근거와 비교한 대안을 `docs/architecture.md`에 기록한다.

## Adding New Dependencies
## Updating / Removing

- 새 의존성을 추가하기 전에 stdlib 또는 기존 의존성으로 해결 가능한지 먼저 확인한다.
- 의존성 추가 시 다음을 평가한다:
- 유지보수 상태 (최근 릴리스, 이슈 대응 속도)
- 라이선스 호환성
- 패키지 크기와 transitive dependency 수
- 프로젝트에서 실제로 사용할 기능 대비 패키지 전체 크기

## Updating Dependencies

- 의존성 업데이트 시 breaking change를 반드시 확인한다.
- major 버전 업데이트는 changelog을 읽고 migration guide가 있으면 따른다.
- 업데이트 후 빌드와 테스트가 통과하는지 확인한다.

## Removing Dependencies

- 더 이상 사용하지 않는 의존성은 제거한다.
- 제거 전 프로젝트 내 실제 사용처가 없는지 검색으로 확인한다.
- 업데이트 시 breaking change를 확인한다. major는 changelog과 migration guide를 읽는다.
- 업데이트 후 빌드와 테스트 통과를 확인한다.
- 쓰지 않는 의존성은 제거한다. 제거 전 실제 사용처가 없는지 검색으로 확인한다.
43 changes: 15 additions & 28 deletions .agents/rules/docs.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
## 문서 유형
## What Exists

- 프로젝트에는 다음 문서 중 해당하는 것만 유지한다:
- **README**: 프로젝트 목적, 시작 방법 (설치, 실행), 주요 명령어
- **Architecture 문서**: 계층 구조, 모듈 책임, 핵심 설계 결정과 그 이유
- **API 문서**: 공개 인터페이스의 입력, 출력, 에러, 사용 예시
- 프로젝트에 필요 없는 문서 유형을 만들지 않는다.
- `README.md` — 무엇인지, 설치·실행, 사전 조건. 처음 보는 사람이 5분 안에 로컬 실행 가능한 수준.
- `docs/architecture.md` — 계층 구조, 모듈 책임, 핵심 설계 결정과 그 이유.
- `docs/` 나머지 — 기능별 사용 문서.
- 필요 없는 문서 유형을 새로 만들지 않는다. 유지보수할 수 없는 문서는 만들지 않는다.
- 형식적으로 빈 섹션(Contributing, License 등)을 채우지 않는다.

## README
## What to Document

- README는 프로젝트를 처음 접하는 사람이 5분 안에 로컬에서 실행할 수 있는 수준을 목표로 한다.
- 최소 포함 항목: 프로젝트가 무엇인지 (1-2문장), 설치/실행 방법, 환경 변수나 사전 조건.
- 사용하지 않는 섹션(Contributing, License 등)을 형식적으로 채우지 않는다.
- 공개 인터페이스의 계약: 입력, 출력, 에러, 부작용.
- 비자명한 제약: 순서 의존성, 호출 전제 조건, 스레드/동시성 안전성.
- 코드가 표현하지 못하는 맥락과 "왜".
- 내부용 함수는 이름과 시그니처가 명확하면 문서화하지 않는다. 타입이 말하는 것을 주석으로 반복하지 않는다.

## API 및 인터페이스 문서
## Quality

- 공개 함수, 클래스, 모듈의 계약(입력, 출력, 에러, 부작용)을 문서화한다.
- 내부 구현용 함수는 이름과 시그니처가 명확하면 별도 문서화하지 않는다.
- 타입 시스템이 표현하는 정보를 주석으로 반복하지 않는다.
- 비자명한 제약 조건(순서 의존성, 호출 전제 조건, 스레드 안전성)은 반드시 문서화한다.

## 문서 품질

- 문서는 현재 코드와 일치해야 한다. 틀린 문서는 문서가 없는 것보다 나쁘다.
- 코드 변경으로 문서 내용이 달라지면 같은 작업 안에서 문서를 갱신한다.
- 예시 코드가 있으면 실제로 실행 가능한 상태를 유지한다.
- 추측이나 미래 계획을 사실처럼 기술하지 않는다.

## 금지 사항

- 자동 생성된 boilerplate 문서는 생성 설정을 통해 수정한다.
- 문서는 코드가 표현하지 못하는 맥락과 이유를 담는다.
- 생성하는 문서는 지속적으로 유지보수 가능한 것만 만든다.
- 틀린 문서는 없는 문서보다 나쁘다. 코드 변경으로 내용이 달라지면 같은 작업 안에서 갱신한다.
- 예시 코드는 실제로 실행 가능한 상태를 유지한다.
- 추측이나 미래 계획을 사실처럼 쓰지 않는다.
53 changes: 17 additions & 36 deletions .agents/rules/guardrails.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,29 @@
## Official Sources
## File Size

- 외부 라이브러리나 SDK의 동작이 불확실할 때 공식 문서와 소스를 직접 확인한다.
- 추측보다 소스 코드 확인을 우선한다.
- 모든 소스 파일(Rust, TypeScript, TSX, JavaScript)은 300줄 이하다. 테스트 파일도 예외 없다.
- 200줄 이상은 code smell이다. 분할을 검토한다.
- 분할은 동작을 바꾸지 않는 순수 리팩토링이어야 한다. 모듈, 순수 함수, 컴포넌트/훅으로 쪼갠다.
- 생성물(`target/`, `viewer-ui/dist/`)과 벤더링한 서드파티는 제외한다.

## Architecture

- 프로젝트에 architecture 문서가 있으면 설계 결정의 기준으로 삼는다.
- 문서화된 설계 전제를 구현의 기준으로 유지한다.
- `docs/architecture.md`가 설계 결정의 기준이다. 구현이 문서와 어긋나면 문서를 먼저 고치거나 구현을 조정한다.
- top-level 구조는 새 모듈을 붙일 수 있도록 열어 두되, 초기 구현은 간소하게 시작한다.

## Code Quality

- 가장 단순한 해결책을 먼저 시도한다. 복잡한 추상화는 반복이 실제로 발생한 후에 도입한다.
- 하나의 함수/모듈은 하나의 책임만 갖는다. 책임이 섞이면 분리한다.
- 매직 넘버, 하드코딩된 문자열은 이름 있는 상수로 추출한다.
- 이해하기 어려운 로직에만 주석을 단다. "무엇"이 아니라 "왜"를 설명한다.

## Performance

- 알고리즘 복잡도를 의식한다. O(n²) 이상이면 의도적 선택인지 확인한다.
- hot path에서는 할당, 복사, 변환을 최소화한다.
- 쿼리는 배치로 처리하여 N+1 패턴을 방지한다.
- 성능 최적화는 측정 후에 한다. 추측 기반 최적화를 하지 않는다.
- 가장 단순한 해결책을 먼저 시도한다. 추상화는 반복이 실제로 발생한 후에 도입한다.
- 하나의 함수/모듈은 하나의 책임만 갖는다.
- 매직 넘버와 하드코딩 문자열은 이름 있는 상수로 뽑는다.
- 주석은 "왜"만 남긴다. 타입이 이미 말하는 것은 반복하지 않는다.

## Error Handling

- 에러는 처리하거나 명시적으로 전파한다.
- 에러 메시지는 디버깅에 충분한 컨텍스트를 포함한다 (무엇이 실패했고, 어떤 입력이었는지).
- 복구 가능한 에러와 복구 불가능한 에러를 구분하여 처리한다.
- 외부 시스템 호출 실패 시 재시도 여부와 전략을 명시적으로 결정한다.

## External Integration
- 에러는 처리하거나 명시적으로 전파한다. 조용히 삼키지 않는다.
- 에러 메시지에 무엇이 실패했고 입력이 무엇이었는지를 담는다.
- 복구 가능/불가능을 구분하고, 외부 호출 실패는 재시도 여부를 명시적으로 결정한다.

- 외부 시스템과의 인터페이스는 공식 문서와 SDK를 우선으로 맞춘다.
- 공식 helper/wrapper가 있으면 우선 사용한다.
- 외부 시스템 인터페이스는 공식 SDK와 표준 패턴을 사용한다.
## Externals

## Extensibility

- 초기 구현은 간소화하되, 이후 확장 가능한 구조를 유지한다.
- top-level 구조는 새로운 모듈 추가가 가능하도록 범용적으로 유지한다.

## File Size

- 모든 소스 파일(Rust, TypeScript, TSX, JavaScript)은 300줄 이하다. 테스트 파일도 예외 없다.
- 200줄 이상은 code smell이다. 분할을 검토한다.
- 분할은 동작을 변경하지 않는 순수 리팩토링이어야 한다. 커스텀 훅, 컴포넌트, 순수 함수 모듈로 쪼갠다.
- 생성된 파일(`dist/`, `target/`)과 벤더링한 서드파티는 제외한다.
- 외부 라이브러리·SDK의 동작이 불확실하면 추측하지 말고 공식 문서와 소스를 직접 확인한다.
- 렌더 루프 등 hot path에서는 할당·복사·변환을 최소화한다. 그 밖의 최적화는 측정 후에 한다.
22 changes: 9 additions & 13 deletions .agents/rules/security.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
## Input Validation

- 시스템 경계(사용자 입력, 외부 API 응답, 파일 읽기)에서 들어오는 데이터는 항상 검증한다.
- 시스템 경계(사용자 입력, 외부 API 응답, 파일 읽기, HTTP 요청)에서 오는 데이터는 항상 검증한다.
- 내부 모듈 간 호출에서는 과도한 방어적 검증을 피한다. 계약을 신뢰한다.

## Secrets Management

- 비밀번호, API 키, 토큰은 환경 변수나 별도 설정 파일을 통해 주입한다.
- `.env`, credentials 파일은 `.gitignore`에 포함하고 절대 커밋하지 않는다.

## Logging
## Secrets

- 비밀번호, API 키, 토큰은 환경 변수나 별도 설정 파일로 주입한다.
- `.env`, credentials 파일은 `.gitignore`에 두고 절대 커밋하지 않는다.
- 로그의 민감 필드(비밀번호, 토큰, 개인식별정보)는 마스킹한다.
- 에러 로그에는 디버깅에 필요한 컨텍스트를 충분히 포함한다.

## Dependencies
## Least Privilege

- 의존성 추가 시 알려진 취약점(CVE) 여부, 유지보수 상태, 보안 이력을 확인한다.
- 파일, 네트워크, API 접근 권한은 필요한 최소 범위로 제한한다.
- 로컬 소켓·HTTP 서버는 필요 이상으로 넓은 인터페이스에 바인드하지 않는다.

## Principle of Least Privilege
## Dependencies

- 파일, 네트워크, API 접근 권한은 필요한 최소 범위로 제한한다.
- 권한은 작업에 필요한 최소 수준만 요청한다.
- 의존성 추가 시 알려진 CVE, 유지보수 상태, 보안 이력을 확인한다.
44 changes: 15 additions & 29 deletions .agents/rules/testing.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,23 @@
## Test Layers
## Which Layer

- unit tests — 순수 함수, 개별 모듈 로직
- contract tests — 모듈 간 계약(인터페이스) 검증
- integration tests — API endpoint, 전체 요청 흐름
- end-to-end tests — 사용자 관점의 시나리오 검증

## When to Use Which

- 모듈의 계약(인터페이스)을 추가/변경할 때 → contract test 필수
- 순수 함수, 개별 로직을 추가/변경할 때 → unit test
- API endpoint, middleware, 전체 요청 흐름을 추가/변경할 때 → integration test
- 하나의 변경이 여러 유형에 해당하면 각각 작성한다

## File Placement

- 테스트 파일 배치와 네이밍은 프로젝트의 기존 컨벤션을 따른다.
- test fixtures/helpers가 여러 테스트에서 공유되면 공통 디렉토리에 둔다.

## Principles

- 테스트는 구현 세부사항이 아니라 계약과 동작을 검증한다.
- mock은 외부 시스템 경계(외부 API, 네트워크 호출)에만 사용한다.
- 테스트 이름은 `무엇을_하면_어떤_결과가_나온다` 패턴으로 의도를 명확히 한다.
- 각 테스트는 독립적으로 실행 가능해야 한다. 테스트 간 상태 공유는 금지한다.
- 모듈 간 계약(인터페이스)을 추가/변경 → **contract test 필수**
- 순수 함수, 개별 모듈 로직 → unit test
- API endpoint, 요청 흐름 전체(web viewer, daemon protocol) → integration test
- 사용자 관점 시나리오 → end-to-end test
- 하나의 변경이 여러 유형에 걸치면 각각 작성한다.

## Rules

- contract test를 먼저 갱신하지 않고 인터페이스를 바꾸지 않는다.
- 에러 케이스와 경계 조건(null, empty, 범위 초과, 잘못된 타입)을 명시적으로 테스트한다.
- 성공 경로뿐 아니라 실패 경로도 테스트한다.
- 테스트는 구현 세부사항이 아니라 계약과 동작을 검증한다.
- 성공 경로만이 아니라 실패 경로와 경계 조건(null, empty, 범위 초과, 잘못된 타입)도 명시적으로 테스트한다.
- mock은 외부 시스템 경계에만 쓴다.
- 각 테스트는 독립 실행 가능해야 한다. 테스트 간 상태 공유 금지.
- 테스트 이름은 `무엇을_하면_어떤_결과가_나온다` 패턴으로 의도를 드러낸다.
- 배치·네이밍은 기존 컨벤션을 따른다. 공유 fixture/helper는 공통 위치에 둔다 (`src/test_util.rs`).

## Flaky Tests

- 테스트 실패 시 원인을 먼저 분류한다: 코드 결함 vs 환경/타이밍 문제.
- flaky 테스트를 발견하면 즉시 수정하거나, 수정 전까지 skip 처리하고 이슈로 기록한다.
- flaky 테스트를 이유로 전체 테스트 결과를 무시하지 않는다.
- 실패하면 원인을 먼저 분류한다: 코드 결함 vs 환경/타이밍.
- flaky를 발견하면 즉시 고치거나, 고치기 전까지 skip하고 이슈로 남긴다.
- flaky를 이유로 전체 테스트 결과를 무시하지 않는다.
28 changes: 0 additions & 28 deletions .agents/rules/token-optimization.md

This file was deleted.

Loading
Loading