Вышел GRAIN 1.2 — и теперь он проверяет сам себя
by APERTURESyndicate · 5 сентября 2026 г.
Смотрите, в чём беда со стандартами кода: на словах с ними все согласны, а через полгода половина кодовой базы всё равно тихо от них отъехала — просто потому что следить за этим никогда ни на кого конкретно не было записано. Вот это как раз и чинит GRAIN 1.2. Ни одно правило из 1.1 он не меняет — те же 33 глагола, то же требование единицы измерения у числа, те же пять тегов в комментариях. Меняется то, что теперь не нужно надеяться на чью-то память, свою в том числе, чтобы их соблюдать. Эту часть теперь делает чекер.
И, честно говоря, почти всё это уже существовало — просто было ни к чему не подключено. В репозитории лежал ESLint-плагин с прописанными семнадцатью правилами по именам и форме кода, и его так и не подключили к реальной сборке. Он просто лежал и выглядел правильным, пока код вокруг него спокойно расходился со стандартом. С 1.2 чекеру стало всё равно, настроен ли где-то этот плагин — он сам гоняет каждое правило напрямую, независимо от того, что у тебя в редакторе. Заодно, раз уж взялись, подключили Kotlin и Swift — теперь Android- и iOS-оболочки Resonance живут по тем же правилам, что и TypeScript.
Первое, что все спрашивают: значит, теперь надо переписывать годы старого кода? Нет. Все нарушения, которые уже лежат в репозитории — а их 45 711 — один раз посчитали, записали как стартовую черту и оставили в покое. Гейт валит только то, что появилось новым. Функция, которую ты написал в прошлом году, продолжает делать ровно то же, что и вчера. А функция, которую пишешь сегодня, уже не может спрятаться за «ну там же в старом коде так же».
Вот как это выглядит на практике, на реальном обработчике, а не на выдуманном примере. Вот это:
function handleTrackData(data) {
const timeout = 900
// increment counter
const flag = data.views > 0
}становится вот этим:
function publishTrack(draft) {
const refreshTtlSec = 900
// why: races the worker otherwise
const hasViews = draft.viewCount > 0
}Логика та же, ничего не переписано с нуля — просто имя теперь говорит, что происходит, число несёт единицу измерения, а комментарий объясняет «почему», а не пересказывает то, что и так написано строкой выше.
Остальное, что реально приехало в 1.2, если интересно:
Чекер сам гоняет свои AST-правила — раньше он полагался на тот самый неподключённый ESLint-плагин, теперь плагин вообще не нужен.
Под проверку попали Kotlin и Swift, не только TypeScript — только в Android-оболочке это 184 файла.
SYNX-конфиги проверяются так же, как обычный код.
Название события обязано читаться как уже случившийся факт —
v1.invoice.paid, никогдаv1.payInvoice.Появился флаг --stat, который просто показывает, какой сервис ближе всех к чистоте, если вам это вообще интересно.
Если хочется прочитать всё целиком — все 33 глагола, почему handle и process под запретом, как гейт вообще решает, что считать «новым» — это всё на docs.aperturesyndicate.com/ru/grain. А если нет — это, в общем-то, и всё обновление.



