# Python
__pycache__/
*.py[cod]
backend/.venv/
backend/*.db
backend/.pytest.db
# Bare too: pytest writes it to whatever directory it is invoked from, and a 0.7 MB
# SQLite file reached main from the repo ROOT, where the backend-scoped line above
# did not cover it (GRPH-428's branch, merged as #267). It fails
# `test_no_tracked_control_bytes` on main and therefore on every PR built against it.
.pytest.db
.pytest.db-journal
# The concurrency lock GRPH-554 added sits beside the database it guards, and xdist gives
# each worker its own — so the pattern has to cover `.pytest_gw3.db.lock` as well as the
# bare one. Untracked litter in `git status` is how a real change gets missed in the noise.
*.db.lock
# Same trap, same fix: scripts/docs_completeness.py opens a throwaway SQLite
# database in whatever directory it is run from (GRPH-475).
.docscheck.db
.docscheck.db-journal
backend/.pytest_cache/
# graphban-fleet is a separate distribution with its own venv (PRD-22 D-e). `uv` drops a
# self-ignoring .gitignore inside .venv/, but naming it here means the repo does not
# depend on that convenience holding.
fleet/.venv/
fleet/.pytest_cache/
*.egg-info/

# Node
web/node_modules/
web/dist/
web/.vite/
web/*.tsbuildinfo

# Env
.env
.env.local

# Drive sync target (runtime data / mounted volume)
sync/

# Compose apply helper socket dir (docker-compose default mount)
.graphban-apply/

# Packed native/GitHub release trees (scripts/graphban_release.py publish)
dist-release/

# OS / editor
.DS_Store

# Tooling
.serena/

# Cursor MCP config — holds a real API key; copy .cursor/mcp.json.example instead
.cursor/mcp.json

# Project MCP config — holds a real API key
.mcp.json

# Cursor claim manifest — per-session runtime state (see .cursor/hooks/README.md)
.cursor/graphban-claim.json
.cursor/agentledger-claim.json
