Двенадцать пятьдесят. Список открытых правок я смотрю до обеда, потому что после обеда смотреть его бессмысленно: за утро прибавилось восемь штук, три из них — автоматика, обновляющая документацию по расписанию. Рядом стоят 2228 и 2229, с разницей в восемь минут. В первой две добавленные строки. Во второй — семьсот пятьдесят две. И вторая не может поехать без первой.

Лист с номерами я распечатала ещё вчера и обвела не ту строку. Сегодня обвожу заново, тем же карандашом.

Что стоит в очереди

2229 — про маржу в столе цен. Внутри кода жило допущение: рублёвая цена одного кредита, зашитая константой и равная цене старой подписки. Витрина с тех пор продаёт кредиты в 2,77 раза дешевле, поэтому пересчёт старым курсом давал минус по всем подпискам при полном расходе токенов — а стол при этом показывал цель. Правка добавляет курс отдельной миграцией 415, переписывает константу на цену витрины и приносит тест, который падает на старом значении: проверено, три падения из пяти.

Но правка — черновик, и в шапке стоит «не вливать». Она перекрывается с 2219, где цена кредита читается из живого тарифа, а форму лесенки владелец выбрал другую. То есть 2229 ждёт не проверки, а решения — и это отдельная очередь, в которую я не лезу.

Перед ней, чтобы файл миграции вообще можно было положить, стоит 2228: две добавленные строки, одна удалённая, единственный файл — реестр миграций. Она резервирует номер 415 и объявляет следующим кандидатом 416. Больше в ней нет ничего.

Зачем гарду такая строгость

Гард называется migration-ledger-first и требует простого: строка реестра на main должна появиться раньше самого файла миграции. Причина не в аккуратности, а в номерах. Реестр — единственное место, где номер занят глобально, сразу для всех веток; пока строка не влита в main, две ветки могут взять один номер, и в проде встретятся две миграции с одним именем.

Это контроль порядка, а не правильности: о содержимом SQL он не знает ничего. И обхода у него нет — ни флага, ни исключения для «у меня честная миграция». Цена такой строгости — сериализация: каждая миграция теперь ждёт влития документа, а документ ждёт свободного окна на слияние.

Сколько это стоит в часах

2228 открыта 5 ноября в 21:52 по Москве, 2229 — в 22:00. Сейчас пятница, час дня, обе открыты. Пятнадцать часов на двухстрочной формальности — это не деньги, это очередь, и она оказалась длиннее самой работы.

За очередью ещё три шага, и они не про код. Проверки в репозитории выключены вручную, поэтому контейнерный прогон запускают руками — в описании 2229 прямо сказано, что его не запускали. Канарейку на копии базы тоже не запускали. Выходит, правка, меняющая одну строку курса, должна пройти документ, слияние, ручные ворота и канарейку: четыре шага, из которых первый не имеет отношения к деньгам, а последний — к коду.

Второй контроль сломался в другую сторону

В тот же вечер рядом лежала 2227 — отказ ноды «Редактировать» для роликов вне четырёх–тридцати секунд. Сама правка в порядке, но её ворота были красными: прогнали 39 254 теста, упало три, все — в проверке хоста Docker. Машина держала среднюю нагрузку 62 при десяти ядрах, заглушке давали тысячу миллисекунд, одиночный повтор упал на 1 077. После спада нагрузки тот же файл прошёл три раза подряд, 51 из 51.

Сегодня утром это починили отдельной правкой 2235 — и там же записали цену. До правки проверки падали шестнадцать раз в шести прогонах из шести при нагрузке 78–119. Отдельный замер: при бюджете в секунду снималось 4 запуска заглушки из 12, при бюджете в десять секунд — ноль из 12, самый долгий занял 1 439 миллисекунд. После правки — 51 из 51 в трёх прогонах под нагрузкой 110, 155 и 203. Цена: файл стал дольше примерно на 24 секунды, потому что восемь проверок ждут окно частичной стадии целиком. Сам код проверки, кстати, не менялся — только бюджеты внутри теста.

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

Инфографика: бюджеты таймаутов в секундах — от 1 до 55
Длительности из описаний правок 2227 и 2235, в миллисекундах. Длина полосы — значение, делённое на 24 000, линейно; шкала не логарифмическая.

Что я записала

Ничего не влито. 2228, 2229, 2227 и 2235 открыты на момент, когда я это пишу: гард по-прежнему стоит на пути миграции 415, хрупкий тест по-прежнему в основной ветке. Все числа выше — из описаний правок; я прочитала их, но не запускала ни одного из этих тестов и не собирала контейнерный прогон.

В очередь записала проверку через неделю. Если резерв номера станет обычным шагом перед каждой миграцией, значит гард научил всех писать формальность — и тогда дешевле починить гард, чем гордиться дисциплиной.