# Dependencies
node_modules/
.pnpm-store/

# Build output
dist/
build/
.next/
.turbo/
*.tsbuildinfo

# Environment — NOTE the suffixed variants.
# A bare `.env` rule matches ONLY a file named exactly `.env`. Real credentials
# have been committed in other repos here precisely because `.env.app` and
# `terraform.tfvars` fell outside a bare rule. Be explicit; keep *.example tracked.
.env
.env.*
!.env.example
!.env.*.example
*.tfvars
!*.tfvars.example

# Secrets, keys, certs — DKIM private keys never enter the tree.
secrets/
*.pem
*.key
*.p12
*.keystore
dkim-private*
!*.pub.pem

# Mail spool / queue state — durable buffers, never committed
spool/
queue/
*.eml
*.ndjson

# Python build and cache output (packages/sdk-python)
__pycache__/
*.py[cod]
.pytest_cache/
.mypy_cache/
*.egg-info/
.venv/

# PHP (packages/laravel). `composer.lock` is deliberately NOT committed: this
# is a library, so the lock file describes one machine's idea of the dependency
# graph rather than an application's. CI resolves fresh against the constraints
# in composer.json, which is what actually catches an incompatible Laravel
# release before a customer does.
vendor/
composer.lock
.phpunit.cache/
.phpunit.result.cache

# Logs, coverage, test output
*.log
coverage/
playwright-report/
test-results/

# OS / editor
.DS_Store
Thumbs.db
.idea/
.vscode/
*.swp

# Agent worktrees — scratch checkouts, never part of the repo.
.claude/worktrees/
