Решили: при переходе авто-атаки на несколько контактов в одном свинге рефанд кулдауна (AttackCooldownTicks = 0 в Interrupt) положен только свингу, который не нанёс ни одного контакта. Как только хотя бы один контакт разрешён, прерывание рефанда не даёт — кулдаун идёт от первого контакта свинга. Промах по ушедшей цели (Evade) считается состоявшимся контактом.

Почему: иначе микростан становится ускорителем. Первый контакт нанесён, свинг рвётся, кулдаун обнуляется — и новый свинг начинается заново с первого контакта, то есть частота первого удара падает с интервала до «стан + замах». Альтернативу «пусть кулдаун тикает и под станом» отвергли: она делает короткие станы бесплатными по темпу и обесценивает контроль как механику. Второй отвергнутый вариант — считать промах пустым свингом: тогда рефанд получал бы кайт, и убегающий ускорял бы того, от кого убегает.

Грабли: инвариант выглядит уже соблюдённым и потому кажется не требующим теста. Сегодня он держится случайно — стан после удара попадает в ветку Recovery, где кулдаун замирает, а не рефандится; ветка Interrupt с рефандом при одиночном контакте безобидна. Сломается ровно в тот момент, когда серия появится, и без guard-теста это пройдёт незамеченным: DPS уползёт только у тех китов, по кому спамят контроль.

Вторая грабля — из той же темы, но про размещение контактов: правилом авторинга её не закрыть. Свинг сжимается (attackDurationTicks = min(MaxAttackAnimTicks, intervalTicks)), а скорость атаки — рантайм-величина, её крутят баффы, поэтому любые два маркера при достаточном сжатии схлопнутся в один тик, и валидатор клипа в редакторе этого не увидит. Позиции контактов считаются в нормированном времени клипа × длительность свинга, затем раздвигаются до зазора в один тик; отсюда потолок атак/сек ≤ TickRate / N для кита с N контактами.

Владелец правды: тест WindupAutoAttackTests.Stun_AfterHit_DoesNotRushNextAttack, <remarks> у ClipMarkers, реестр звеньев и вердикты — tech/00-meta/tech-debt §3.9.