# Go
*.test
/control-plane/bin/
/forge-node/bin/
# Local `go build` output landing next to the sources instead of bin/. CI builds
# these from ./cmd/... and publishes them as generic packages — a host binary
# committed here is always an accident.
/forge-node/forge-node
/forge-node/forge-relay
/forge-node/forge-sandboxd
/control-plane/control-plane

# Python
__pycache__/
*.egg-info/
.venv/
dist/
.pytest_cache/
.ruff_cache/

# Node
node_modules/

# Env / local
.env
*.local
.DS_Store

# e2e generated artifacts (logs, screenshots, tokens)
/e2e/artifacts/
/e2e/tutorials/artifacts/
/e2e/artifacts-*

# Inference outputs from running the tutorials by hand — the tutorial code
# writes these to the working directory, so they land at the repo root. The
# copies that actually matter live in motion/assets/. .dockerignore already
# excluded sd-out.png and structure.pdb; keep the two lists in step.
/flux-out.png
/sdxl-out/
/sd-out.png
/animation.mp4
/ltx-out.mp4
/structure.pdb
.claude/worktrees/

# provider secrets (OpenStack OS_* creds) — never commit
.env.provider
infra/dev/.env.provider

# OVH S3 credentials (never commit)
user-*.txt

# Registry v2 token-signing keypair (registry-v2.md §5.1) — never commit
infra/dev/registry/

infra/dev/headscale/lib/
infra/dev/headscale/authkey.txt
infra/dev/headscale/preauth.key

# forge-node fetches contracts/ here (make contracts) — never a vendored copy.
/forge-node/.contracts
/forge-node/.contracts.tmp

# iam's published persona -> capability contract, fetched by
# contracts/fetch-iam-personas.sh and asserted by
# control-plane/internal/api/adminauthz_test.go. Same rule as the line above:
# never a vendored copy. A copy in this repo would keep passing after iam's map
# moved, which is the one thing the cross-check exists to catch.
/contracts/.iam-personas.json
/contracts/.iam-personas.json.tmp.*

