Грабли: ветка не собиралась из чистого клона несколько дней, и ни один локальный инструмент этого не видел. Два типа (PlateButton, MapIntroTiming) лежали на диске некоммитнутыми, а их потребители — четыре экрана и вид карты — были закоммичены давно.

Почему невидимо. И редактор, и compile-check.ps1 берут список исходников с диска. Файл есть — значит компилируется, и оба честно отвечают «зелено». Вопрос «а есть ли он в репозитории» локально не задаёт никто. Тесты в теневом проекте тоже не помогают: Assets там — junction на живое дерево, то есть тот же диск.

Кто нашёл: первый прогон выкладки в Steam — единственное место, которое всегда стартует с чистого checkout. Нашёлся при этом чужой недочёт, а не тот, ради которого прогон запускался.

Следствие, которое стоит помнить: «compile-check зелёный» означает «компилируется ТО, ЧТО У МЕНЯ НА ДИСКЕ», а не «компилируется то, что в репозитории». Разница видна только в CI и у того, кто клонирует репозиторий заново — то есть у второго игрока на тесте вдвоём.

Дешёвая привычка вместо инструмента: перед пушем смотреть git status на untracked .cs рядом с тем, что коммитишь. Заводить отдельный гейт не стали: CI ловит это бесплатно и без ложных срабатываний, а локальная проверка «а всё ли добавлено» ошибалась бы на каждом черновике.

Владелец правды: ci.yml (job build), .github/workflows/steam-deploy.yml.