Builds and test binaries belong in .cache/bin. The root .gitignore catches stray builds (aego-*, i18n, profiles, data dumps), make affected builds into .cache/bin/affected, make clean empties .cache/bin, and make ci ends with tools/ci-clean-root.sh: it fails when the root holds an untracked executable or a *.test file, and in CI when the run left changes git sees. .claude/CLAUDE.md tells agents to build only into .cache/bin and to run make ci before every push.