.env
.env.*
.dev.env
*.env.local
node_modules/

# Exclude markdown files by default (design notes, architecture
# docs, battle reports, CLAUDE.md, READMEs). Published docs ship
# as HTML under landing/docs/.
*.md

# Re-include: the public agent/reviewer guide at the repo root.
!AGENTS.md

# Re-include: user-feedback corpus (Kibana + Elasticsearch theme
# write-ups that drive XERJ design decisions). These are the
# research artifacts we want in the repo.
!user-feedback/**/*.md

# Re-include: internal design/planning docs we want in the repo.
!playground/docs/**/*.md

# Re-include: engine working notes for future Claude sessions
# (session log in git form — motivations, benchmark results,
# architecture decisions).
# NOTE: CLAUDE.md files are INTERNAL-ONLY (user directive 2026-07-10)
# and must never be tracked/pushed; the public agent-facing guide is
# the root AGENTS.md.
!engine/README.md
!engine/ARCHITECTURE_*.md
!engine/BATTLE_*.md
!engine/REAL_BATTLE_*.md
!engine/SEARCH_BATTLE_*.md
!engine/STORAGE_BATTLE_*.md
!engine/CHAOS_*.md
!engine/CAPPED_*.md
!engine/CLUSTER_*.md
!engine/COMPRESSION_*.md
!engine/CLUSTERING_*.md
!engine/ES_vs_*.md

# Re-include: engine/reports/ for datetime-stamped test/bench logs
!engine/reports/**

# Re-include: engine/docs/ for design notes (API specs, RFCs).
!engine/docs/**/*.md

# Re-include: sales-engineer demo kit (runbook, pitch, objection bank).
!demo/**/*.md

# Rust build output
target/
# Per-task build directories. Parallel work in several worktrees sets
# CARGO_TARGET_DIR=engine/target-<task> so the builds do not evict each other's
# artifacts, and `target/` alone does not match those. One `git add -A` over a
# tree with one of them staged 14,623 object files, which is why this is a rule
# and not a habit.
target-*/

# cargo-fuzz working state. The harnesses and their SEEDS are tracked
# (engine/fuzz/fuzz_targets/, engine/fuzz/seeds/) — the seeds are the
# regression suite and every one of them is named after what it covers. The
# working corpus is not: `cargo fuzz run` writes every input it finds
# interesting into it, and a few hundred opaque blobs per run is how a seed
# corpus stops being reviewable. Promote a discovered input by copying it into
# seeds/ under a descriptive name.
engine/fuzz/corpus/
engine/fuzz/artifacts/
engine/fuzz/coverage/
engine/fuzz/Cargo.lock

# Upstream Elasticsearch reference clone — not part of this repo
es-reference/

# Local tool state + deploy artifacts
.claude/
encrypted/
.DS_Store

# Ephemeral runtime / demo state (regenerated by demo + CLI scripts)
demo/.cli-validate/
demo/.flow-data/
demo/.ingest-validate/
demo/.flow-chrome/
demo/.xerj.log
demo/.xerj.pid
engine/demo-data/
!engine/IMPLEMENTATION_*.md
scratchpad/
engine/build.log

# ----------------------------------------------------------------------
# OSS release hygiene (added by RELEASE_HYGIENE_AUDIT). Additive only —
# NOTE: ignoring a path does not untrack files already committed. To stop
# shipping the internal dirs below, maintainers must also run:
#   git rm -r --cached brief landing/resources/xerj-sales-kit.zip
# (xerj-ux/ is intentionally tracked — the Console UI ships with the
#  open-source engine so the binary bundles a working console.)
# ----------------------------------------------------------------------

# Local Cloudflare Wrangler state (may contain account/session data).
.wrangler/

# Internal go-to-market material — not part of the OSS engine.
# (Recommended for a separate repo; see docs/RELEASE_HYGIENE_AUDIT.md.)
brief/
gtm/
landing/resources/xerj-sales-kit.zip

