Суббота начинается не с новостей, а с вопроса: кто вообще в субботу трогает релизы. Ответ — тот, у кого двадцать три пул-реквеста приехали ночью, пока он спал. Я разбирала это с чашкой в руке, и первое, что поняла: в этой истории самое интересное не то, что выкатили, а то, что утром убрали.

В ночь на 24 октября в main приехал релиз из двадцати трёх PR. К половине одиннадцатого утра один из них был откачен.

Причина простая и человеческая: владелец посмотрел набор иконок Sproun на стенде и решил, что не пойдёт. Днём раньше этот набор приехал тем же ночным поездом в составе релиза #2123 — и не пережил первого показа. Такое бывает чаще, чем пишут в релиз-ноутах, и обычно остаётся внутри.

Что именно ушло

Сто четыре PNG из `public/icons/**`, компонент `RasterIcon.tsx` и правки в восьми компонентах с пятью тестами. Обратный патч merge-коммита лёг чисто — файлы после мержа никто не трогал, это проверено `git apply -R --check`: 127 файлов, +103/−329. Миграций, бэкенда и биллинга в откате нет — то есть цена ошибки ограничилась фронтендом и половиной рабочего дня.

Проверки при откате: eslint по изменённым компонентам — ноль замечаний, точечные тесты каталога и поповера — 50 из 50. Три файла e2e в песочнице не стартовали из-за неполного `node_modules` — это состояние среды, а не изменения; полный прогон шёл в CI.

Инфографика: 23 PR в релизе, 1 откачен, 127 файлов в патче, 39 262 теста, авто-деплой удержан
Цифры дня: масштаб релиза, цена отката и состояние выкатки.

Вторая история — про молчание модели

Пока иконки ходили туда-обратно, чинили nodesmith. Симптом неприятный: при редактировании метки пула референсов в документ попадало запрещённое поле `label`, и следующее сообщение ассистента падало с плоским HTTP 400 ещё до того, как модель успевала ответить. Со стороны это выглядит как «модель сломалась», хотя модель была ни при чём.

Починили в три слоя: редактор теперь пишет `label_template`, строгая валидация выбирает ветку по `type`, а HTTP- и tool-результаты сохраняют конкретные замечания по полям. Отклонённая команда остаётся на рабочей ревизии — модель может исправить её и повторить, вместо того чтобы начинать заново. Повторные невалидные тела считаются в Redis по паре «актор/цель», и третье подряд отклонение уже поднимает событие об ошибке.

Чем это закончилось для прода

Полный локальный прогон на изолированных PostgreSQL и Redis: 2 363 файла тестов прошли, 39 262 теста, один ожидаемый провал. CI на том же коммите зелёный со второй попытки — первый прогон упал не на логике, а на подтверждении очистки Docker.

И главное, что стоит знать: авто-деплой в production держат. Настоящий путь «сохранить, одобрить, опубликовать» на стенде с Wan 3.0 ещё не пройден до конца. То есть работа влита, но в прод не поехала — и это осознанное решение, а не забывчивость. Merge не доказывает deploy; здесь это не оговорка, а причина, по которой релиз стоит.