Решили: рекаст — это ускорение фаз, а не их снятие. Доигрыш прерванной атаки и замах вышедшего вне очереди удара остаются на месте и проигрываются вдвое быстрее; ожидание интервала по-прежнему снимается целиком. Множитель во всех API стал скоростью (2 = вдвое быстрее), а не долей, в которую превращается длительность, и живёт в двух ручках SimTuningConfig — «Ускорение доигрыша» и «Ускорение замаха».

Почему: снятая фаза убирает окно, в которое противник успевает ответить, — ускоренная лишь сокращает его. Отвергнутая альтернатива (recoveryMult: 0, «хвост снят целиком») делала рекаст бесплатным: у бурста не оставалось ни телеграфа, ни паузы, в которую можно вклиниться, и парированию, которое делается следующим, было бы не во что целиться. Числа вынесены в SO, а не в константы, по прямому требованию: их будут крутить «с позиции визуала и ощущения», а это правка ассета, не сборки. Ручек две, хотя пока обе равны 2 — доигрыш и замах подкручиваются под разное, и одна ручка на двоих означала бы, что настроить можно только оба сразу.

Грабли: ускоренный замах обязан сокращать весь свинг, а не переливать сэкономленное в доигрыш. Хвост считается от контакта (duration − lastContact), поэтому наивная формула выдавала удару, вышедшему вдвое быстрее, вдвое более длинный доигрыш — весь выигрыш возвращался обратно тем же тиком. Лечится расчётом доигрыша от базовой длины замаха (AttackTiming.WindupTicksFor(unit, ignoreRecast: true)). Поймал тест RecoveryCut_IsSpentByOneSwing, причём поймал не тем, что проверял: он ждал равных хвостов у двух подряд идущих атак и упёрся в 9 против 19.

Второе: узкий фильтр тестов не показывает соседние падения. Прогон по одному классу был зелёным, а по всему боевому неймспейсу — три красных: тест на удалённый авто-рекаст, переименованное поле _bonusOnHitEffect_bonusOnHitEffects и ассет «Решительного удара», снимавший заряд по тегу Stealth вместо Empowered. Лестница из CLAUDE.md («узко локально, целиком — в CI») означает, что блок сдаётся прогоном по неймспейсу, а не по классу.

Владелец правды: RuntimeUnit.RecastAttack (семантика скорости и конверсия «скорость → длина»), SimTuning.RecastRecoverySpeed / RecastWindupSpeed (числа), AutoAttackSystem.EnterRecovery и EnterWindup (применение), тесты WindupAutoAttackTests группы «Рекаст» — в том числе Recast_FasterWindup_ShortensTheSwing_DoesNotLengthenTheFollowThrough и Recast_KeepsAtLeastOneTickOfRecovery.