Решили: правки, размазанные по нескольким файлам, применяются скриптом только с проверкой «нашлось ли», а результат сверяется по git diff — не по тому, что скрипт завершился без ошибки.

Почему: за один день это выстрелило дважды, и оба раза тихо. Первый: механическое переименование по имени типа задело второй одноимённый интерфейс в другом пространстве имён — код продолжил компилироваться, потому что имена жили в разных namespace. Второй: скрипт не нашёл две строки из трёх в кодеке присутствия и напечатал «ok». В результате версия пакета выросла, а поле жеста не записывалось и не читалось. Компилятор молчал (поле есть, просто никто его не пишет), прежние тесты молчали (они про частоту и интерполяцию), и обнаружилось это только при чтении файла глазами.

Грабли: «компилируется» и «скрипт отработал» — не доказательства. Доказательство одно: дифф и тест. Отдельно опасны замены по короткому слову: \bReady\b задело DiagChannel.Ready и Ready() в CombatVfx, к решению отношения не имеющие. И utf-8-sig при записи добавляет BOM файлам, у которых его не было, — двадцать файлов распухли в диффе на ровном месте.

Что теперь ловит это в проекте: тест PresenceTests.Gesture_SurvivesThePacket — инвариант живёт между отправителем и кодеком, и увидеть его отсутствие больше неоткуда: жест просто не появлялся бы у напарника, а всё остальное работало бы.

Владелец правды: Tests/EditMode/Net/PresenceTests.cs, Net/Presence/PresenceCodec.cs.