# =============================================================================
# Python
# =============================================================================
.venv/
__pycache__/
*.pyc
*.pyo
*.pyd
*.egg
*.egg-info/
dist/
build/
.pytest_cache/
.coverage
htmlcov/
.ipynb_checkpoints/

# =============================================================================
# Secrets / local config
# =============================================================================
.env
.env.*
!.env.example
.claude

# =============================================================================
# Owner-only artifacts (not needed in repo)
# =============================================================================
.planning/
# Anchored to repo root — a bare `data/` also matched web/lib/data/ and silently
# dropped public-catalog.ts from commits, breaking CI (same failure as emails/).
/data/
# Anchored to repo root — bare `marketing/`, `landing/`, `sources/` also matched
# nested dirs anywhere in the tree (same footgun as `data/`/`emails/` above).
/marketing/
/landing/
/sources/
# NOTE: no bare `docs/` rule — the project documentation lives in /docs/ and
# web/docs/ and must stay tracked. A bare `docs/` silently ignored them.
# Legal agreements stay OUT of the repo (never been tracked; may hold PII/terms).
# Wave 2026-08-06 carve-out: the legal lane's ANALYSIS deliverables (.md only —
# counsel briefs, verdict cards, specs; wave plan §3/§6 requires them as
# committed handoff artifacts) are tracked. Agreements, signed documents, and
# archived third-party page copies (docs/legal/archives/) remain ignored.
/docs/legal/*
!/docs/legal/*.md
!/docs/legal/source-verdicts/
/docs/legal/source-verdicts/*
!/docs/legal/source-verdicts/*.md
/docs/brand/
# Anchored to repo root — a bare `emails/` also matched web/emails/ and silently
# dropped new source files (e.g. contact-message.ts) from commits, breaking CI.
/emails/
# Marketing pipeline artifacts (ms:* skills write here). Anchored to repo root
# like the rules above. Was tracked once — untracked via `git rm -r --cached`.
/context/
# NOTE: no `/onboarding/` rule — onboarding/<slug>.yaml manifests are the
# human-approval gate and MUST be tracked (deployment runbook Phase D commits
# them; docs/INGESTION.md documents them as git-tracked).
WHY_SELECTIVE_IDENTIFIERS.md
# =============================================================================
# ML artifacts — regenerable
# =============================================================================

# Trained model files — regenerate with scripts/04_train.py
# Anchored to root so it doesn't also ignore dbt_pipeline/models/ (tracked source).
# metadata.json IS tracked (G4, 2026-08-06): it carries the honest per-horizon
# skill/coverage record every public figure must trace to. Binaries stay out.
# `/models/` alone would exclude the directory itself and git would never
# descend, so negations below it could not re-include anything — hence the
# three-pattern form: ignore contents, re-include first-level dirs so git
# descends, re-include only their metadata.json.
/models/**
!/models/*/
!/models/*/metadata.json

# MLflow run store
mlruns/

# Pipeline logs
logs/
*/logs/

# =============================================================================
# dbt — regenerable artifacts
# =============================================================================
dbt_pipeline/target/
dbt_pipeline/logs/
dbt_pipeline/dbt_packages/
dbt_pipeline/.user.yml

# =============================================================================
# Great Expectations — removed, replaced by validate_observations() in ingest.py
# =============================================================================
gx/

# =============================================================================
# Editor / OS
# =============================================================================
.vscode/
.idea/
.DS_Store
Thumbs.db
*.swp
*~
MARKET.md
# =============================================================================
# Dagster local runtime state — regenerated by every `dagster dev` run
# =============================================================================
dagster/.tmp_dagster_home_*/
dagster/logs/
dagster/disk/

# =============================================================================
# Disk data — regenerable via pipeline commands
#
# Regenerate commands:
#   AMS CSVs     → python scripts/02_pipeline.py fetch <commodity>
#   FRED data    → python scripts/ingest.py --commodity <commodity>
#   NASS taxonomy→ python scripts/ingest.py --commodity <commodity>
#
# KEEP in repo (curated, not regenerable):
#   disk/fred/series_map.json   — curated FRED series index
#   disk/ams/slug_index.json    — curated AMS slug index
#   disk/nass/commodities.csv   — curated NASS taxonomy; onboarding approve
#     writes approved commodity_desc values here, and ingest.py resolves the
#     QuickStats commodity_desc from it. Without it a fresh CI checkout falls
#     back to naive upper-casing (soybean → SOYBEAN ≠ SOYBEANS → empty pull).
# =============================================================================
disk/ams/AMS_*/
disk/fred/dollar_index/

# =============================================================================
# Supabase CLI temporary files
# =============================================================================
.temp*
# =============================================================================
# Node / web
# =============================================================================
**/node_modules/
.worktrees/
.superpowers/
# Anchored to root — the retired Dash app. A bare `dashboard/` also matched the
# web/app/(dashboard)/dashboard/ route segment (tracked source).
/dashboard/
.handoff/
.playwright-mcp/