__pycache__/
*.pyc
*.egg-info/
dist/
build/
.venv/

# Tool caches
.mypy_cache/
.pytest_cache/
.ruff_cache/

# Wrought runtime
.wrought/
.claude/bridge/
.claude/scheduled_tasks.lock
# Loop-state temps. Publish-by-rename needs a per-invocation unique name, so an
# interrupted write (SIGKILL only -- the EXIT trap and the helper's unlink cover the
# rest) leaves a uniquely-named sibling instead of the one self-limiting `.tmp`.
/.claude/wrought-loop-state.json.*

# Coverage
.coverage
htmlcov/

# macOS
.DS_Store

# Environment
.env
.env.local
.env.watchdog

# Session handoff (local-only, not project documentation)
NEXT_SESSION_PROMPT_*.md
SESSION_SUMMARY_*.md
docs/archive/sessions/
tools/redaction_sweep_2026-05-07/

# Agent-memory: local learning, never committed (GH #174)
.claude/agent-memory/
.claude/agent-memory-local/
.codex/agent-memory/
.claude/agents/*/MEMORY.md

# Archives: never tracked. Their contents are invisible to git grep and to every
# text-based control in this repo (F1, S149).
#
# These patterns match SPELLINGS ONLY and are therefore incomplete BY CONSTRUCTION:
# .gitignore cannot express content matching, so an OOXML file (.docx/.pptx -- a ZIP
# container) is not matched by anything below. Ten such files are tracked today. The
# authority is tests/test_archive_hygiene.py, which classifies by MAGIC BYTES and
# requires every tracked archive to be explicitly declared. Treat this block as a
# convenience that stops the common accident, never as the guarantee.
*.zip
*.tar
*.tgz
*.tbz2
*.7z
*.rar
*.gz
*.bz2
*.xz
