Lint (ruff) and test (pytest, fail under 80% coverage) on every PR and push to main/dev. On a merge to main/dev, build the sdist+wheel and publish to the Gitea PyPI registry — main as a clean release, dev as a unique .devN pre-release. No Docker; runs on uv. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>