Skip to content

Contributing#

$ uv sync
$ scripts/check.sh          # every gate CI runs
$ uv run pytest -n auto     # the fast tier (about 10 seconds)
$ uv run pytest -m nightly  # real-library corpus and a 1500-program fuzz campaign
$ scripts/mutation.sh       # mutation testing of the analysis core

Quality gates#

Every change must pass all of these:

Gate Tool
Formatting, and every lint rule (with a short, justified ignore list) ruff format, ruff check with select = ["ALL"]
Types, checked twice pyright strict (plus override, cycle and unnecessary-ignore checks), mypy --strict
Tests pytest with warnings as errors, strict markers and config, random order, timeouts
Branch coverage ≥ 96% coverage, including CLI subprocesses
Mutation kill rate ≥ 99% (nightly) mutmut on the effects rules, class analysis and shaker
No dead code vulture, and a test that shaking shakeout removes nothing
Spelling, pyproject.toml schema codespell, validate-pyproject
Packaging uv build, twine check --strict, check-wheel-contents, install smoke test
Supply chain and workflows pip-audit, zizmor (pedantic), actionlint, SHA-pinned actions
Docs mkdocs build --strict, plus tests that every CLI flag and config key is documented

Adding a case#

Behavior is specified by .case files in tests/cases/: a TOML header with expectations, then === path sections with the program. Run uv run pytest --update-goldens, then review the generated .golden report like code.