# Python
__pycache__/
*.py[cod]
*$py.class
*.so
*.egg-info/
*.egg
dist/
build/
*.whl

# Agents
.spec/archive/
.spec/scrutiny-reports/
.spec/verification-reports/
.spec/proposals/
.spec/plans/
.spec/.agentic-coding
.spec/STATE.md
# A one-hour spec-gate bypass token, not a repository artifact. The *ledger* of
# uses (.spec/exemptions.log) is committed and is the real mitigation; the token
# itself is per-session, and committing it would hand everyone else a live
# bypass. Ignored because the documented escape hatch otherwise sits in
# `git status` waiting to be added by accident.
.spec/EXEMPT
.opencode/


# Virtual environments
.venv/
venv/
ENV/

# Testing
.coverage
.pytest_cache/
htmlcov/
.hypothesis/
snapshot_report.html
_*_result*.txt
_debug.txt
_tui_debug.txt
_tui_eval_debug.txt

# IDE
.idea/
*.swp
*.swo
*~
*.code-workspace

# Coding-agent tooling state (guards — these dirs are not part of the repo)
.kiro/
.moai/

# OS
.DS_Store
Thumbs.db

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

# Agent scratch space (test output, temp scripts)
tmp/

# Local-only files (not for the repo)
*.local.md
*.local.*

# Personal notes
HUMAN_NOTE.md

# Distribution
dist/

# Documentation site build output
site/

# uv
.python-version
.functualize/cache.json
.functualize_cache.json
.todos/
.sidecar/
.sidecar-agent
.sidecar-task
.sidecar-pr
.sidecar-start.sh
.sidecar-base
.td-root
.functualize/
# ...except the committed example plugin, which the blanket rule above swallowed.
# Git will not descend into an excluded directory, so every level must be un-excluded
# in turn, and each level re-ignores its own contents so that only the plugin sources
# become trackable — never the cache, state or lock files a run drops beside them.
!examples/plugins/file_based_plugin/.functualize/
examples/plugins/file_based_plugin/.functualize/*
!examples/plugins/file_based_plugin/.functualize/plugins/
examples/plugins/file_based_plugin/.functualize/plugins/*
!examples/plugins/file_based_plugin/.functualize/plugins/*.py
.import_linter_cache/
.mypy_cache/
.pytest_cache/
.ruff_cache/

# OmO / OpenCode agent run-continuation scratch state
.omo/
.mcp.json

# Internal pre-release audit reports (contain session IDs / local infra notes)
.release/
.worktrees/
.claude/settings.local.json

# Agent index directories. Which parts are tracked is decided by ONE property:
# whether the stored paths are portable.
#
#   graphify  graph.json holds only repo-relative paths, so it travels into every
#             worktree and every ephemeral cloud checkout for free. Tracked.
#             Its cache/, manifest.json and .graphify_root are machine-local
#             (mtimes, absolute paths), so the rule below is a whitelist: ignore
#             everything, then un-ignore the two portable artifacts.
#   zvec-grep index entries are keyed by ABSOLUTE path — copying one and rewriting
#             its manifest yields 0% coverage and a full re-embed. Never tracked;
#             each workspace builds its own (~21s scoped).
#   serena    cache/ pickles hold absolute file:// URIs, so those and
#             project.local.yml are machine-local; serena's own
#             .serena/.gitignore already excludes cache/ and project.local.yml.
#             memories/ is plain text and portable, but not tracked anyway: it
#             duplicated contract docs that already have a committed home
#             (`.claude/rules/spec-workflow.md`, `.spec/ARCHITECTURE.md`,
#             AGENTS.md) and went stale the moment those changed underneath
#             it. project.yml stays tracked and portable.
graphify-out/*
!graphify-out/graph.json
!graphify-out/GRAPH_REPORT.md
.zvec-grep/
.serena/cache/
.serena/project.local.yml
.serena/memories/
