This document codifies the standard for all work on the subsystem. Every change is born compliant — nothing gets "documented later".
- Branch from
develop:feature/<descriptive-name>for features,chore/<name>for cross-cutting work. - Atomic Conventional Commits: a semantic prefix (
feat:,fix:,refactor:,test:,docs:,build:,chore:,style:), an imperative subject of at most 50 characters with no trailing period, context in the body, and issue/PR references when they exist. One commit = one coherent logical change. - Once complete and verified: merge into
developwith--no-ff(after maintainer sign-off). A stable milestone =develop→mainplus a version tag. - Forbidden:
push --force, deleting branches, or rewriting history without explicit authorization.
- Python ≥ 3.12, environment managed with
uv(uv venv --python 3.12 && uv pip install -e ".[dev]"). - Complete type hints;
mypy --strictclean (also applies totests/). - Pydantic only at process boundaries; internal objects use
@dataclass(frozen when they are value objects) — see ADR-0003. - Composition and dependency injection over inheritance; interfaces via
Protocol. - Specific exceptions with actionable messages; validate at the edges, fail early.
- Pure computation separated from I/O;
logging(neverprint) outside CLI entry points. - All randomness through an injectable RNG with a configurable seed (reproducible determinism).
- No secrets or absolute paths in code; configuration via
.env(git-ignored).
tests/mirrorssrc/; test data is generated synthetically (never external files or network access).- Coverage ≥ the current threshold in
pyproject.toml(it rises with the project, never falls). - Warnings in tests are errors; every filter exception is documented with its reason.
Mandatory in the same change as the code (same PR/branch, never "at the end"):
- PEP 257, Google-style docstrings on all new public API (
Args:/Returns:/Raises:/Example:where it helps); a module docstring in every new file. - Update
README.md,docs/architecture.mdandCHANGELOG.mdwhenever the change affects what they describe. - A new ADR (
docs/adr/ADR-XXXX-*.md) whenever the change introduces an architecture decision; ADRs are never edited, they are superseded. - If the contract changes (only via a new version): regenerate
docs/payload-schema-v1.json— the anti-drift test demands it.
ruff check . && ruff format --check . # style
mypy # types (strict, src + tests)
pytest # tests + coverage threshold
mkdocs build # documentation buildsAll four green, or there is no merge.