본문으로 건너뛰기

LMCache Contribution 룰 정리

PR 작성/리뷰 시 빠르게 참고하기 위한 한국어 요약. 원본은 다음 5개 문서:

  • CONTRIBUTING.md — 기본 절차, 환경, 테스트
  • AGENTS.md — 자기-검수 체크리스트 (docs/coding_standards.md 의 quick-reference)
  • docs/coding_standards.mdcanonical reference (§1 ~ §10)
  • DCO — Developer Certificate of Origin v1.1
  • CODE_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 구성:

  1. Summary (한 문장)
  2. Details — thread safety, invariants, 호출 전제
  3. Args — 타입 + 제약 (예: "keysvalues 길이 같아야 함")
  4. Returns
  5. Raises
  6. 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 컨벤션 — 신규/수정 코드는 모두 준수.
  • 중복 필드보다 @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 어댑터)

원칙:

  1. 같은 PR 에서 caller 도 함께 수정. "나중에 고치겠다" 금지.
  2. backwards-compatible extension (새 파라미터 + default, optional 반환 필드) 을 break 보다 선호.
  3. 의심되면 한 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 순서 (헤딩 주석 필수):
    # Standard
    import os

    # Third Party
    import torch

    # First Party
    from lmcache.v1.config import LMCacheEngineConfig

    # Local
    from .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__) 사용. bare logging.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

  1. Design / 아키텍처 적절성
  2. Correctness — logic, error path, resource, edge case
  3. Caller impact (global view) — §6.2
  4. Thread safety
  5. 가독성/모듈성/네이밍
  6. Docstring + design doc + user doc
  7. Test coverage (특히 failure path, concurrency)
  8. Design doc 과 구현 일치 여부

리뷰에서 다루지 않는

  • 보안 이슈 (대부분 PR 의 scope 밖)
  • 린터가 잡는 trivial style
  • 변경되지 않은 코드의 무관 refactor (단, 변경된 symbol 의 caller 인 경우는 예외)

Severity

Severity의미예시
errormerge 전 fix 필수SPDX 누락, public 함수 type hint/docstring 누락, test 0개 신규 feature, cross-class private 접근, 모호한 반환값, runtime assert, caller 깨진 채 둔 breaking change
warning고치는 게 좋음docstring 부실, 구현-detail 테스트, 네이밍 모호, 모듈성 부족, parallel list zipstrict=True 누락, caller 가정 약화 후 미감사
info제안, non-blocking네이밍 개선 제안, minor 리팩터, style 선호

Reviewer 가이드라인

  • diff 안의 라인만 리뷰. 변경되지 않은 코드 이슈 보고 X (caller 예외).
  • 칭찬 X. clean 하면 그렇다고만.
  • padding 금지. 모호하면 info 로 표시.
  • file:line 정확히.

리뷰 출력 포맷

  1. PR 요약 한 줄
  2. 관련 design doc 있으면 compliance 표 (requirement / pass-fail / notes)
  3. Severity 별 이슈 (errorwarninginfo)
  4. 마무리 표: 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

  1. PR 이 너무 큼 — 모듈/단계로 분할.
  2. Caller impact 분석 누락tests/, lmcache/integration/ 까지 같이 수정.
  3. Docstring 이 현재 동작과 불일치 — 코드 수정 시 docstring 동기화 빠뜨림.