
# Python
__pycache__/
*.py[cod]
*$py.class

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

# Virtual Environment
.venv/
venv/
ENV/

# Testing
.pytest_cache/
.coverage
coverage.xml
htmlcov/

# Format
.mypy_cache/
.ruff_cache/

# Environment
.env
.env.local
.env.*.local

# Storage (user uploads)
storage/

# PDFs (except test data)
*.pdf
!frontend/e2e/fixtures/*.pdf
!tests/data/*.pdf
!backend/tests/data/*.pdf

# Sensitive
sensitive/

# Windows artifacts
nul

# Project Specific
tests/examples_output/
backend/tests/examples_output/
!tests/data/sample.pdf
!backend/tests/data/sample.pdf
*.log
.DS_Store

# AI
.claude/
.gemini/

# Astro / Site
site/node_modules/
site/dist/
site/.astro/
# Review run state: megabytes of transcript per round, written by `dotf spec
# review`, never part of a spec's contract. Ignored for ACTIVE specs too, not only
# archived ones -- the archive rules below were the only ones here, and a directory
# add silently staged 2.5 MB of it twice in one session.
#
# `review-request.json` is deliberately NOT ignored while a spec is active:
# `dotf spec review` refuses to launch when git ignores it, because `spec archive`
# reads the contract digests it records and that evidence has to exist in any
# other checkout. The archive rules below cover the copies that outlive a spec.
specs/*/review-transcript.jsonl
specs/*/review-transcript.jsonl.stderr
specs/*/review-second-transcript.jsonl
specs/*/review-second-transcript.jsonl.stderr
specs/archive/*/review-transcript.jsonl
specs/archive/*/review-transcript.jsonl.stderr
specs/archive/*/review-second-transcript.jsonl
specs/archive/*/review-second-transcript.jsonl.stderr
specs/archive/*/review-request.json
specs/archive/*/review-second-request.json
