LMCache Contribution 룰 정리
PR 작성/리뷰 시 빠르게 참고하기 위한 한국어 요약. 원본은 다음 5개 문서:
CONTRIBUTING.md— 기본 절차, 환경, 테스트AGENTS.md— 자기-검수 체크리스트 (docs/coding_standards.md의 quick-reference)docs/coding_standards.md— canonical reference (§1 ~ §10)DCO— Developer Certificate of Origin v1.1CODE_OF_CONDUCT.md— Contributor Covenant 기반
규칙이 충돌하거나 헷갈리면 docs/coding_standards.md 가 source of truth.
1. 기본 절차
- Default branch 는
dev. 모든 새 브랜치/PR 은dev기준. - DCO sign-off 필수. 모든 커밋에
Signed-off-by:라인 (git commit -s). - Committer 승격: 5+ 중요 feature 머지 + 3개월+ 기여 + 기존 committer nomination.
- Default 환경:
uv venv --python 3.12+uv pip install -e . --no-build-isolation(torch 선설치).
2. PR Scope (§1.1)
- PR 은 작고 한 가지 목적. 큰 변경은 모듈 경계 또는 단계(interface → 구현 → 테스트)로 분리.
- omnibus PR 금지. 시리즈로 쪼개기.
3. Typing (§2)
- 모든 함수/메서드에 인자/반환 type hint 필수.
Any금지 — 타입이 애매하면 인터페이스를 다시 설계.- 컨테이너는 fully typed:
list[T],dict[K, V],tuple[int, str]/tuple[int, ...]. Optional회피 — 빈 값으로 초기화하는 게 우선. 정말 필요하면X | None.- runtime validation 에
assert금지 (python -O로 stripped). →if ...: raise ValueError(...).assert는 programmer error 잡는 invariant 체크 한정.
4. Docstring (§3)
대상: public 함수/메서드, 모듈-level helper, 긴 private helper. 짧고 자명한 class-private helper, no-behavior override 는 short docstring OK.
Full docstring 구성:
- Summary (한 문장)
- Details — thread safety, invariants, 호출 전제
- Args — 타입 + 제약 (예: "
keys와values길이 같아야 함") - Returns
- Raises
- Note — 비자명한 가정/caveat
docstring 은 "현재" 동작과 정확히 일치해야 함. 함수 수정 시 docstring 동시 업데이트. no-op 파라미터는 그렇다고 명시.
5. 함수/인터페이스 설계 (§4)
- 함수명은 self-explanatory. predicate/filter 는 의미가 드러나도록 (
key_eligible_filter). - private 멤버는
_prefix. - 자기-완결성: 다른 함수의 출력이 입력으로 전제되면 docstring 에 명시.
- 모호한 반환값 금지 — 예:
None이 "미완료"와 "없음" 둘 다 의미하면 안 됨. 타입 분리 또는 exception. - bool 파라미터 금지 → enum 또는 함수 분리.
- dict/복합 컨테이너 파라미터는 schema 문서화.
- caller assumption (lock 보유, main thread 등) 은 docstring 에 명시.
클래스 설계
- public surface 최소화 — 신규 public method/property 는 구체적 필요가 있을 때만.
- 내부 state field 에는: 명확한 의미 + invariant + docstring/inline 주석.
- 다른 클래스의
_멤버 절대 접근 금지 (SLF rule).- CI 강제 범위:
lmcache/v1/multiprocess/,lmcache/v1/distributed/. - 그 외에도 프로젝트-wide 컨벤션 — 신규/수정 코드는 모두 준수.
- CI 강제 범위:
- 중복 필드보다
@property로 derive 선호. - config dispatch 는
isinstance()사용, 문자열 type name 비교 금지. - Controller/Manager 는 빈 config 라도 항상 생성 —
Optional으로 감싸지 말 것.
6. 기존 코드 수정 — Caller Impact Analysis (§6.2) ⚠️
가장 자주 빠뜨리는 부분. 다음 변경 시 모든 caller 전수조사:
- 파라미터 추가/제거/이름변경/순서변경, 타입/default/허용 도메인 변경
- 반환 타입/의미/sentinel 변경 (예:
None의 의미) - raise 하는 exception 변경
- side effect, ordering guarantee, thread-safety, blocking 동작 변경
- public field 의 invariant 변경
- base class / protocol 의 public method 변경 (subclass 도 caller)
조사 범위:
- 모든 production 코드
tests/전체- docs/examples snippet
lmcache/integration/(vLLM, SGLang, TRT-LLM 어댑터)
원칙:
- 같은 PR 에서 caller 도 함께 수정. "나중에 고치겠다" 금지.
- backwards-compatible extension (새 파라미터 + default, optional 반환 필드) 을 break 보다 선호.
- 의심되면 한 caller 라도 더 읽어보기 — 읽는 비용은 작고, 누락된 latent bug 의 비용은 큼.
7. 신규 기능 (§5)
Design doc
- Non-trivial 한 기능/아키텍처 변경에는 design doc 필수.
- 위치:
docs/design/가lmcache/패키지 트리를 그대로 미러.- 예:
lmcache/v1/distributed/l2_adapters/→docs/design/v1/distributed/l2_adapters/. - 여러 sibling 을 묶는 doc 은 공통 parent 디렉터리에 둠.
- 예:
- 파일명은 descriptive (
overall.md,l2_eviction.md등) — 모듈 파일명 미러링 X. - 모듈
README.md는 코드 옆에 두고docs/design/에서 symlink — 옮기지 말 것. - 전체 컨벤션:
docs/design/README.md.
Test
- 모든 신규 feature 는 unit test 필수.
- 모든 bug fix 는 regression test 필수.
- 테스트는 public interface + docstring contract 기준 — 구현 detail 검증 금지.
- 테스트 코드도
_멤버 접근 금지. - 파일 구조는
tests/아래서 source 와 미러.
재사용
- 새 함수/state 추가 전 reuse 가능한 기존 코드/state 가 있는지 먼저 확인.
8. 코드 조직 & 스타일 (§7)
헤더 / Import
- 모든 .py 첫 줄:
# SPDX-License-Identifier: Apache-2.0 - Import 순서 (헤딩 주석 필수):
# Standardimport os# Third Partyimport torch# First Partyfrom lmcache.v1.config import LMCacheEngineConfig# Localfrom .utils import helper
- lazy import 금지 — 모두 파일 상단.
lmcache.c_ops등 native ext 사용 시import torch를 먼저.
파일/클래스 레이아웃
- 모듈-level helper: 파일 상단 (import 다음, 클래스 전).
- 클래스 내 private/helper method: 클래스 끝 (public method 뒤).
- 파일이 길어지면 모듈로 분리.
Logging (§7.4)
lmcache.logging.init_logger(__name__)사용. barelogging.getLogger()금지.- 운영성 로그 (store/retrieve, 백그라운드 진행) 는 DEBUG — INFO 아님.
- 정상 동시성에서 발생할 수 있는 상황 (예: benign race 로 key not found) 에 WARNING 사용 금지.
Error / Resource (§7.5–7.6)
- runtime validation:
if/raise(assert 금지). - 실패 경로에서 inconsistent state 남기지 말 것 — lock 해제, pool entry free, fd close, partial state cleanup.
- unbounded collection 금지 (memory leak). 자라는 set/dict 는 대응 리소스 free 시 entry 도 cleanup.
- CUDA/GPU 리소스는 allocate/free/sync 명시적으로.
- hot path 에서 불필요한 memcpy/alloc 금지.
9. Thread Safety (§8)
- 공유 state 는 적절한 lock 으로 보호.
- granularity 적절히 (너무 coarse → 무관 op 블로킹, 너무 fine → 동기화 누락).
- test/debug method 도
self._lock보유. - 여러 controller thread (StoreController + PrefetchController 등) 가 같이 도는 코드는 concurrent access 안전성 확인.
- 가장 단순한 정답에서 시작. thread/lock/queue 는 구체적 필요가 있을 때만 도입.
10. Lint / Test / Docs 명령
# Lint (CI 와 동일)
pre-commit run --all-files
# 개별 도구
ruff check . # E, F, B, SLF
ruff format . # line-length 88
isort . # black profile, from_first=true
mypy --config-file=pyproject.toml
codespell --toml pyproject.toml
# Test 표준 suite (CI mirrors)
pytest -xvs --ignore=tests/disagg \
--ignore=tests/v1/multiprocess/ \
--ignore=tests/v1/distributed/ \
--ignore=tests/skipped \
--ignore=tests/v1/storage_backend/test_eic.py
# Docs (warning 없이 통과해야 함)
cd docs && make clean && make html
- C++/CUDA: clang-format Google style, 80-col.
- Rust (
rust/):cargo fmt+cargo clippy. - pytest marker:
@pytest.mark.no_shared_allocator— shared-allocator monkeypatch 해제.
11. 리뷰 프로세스 (§9)
리뷰 focus
- Design / 아키텍처 적절성
- Correctness — logic, error path, resource, edge case
- Caller impact (global view) — §6.2
- Thread safety
- 가독성/모듈성/네이밍
- Docstring + design doc + user doc
- Test coverage (특히 failure path, concurrency)
- Design doc 과 구현 일치 여부
리뷰에서 다루지 않는 것
- 보안 이슈 (대부분 PR 의 scope 밖)
- 린터가 잡는 trivial style
- 변경되지 않은 코드의 무관 refactor (단, 변경된 symbol 의 caller 인 경우는 예외)
Severity
| Severity | 의미 | 예시 |
|---|---|---|
| error | merge 전 fix 필수 | SPDX 누락, public 함수 type hint/docstring 누락, test 0개 신규 feature, cross-class private 접근, 모호한 반환값, runtime assert, caller 깨진 채 둔 breaking change |
| warning | 고치는 게 좋음 | docstring 부실, 구현-detail 테스트, 네이밍 모호, 모듈성 부족, parallel list zip 에 strict=True 누락, caller 가정 약화 후 미감사 |
| info | 제안, non-blocking | 네이밍 개선 제안, minor 리팩터, style 선호 |
Reviewer 가이드라인
- diff 안의 라인만 리뷰. 변경되지 않은 코드 이슈 보고 X (caller 예외).
- 칭찬 X. clean 하면 그렇다고만.
- padding 금지. 모호하면
info로 표시. - file:line 정확히.
리뷰 출력 포맷
- PR 요약 한 줄
- 관련 design doc 있으면 compliance 표 (requirement / pass-fail / notes)
- Severity 별 이슈 (
error→warning→info) - 마무리 표: severity / count / 핵심 항목
12. DCO & CoC
- DCO v1.1: 본인 작성 또는 적절한 OSS 라이선스 권리 보유를 인증. 모든 커밋
Signed-off-by:필수. - Code of Conduct: Contributor Covenant 기반. harassment-free, inclusive 유지.
13. PR 제출 전 self-check (압축본)
[ ] PR 이 작고 한 가지 목적인가
[ ] pre-commit run --all-files 통과
[ ] 모든 public 함수에 type hint + 완전한 docstring
[ ] SPDX 헤더, import 순서 컨벤션
[ ] cross-class private 접근 없음
[ ] bool 파라미터 / 모호한 반환값 없음
[ ] runtime 에서 assert 안 씀
[ ] 시그니처/의미 변경 시 caller 전수조사 (tests + integration 포함)
[ ] 신규 feature → test, bug fix → regression test
[ ] design doc 필요 시 작성 (경로: lmcache 트리 미러)
[ ] user-facing 변경 시 docs/source/ 업데이트, Sphinx build clean
[ ] DCO sign-off (-s)
자주 PR 리젝되는 포인트 Top 3
- PR 이 너무 큼 — 모듈/단계로 분할.
- Caller impact 분석 누락 —
tests/,lmcache/integration/까지 같이 수정. - Docstring 이 현재 동작과 불일치 — 코드 수정 시 docstring 동기화 빠뜨림.