apiVersion: conventions/v1 version: 0.1.0 updated: "2026-06-29" name: code_standards title: Python code standards scope: py status: active summary: uv + hatchling, src layout, mypy strict, ruff, async-all-the-way, Pydantic v2 at boundaries, structured logging. Proven across v2 lilith Python packages. appliesTo: ["**/*.py"] rules: - id: toolchain level: must text: "uv (deps/venv) + hatchling (build); ruff (lint+format); mypy. Never substitute (no poetry/pip/black/flake8)." - id: src_layout level: must text: "src// layout (e.g. src/lilith_foo/), never a flat top-level module." - id: mypy_strict level: must text: "mypy strict:true; full type annotations; no `Any` (use precise types / protocols / TypedDict)." - id: async_all_the_way level: should text: Don't mix sync and async; async from the entrypoint down. No blocking calls in async paths. - id: pydantic_boundaries level: should text: Pydantic v2 models validate data at system boundaries (API/IO); plain dataclasses/types internally. - id: logging level: must text: "No print() in library code. logging.getLogger(__name__); lazy %-formatting (logger.info('x=%s', x)), not f-strings in log calls." - id: specific_exceptions level: must text: "Catch the specific exception expected; never bare `except:` or `except Exception: pass`. Chain with `raise ... from exc`." - id: no_dead_code level: must text: "Delete unused code; no commented-out blocks, no `# type: ignore` without a code+reason."