# --- Python -----------------------------------------------------------------
__pycache__/
*.py[cod]
*.egg-info/
.eggs/
.installed.cfg
dist/
sdist/
.venv/
venv/
env/
.python-version

# --- Test / type / lint caches ----------------------------------------------
.pytest_cache/
.hypothesis/
.mypy_cache/
.ruff_cache/
.coverage
.coverage.*
coverage.xml
htmlcov/
*.gcda
*.gcno
*.gcov

# --- CMake / native build ----------------------------------------------------
build/
# Every workflow builds into its own directory beside build/: build-tests,
# build-assert, build-bench, build-fastmath, build-asan, build-tsan. Only
# `build/` was ignored, so running any command from ci.yml or sanitizers.yml
# as documented left an untracked tree in `git status`.
build-*/
_skbuild/
CMakeUserPresets.json
compile_commands.json
*.o
*.obj
*.a
*.lib
*.exp
*.ilk
*.pdb

# Built extension modules land in the package tree; never commit them.
src/tfidf_stability/_native/*.pyd
src/tfidf_stability/_native/*.so
src/tfidf_stability/_native/*.dylib

# --- Data --------------------------------------------------------------------
# MovieLens may NOT be redistributed (see data/README.md). Fetched, never committed.
data/raw/
data/interim/
data/processed/
data/external/
!data/README.md
!data/assets/
!data/lexicon/

# Figures ARE committed. They are renderings, and matplotlib stamps its version
# into every PNG, so the bytes depend on the plotting library rather than on the
# result: two people regenerating from identical JSON get different files. That
# argued for keeping them out, and for a while they were.
#
# It was the wrong trade. reports/text/main.tex embeds seven of them, so a fresh
# clone built the report with seven "figure not generated" boxes, and the results
# were invisible to anyone reading the repository rather than running it. A
# figure nobody can see is worth less than a figure whose bytes are not
# reproducible. The JSON beside them is the reproducible artefact and the digest
# in each caption ties the image back to it, so the provenance claim survives.
#
# Consequence to know about: a regenerated PNG shows as modified whenever
# matplotlib changes, even with the underlying result identical. Check the digest
# in the caption, not the bytes.

reports/*.csv
!reports/text/

# The experiment JSON *is* committed, deliberately. A figure or a quoted number
# whose underlying data is absent from the tree is an assertion nobody can check,
# which is the one thing this repository is built not to be. Each file carries
# its own result digest and the provenance of the run that produced it, so a
# reader can regenerate it and compare rather than take it on trust.

# --- LaTeX -------------------------------------------------------------------
*.aux
*.bbl
*.blg
*.fdb_latexmk
*.fls
*.lof
*.log
*.lot
*.out
*.synctex.gz
*.toc
reports/text/*.pdf

# --- Notebooks ---------------------------------------------------------------
.ipynb_checkpoints/

# --- Editors / OS ------------------------------------------------------------
.vscode/
.idea/
*.swp
.DS_Store
Thumbs.db
