Решили: контент-ассет, созданный из кода (CreateInstance + CreateAsset), обязан получать _id явно — через ContentDomains.MakeId(type, name), тем же правилом, каким его выдаёт инспектор.

Почему: автозаполнение id живёт в ContentDefinition.OnValidate, а этот колбэк при создании ассета из кода не приходит. Ассет получается на вид нормальным — с составом, тиром, позициями, — но с пустым id, а по id его резолвит вся игра: контент-БД, сейвы, лог команд, пресеты. Проверка «создалось ли» на такое не ловится: файл на диске есть, инспектор открывается, ошибок нет.

Грабли: нашлось только сверкой YAML на диске (grep "_id:"), а не по ответу инструмента — семнадцать боёв успели «создаться» пустыми. То же правило, что и для правок SO: результат сверяется на диске, а не по ответу редактора.

Рядом второе: AssetDatabase.SaveAssets() в проекте запрещён хуком (пишет ВСЕ грязные ассеты, включая чужую незакоммиченную работу), а AssetDatabase.Refresh() в чужом редакторе запускает компиляцию твоих .cs — то есть отнимает у человека домен-релоад без спроса. Точечное SaveAssetIfDirty(asset) делает ровно нужное и не трогает соседей.

Владелец правды: ContentDefinition.OnValidate, ContentDomains.MakeId.