# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
*.so

# Distribution / packaging
build/
dist/
*.egg-info/
.eggs/

# Virtual environments
.venv/
venv/
env/

# Testing / coverage
.pytest_cache/
.coverage
.coverage.*
coverage.xml
htmlcov/
.hypothesis/
.benchmarks/

# Type checking / linting
.mypy_cache/
.ruff_cache/

# Docs
/site

# IDE
.vscode/
.claude/
.idea/

# Secrets & local config — NEVER commit these.
# A Coolify root token can read every secret of every project in the team.
.env
.env.*
!.env.example
!.env.template
.pypirc

# Runtime state. Migration journals contain resource UUIDs and host addresses;
# they belong in the user state dir (platformdirs), never in the repo. This entry
# only catches accidental --state-dir=. runs.
/state/
*.journal.jsonl

# Integration rig: throwaway keys, generated on demand by
# tests/integration/prepare.py. They authorise nothing but two local containers,
# but a key in git is a key in git.
tests/integration/keys/

# ── e2e rig artefacts ───────────────────────────────────────────────────────
# Minted per run and every one of them is a credential. The rig is reproducible
# from prepare.py + bootstrap.py, so there is nothing here worth keeping.
tests/e2e/keys/
tests/e2e/rig.json
tests/e2e/coolify.env
tests/e2e/.probe.json

# Lockfile — deliberately absent, not merely unwritten
# ---------------------------------------------------
# Nothing here would read it. All three CI workflows install with
# `pip install -e ".[dev]"`, consumers get a PyPI wheel and resolve the ranges in
# pyproject.toml themselves, and even our own setup instructions use `uv pip
# install`, which is the pip-compatible interface and ignores a lock (only
# `uv sync`/`uv run` consume one).
#
# A lock nothing consumes is worse than none: it claims a reproducibility that
# does not exist, and it is a second source of truth beside pyproject.toml that
# drifts in silence. Dependabot already maintains the pip ecosystem weekly from
# pyproject; a lock would need its own update path or quietly fossilise.
#
# To reverse this, the lock is the small part — the work is consuming it: move
# the workflows to `uv sync --locked`, add setup-uv, and arrange for the lock to
# be updated. Committing a lock while CI still runs pip is the worst of both:
# all of the cost, none of the benefit.
uv.lock
