Решили: Ристалище открывается ПУСТЫМ. Ассетный расклад (ProvingGroundsConfig) на входе больше не ставится, параметр снят с боевого скоупа. Бойцов приносит заказ: сегодня дев-команда, позже — экран сборки боя. Токен отмены стал токеном ТЕКУЩЕГО МЕРОПРИЯТИЯ, а не только забега.

Сказано: «щас при входе в ристалище уже есть какой-то ГОТОВЫЙ бой. Будто это mirror, но я не уверен. Найди костыль в коде этот и поправь. Также из ристалища нельзя корректно выйти в главное меню. Кнопка просто не работает» (02.08.2026, сессия f24f0cc4).

Почему: ассет заводился как заглушка на время, пока нет экрана сборки состава, — «чтобы было с кем». Но заглушка срабатывала ПЕРВОЙ и потому оказалась вторым владельцем состава: игрок, вошедший на площадку, получал готовый бой 4×4, которого не заказывал. Пустая площадка — единственный честный ответ: драться не с кем, и кнопка «Начать» это показывает сама, потому что смотрит на наличие врага, а не на место.

Вторая правка: «В главное меню» на площадке молча не работала. Токен отмены взводился только в RunActAsync, и на Ристалище отменять было нечего. Теперь его взводит любое мероприятие, а ожидание выхода с площадки отменяется вместе с ним.

Грабли резки: мёртвый код удалялся по диапазону строк (sed), и вместе с командами запуска боя уехали живые соседи — SetRngSeed и пять Sep*. Компилятор поймал, но урок общий: перед резом диапазона проверить, что внутри нет чужого; вырезать по границам методов, а не по номерам. Всего снято 870 строк: семь команд, семь срезов китов, зеркальный бой и витрина F3 со своей клавишей и событием ввода.

Владелец правды: Game/DeploymentController.StageProvingGrounds, Game/Services/GameFlow.ShowProvingGroundsAsync, Game/CombatLifetimeScope.