Решили: предел живых призывов проверяется гейтом каста в AbilitySystem.TryPlan, а тест на него переписан так, чтобы падать при отсутствии гейта.

Почему: AbilityData.SummonLimit было объявлено в данных, описано в карточке Bonewright («лимит живых скелетов — 8») и закреплено решением Макса («предел — гейт каста: мана и кулдаун целы, игрок видит предел глазами»). Читать его при этом не читала ни одна строка боевой логики: единственный потребитель SummonSystem.CountLiveSummons вызывался только из теста. Некромант копил скелетов, пока хватало маны.

Грабли: поле, объявленное в данных и не прочитанное кодом, ничем себя не выдаёт — ни ошибкой, ни предупреждением. Инспектор его показывает, карточка его обещает, тест его упоминает; отсутствует только исполнение. Хуже того, тест был ложнозелёным по чужой причине: у призывателя было 100 маны при цене каста 40, поэтому третий призыв отсекала цена, а не предел. Тест проходил и при полностью отсутствующем гейте — то есть охранял инвариант только на словах. Признак такого теста: его числа сходятся ровно на границе, и граница эта — не та, что он проверяет.

Владелец правды: AbilitySystem.TryPlan (гейт с комментарием), тест SummonTests.SummonLimit_BlocksTheCastEntirely_KeepingManaAndCooldown.