Решили: обратной правкой к «добавили модификатор» считается его СНЯТИЕ, а не запись прежнего значения. Change получил признак Added, в пакете появилась операция removeStat.

Почему: SetStat, не найдя стата в _stats, добавляет модификатор и честно возвращает Before = NaN — значения до правки не существовало. Батч же трактовал Before как число и клал его в *.undo.json. Откат такого пресета писал юниту MaxHP = NaN (или 0, если разбор NaN проваливался в fallback) — арена получала бойца без HP. Отвергнутая альтернатива — «не писать undo для добавления вовсе»: она тише, но делает файл отката неполным, а он и есть единственный ответ на вопрос «что пакет реально тронул».

Грабли: отсутствие значения и нулевое значение в аудите выглядят одинаково, если аудит хранит только числа. NaN в change-log печатается прочерком, поэтому в логе поломка читалась как «было пусто — стало 2000», то есть как норма. Заодно выяснилось, что справочник скилла баланса звал две операции setFloat/addFloat, тогда как код знает setValue/addValue: пакет по документации не применился бы, ограничившись предупреждением в консоли.

Владелец правды: ContentEditService.Change.Added, ContentEditService.RemoveStat, ContentEditBatch.SetStat.