# Python
__pycache__/
*.py[cod]
*.egg-info/
.eggs/
build/
dist/
# ... except the download service deckname-dist (its own container, dist/README.md).
!/dist/
/dist/import/
*.so

# Virtual environments / uv
.venv/
venv/

# Environment / secrets
.env
.env.*
!.env.example

# Test / coverage / type-check caches
.pytest_cache/
.mypy_cache/
.ruff_cache/
.coverage
htmlcov/

# Model caches (HF, spaCy, flair, GLiNER)
models/
# ...but not the package that fetches them (the manifest, downloader and model state).
!src/deckname/models/
.cache/
*.bin
*.pt
*.safetensors

# IDE / OS
.idea/
.vscode/
.DS_Store
Thumbs.db

# Benchmark output (scripts/bench_engines.py, scripts/bench_leaks.py, scripts/bench_anonymize_latency.py)
bench_results.json
leak_results.json
bench_anonymize_latency.json

# Frontend: SPA deps + built bundle are never committed — the bundle is
# produced by `npm run build` / the Docker build stage into the Python package.
frontend/node_modules/
# Unanchored, so it also catches a node_modules/ dropped at the repo root by a
# tool invoked from there rather than from frontend/.
node_modules/
src/deckname/webui/

# fs-orchestrate transient worktrees
.worktrees/

# M72 UAT demo store (scripts/uat.py) — a seeded, persistent SQLite store of
# SYNTHETIC German demo data. Disposable (`--reset` re-seeds it) and never committed.
uat-data/

# The store `.env`'s own `DECKNAME_DB_PATH=./data/deckname.db` points here, so a UAT run
# (and, until the suite stopped reading that file, a test run) writes a SQLite store into
# the checkout. Untracked it is still a DIRTY TREE, and `merge.js` refuses `DIRTY-TREE` on
# any uncommitted change in the primary checkout -- so one un-ignored demo database stalls
# every milestone merge in the repository, which is why this rule is not cosmetic.
data/

# `data/` (above) has no leading slash, so it also matches `tests/data/` -- which is NOT the
# UAT store, it is M78-T07's committed detection-eval baseline
# (`tests/data/eval_baseline.json`, tracked and honest). Un-ignore that one directory rather
# than re-anchoring the UAT rule, so a future `tests/data/*` addition stays tracked by default.
!tests/data/
# The same for the package's shipped data: the evidence calibration table (counts only, plan
# 2026-10-03-belegregeln M6) is tracked.
!src/deckname/data/
!tests/data/*

# M72 UAT tester scratch files — the script tells the tester to create these by
# hand during a run (block 1's sample text, block 2's request bodies, the hook
# payloads of blocks 4/5 and 10). They are synthetic, but they are working files
# of one run, not repository content.
uat-demo.txt
uat-anfrage.json
uat-eingehend.json
uat-ausgehend.json
uat-initialize.json

# /design-sync (claude.ai/design): staged converter, build output, machine state.
# The durable inputs under .design-sync/ (config.json, NOTES.md, conventions.md,
# previews/, overrides/) ARE committed; everything below is regenerated.
.ds-sync/
ds-bundle/
.design-sync/.cache/
.design-sync/learnings/
.design-sync/node_modules
# (`frontend/ds-tailwind.css` was ignored here while the retired app built a
# Tailwind sheet. The rewrite is plain CSS — see frontend/vite.config.ts — so
# nothing produces that file; retired in M1-web-cutover.)

# Working material (reports, reviews, spikes, drafts) lives in the sibling repository
# ../deckname-planning (CLAUDE.md, "Working material"); a planning/ folder here is never committed.
planning/

# Deckname design — BUILD OUTPUTS, never sources.
# `screens/*.html` and the preview walk-through both come from `build_templates.py`; the
# editable sources are `screens/_src/*.html`. They were committed by accident at aca29a6a
# and went red on a fresh checkout. (This comment used to name the test that caught it;
# that file does not exist in this repository and the citation was removed rather than
# left pointing at nothing.)
# Rebuild:  cd design/legacy-screens && uv run python build_templates.py --preview ../../design-preview
design/legacy-screens/screens/*.html
design-preview/

# M21-keycloak-broker-compose-overlay: the self-signed cert/key examples/keycloak/README.md's
# command generates for the Keycloak recipe overlay — developer-local material, never committed.
examples/keycloak/certs/

# Playwright's per-run artifacts. `@playwright/test` IS a declared devDependency and is
# required to be one: it is the renderer the design gate's rendered lane probes for
# (`tests/test_design_capture.py::test_the_renderer_is_a_declared_dependency`), and
# `frontend/scripts/capture-screens.mjs` drives it. Running it here writes this directory.
test-results/

# UAT runs (scripts/uat_run.py): per-cell data dirs, logs, traces, reports.
uat-runs/
uat-runs-archive/
