# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
# Exception: brand/dist/ is generated but COMMITTED. Apps read it in place, and
# brand/build.py --check (run by packages/core/tests/test_brand.py) compares it
# with tokens.json, so a checkout without it fails pytest (ADR-088).
!brand/dist/
# Exception: the Next.js apps' source lib dirs (beat-state, funnel helpers,
# console types) are real source, NOT Python build artifacts — the `lib/` rule
# above over-matches them and silently excluded them from the #21 import. Keep
# tracked. The paths moved under apps/ in the ADR-050 migration; the stale
# `web/app/lib/` exception stopped matching, which is why every tool that reads
# .gitignore (prettier among them) skipped those files.
!apps/web/app/lib/
# Same over-match, second victim: the partner console's source lib dir. Its
# three existing files predate ADR-050 step 5 and stay tracked because gitignore
# does not evict tracked files — but every NEW file added there was silently
# invisible to `git add`, which is how a source file can be written, built,
# tested, and then simply not exist in the commit. Found while adding
# `lib/csp.ts`.
!apps/managed/web/lib/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
coverage/
*.cover
*.py.cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Environments
.env
.envrc
# Per-worktree dev-port assignment (scripts/new-worktree.sh). Not .env — that
# name is owned by the mission-env remediation, which deletes it on sight.
.flatland-dev-port
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# PEP 582
__pypackages__/

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# Ruff
.ruff_cache/

# PyPI configuration file
.pypirc

# IDE
.idea/
.vscode/
*.swp
*.swo
*~

# Cursor
.cursorignore
.cursorindexingignore

# Claude Code. The harness is COMMITTED; only per-machine state is ignored.
#
# This was a blanket `.claude/` ignore. The stated reason — agent memory must
# never live in the repo — is still right, and the four rules below still
# enforce it. But the blanket form also made settings, hooks, generated agents
# and commands uncommittable, which meant the harness could not be reviewed,
# could not be gated by CI, and could not be shared with another machine or
# another agent runtime. A rule that ignores state and configuration alike
# cannot tell the difference between the thing that must not be shared and the
# thing whose whole purpose is to be shared.
#
# Committed (see AGENTS.md): .claude/settings.json, .claude/hooks/,
# .claude/agents/ (GENERATED from agents/ — see scripts/build-agents.py),
# .claude/commands/.
.claude/settings.local.json
.claude/agent-memory/
.claude/worktrees/
.claude/projects/
.claude/shell-snapshots/
.claude/todos/
.claude/statsig/
.claude/history.jsonl

# Stray agent-memory backstop. If an agent's cwd is inside this subrepo and it
# resolves a bare `memory/<role>/` path relative to cwd, the write lands here
# instead of the canonical `flatland-business/agents/memory/<role>/`. Drift
# incident 2026-05-16 (CAO log) is the precedent. Ignore so any accidental
# write stays local and never commits. Migrate to canonical and delete the dir.
/memory/

# Vercel CLI link state — holds the projectId/orgId for the linked Vercel
# project; created by `vercel link`. Machine-local, never committed.
.vercel

# OS
.DS_Store
Thumbs.db

# Flatland local data
*.xlsx
# The planted-fault challenge serves this sealed workbook byte for byte
# (apps/web/app/lib/challenge/challenge-assets.test.ts checks its SHA-256).
!apps/web/public/challenge/sotol_springs_reservoir.xlsx
models/
exports/
results.tsv
run.log
__pycache__/
*.pyc

# --- Monorepo workspace (ADR-050) ---
# npm workspaces hoists dependencies to a single root node_modules.
node_modules/
# turbo was removed — see the turbo-removal amendment in
# docs/adr/050-monorepo-consolidation.md. This line stays as a cheap guard:
# `npx turbo` still writes .turbo/ caches, and an accidentally committed task
# cache is a worse discovery than one redundant ignore line.
.turbo/

# --- The task graph (Mission 004 lane 2, SPEC §4.3) ---
# `.moon/workspace.yml` and every `moon.yml` ARE committed — they are the graph.
# `.moon/cache/` is moon's own local state: the content-addressed task cache,
# the hashed input manifests, and the serialised workspace graph. It is machine-
# local and it is written even under `MOON_CACHE=off`, which turns the task
# cache off rather than turning writing off, so this line is not conditional on
# how moon is invoked.
.moon/cache/

# Generated analysis reports (regenerated each run, never committed). Includes
# the jscpd duplication report (VAL-STYLE-007) emitted to reports/jscpd/.
reports/

# Generated test-performance reports (regenerated each run, never committed).
# JUnit/vitest XML output from the `test-performance` CI job and the
# services.yaml `test-performance` command (VAL-TEST-004).
test-results/

# --- Mission artifacts (analyst-harness v1.0) ---
# Mission-specific research and validation artifacts that are generated during
# the mission and must never be committed. These live in the worktree during
# active development but are not source.
.mission-research/
.flatland-mission/

# Impeccable design-hook local state. `config.json` IS committed — it carries the
# reviewed suppressions and their reasons — but the dedup cache and the
# per-developer overrides are machine-local.
.impeccable/hook.cache.json
.impeccable/config.local.json