# Re-include root OSS scaffolding so the default *.md / no-extension
# ignore above does not swallow the standard public-repo files.
!README.md
!/README.zh-CN.md
!/README.ja-JP.md
!/README.ar.md
!/README.es.md
!/README.ko.md
!CLA.md
!LICENSE
!LICENSE.md
!NOTICE
!CONTRIBUTING.md
!CODE_OF_CONDUCT.md
!SECURITY.md
!CHANGELOG.md

# Re-include the public architecture doc (Markdown is ignored by default above).
!docs/ARCHITECTURE.md
!ROADMAP.md
!docs/**/*.md

# Re-include the shipped tooling's own docs. `tools/xerj-code/SKILL.md` is part
# of the tool, not a design note, and the blanket *.md rule above silently
# swallowed it — the same failure mode as the pull-request template below, and
# the reason issue #319 existed at all (the reference-coding tooling was
# documented everywhere and shipped nowhere).
!tools/**/*.md

# Re-include the DeepSeek Harness bundle readme. The blanket *.md rule
# above would drop dsh/README.md on `git add`, and the catalog lists the
# committed file.
!dsh/**/*.md

# Re-include the public .github community files. The blanket *.md rule above
# silently swallowed these: no pull-request template has ever existed in this
# repo's history because `git add` refused it without anyone noticing, while
# CONTRIBUTING.md claimed one was there. Add a `!` line here for any new
# Markdown under .github/, or it will not be committed.
!.github/AI_CONTRIBUTIONS.md
!.github/PULL_REQUEST_TEMPLATE.md

# Transient demo-capture artifacts (local paths + ephemeral tokens)
demo/screenshots/manifest.json

# Local ES 8.13.4 reference node for fair benchmarking (never committed)
.es-local/
__pycache__/

# Re-include: agentic-SEO article sources and their published Markdown
# twins. The twins are what AI agents fetch via <link rel="alternate">;
# without this rule the blanket *.md above silently drops them from the
# deploy and every alternate link 404s.
!content/**/*.md
!landing/**/*.md

# Re-include: the factcheck fixture corpus. These 21 Markdown files ARE the
# regression suite for claims_rules.py - `factcheck.py --fixture-check` runs
# every one of them and prints a confusion matrix, and each rule is required to
# own at least one fixture. The blanket *.md rule above silently swallowed the
# whole directory, so the suite has never been in the repo and --fixture-check
# reports "no fixtures" on a clean checkout. Same failure mode as the
# pull-request template and tools/**/SKILL.md above.
!scripts/seo/testdata/**/*.md

# Re-include: the committed synthetic Takeout that xerj-autoindex's end-to-end
# mail test indexes. scripts/synthetic-takeout.py writes a Drive/meeting-notes.md
# into it, and the blanket *.md rule above dropped that one file from the
# commit: the tree was complete on the author's disk, `git status` was clean,
# and "Build + Test" was red on every clean checkout (PR #949 review). Test
# fixtures are data, whatever their extension.
!engine/crates/xerj-autoindex/tests/fixtures/**/*.md

# Re-include: the SEO toolchain's own operational guide. It documents the
# article generator, the URL map and every merge gate for landing/, so it is
# part of the tooling — the same reasoning as tools/**/*.md above. The
# unanchored `!README.md` rule further up happens to cover this path today,
# but that rule exists for the repo-root README; anchoring it to `!/README.md`
# would silently drop this file and nothing would say so.
!scripts/seo/README.md

# Working record for agent sessions. Never committed: the captures and
# research notes under .dogfood/ are the session's scratch record, not
# repository material, and the blanket *.md rule above does not cover
# the JSON/txt captures. An explicit directory ignore keeps every path
# under it out of a commit no matter what a later re-include says.
.dogfood/

# The evidence harness that produced those captures. It has no consumer
# in site generation or in any CI gate, and its only output was
# .dogfood/seo/evidence/, so it follows the captures out of the tree.
scripts/seo/evidence/

# MCP Registry bundle build output (deploy/mcp-registry/build-mcpb.py)
/dist/
