П. Толкачев
01Цифровая культура и трудапрель 202610 минут

Feature flags как микрополитика

Кто решает, что вы видите в продукте, и почему за переключателем в конфиге прячется вопрос власти.

Feature flag выглядит как самая безобидная вещь в кодовой базе. Булево значение, переключатель, строчка в конфиге. Включено — пользователь видит новую кнопку. Выключено — не видит. Инженеры относятся к флагам как к гигиене: можно выкатить код, не выкатывая функциональность, погасить сбойную фичу за секунды, показать изменение одному проценту аудитории, откатить все одним кликом в три часа ночи. Все это правда, и я сам семь лет живу внутри этой правды. Но у безобидной строчки в конфиге есть вторая жизнь, о которой на код-ревью обычно не говорят.

Решение, оформленное как настройка

Флаг решает, что и кому показать. У одних пользователей продукт один, у других другой, и граница между ними проходит по чьему-то выбору. Этот выбор редко делается на собрании или в публичном документе. Чаще он делается в панели управления, куда имеют доступ несколько человек, и занимает он секунд пять.

Я много лет работал с Unleash — платформой фича-флагов, которую мы у себя развивали и дописывали под свои процессы. Панель там устроена честно и удобно: список флагов, тумблеры, проценты раската, стратегии по сегментам. Заходишь, двигаешь ползунок с 5 до 25 процентов, жмешь «сохранить». Никакой драмы. И вот в этой гладкости все и дело: интерфейс сделан так, чтобы решение ощущалось как настройка яркости экрана, хотя по последствиям оно ближе к редакционному: кто увидит новую цену, а кто старую.

Назвать это «настройкой» — значит снять с решения вес. Слово звучит нейтрально и обратимо. А между фразами «мы решили показывать эту цену только этому сегменту» и «мы выставили флаг» разница только в тоне. Второе звучит так, будто никто ничего не решал, будто оно само сложилось.

Микрополитика раската

Постепенный раскат обычно объясняют через риск: выкатим на процент, посмотрим на метрики, если все хорошо — пойдем дальше. Разумно. Но посмотрите, что при этом происходит с человеком по ту сторону экрана. Он попадает в выборку, не зная об этом. Его опыт работы с продуктом становится замером. Его поведение на новой версии — те данные, по которым потом решат, увидят ли эту версию остальные.

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

Помню ночной инцидент. Новая фича раскатана на 10 процентов, метрика оплат по этому сегменту проседает, дежурный (это был я) видит график, который расходится с контрольной группой. Пять минут на диагностику, один тумблер в ноль, оплата восстановилась. Инженерно — красиво. Но задним числом я думаю о тех людях, которые эти десять процентов составляли: час-другой продукт у них просто работал хуже, никто их об этом не спрашивал, и в отчете они остались строчкой «раскат откачен, влияние ограничено».

Флаг, который живет второй год

Самый честный портрет власти в коде — это не эффектный инцидент, а забытый флаг. У нас был флаг, включенный на 100 процентов, который поставили как временный на время миграции. Миграция закончилась, флаг остался. Прошел год. Он висел в панели, зеленый, никем не тронутый, и формально все еще «управлял» поведением, хотя ни одна живая душа уже не помнила, что случится, если его выключить.

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

Вот это меня и цепляет. Приказ можно оспорить, у приказа есть тот, кто его отдал. А у зависшего флага спрашивать не с кого: есть коммит двухлетней давности и человек, который давно ушел из компании.

Власть, распределенная по коду

Где вообще живет решение показать одному пользователю одно, а другому другое? Не в голове менеджера и не в стратегии на слайдах. Оно размазано: часть в коде, часть в конфигурации, часть в правах доступа к панели, часть в негласном уговоре о том, кто может трогать какие флаги в проде без спроса. Власть размазана по инфраструктуре, и разглядеть ее из-за этого трудно.

Однажды на код-ревью я поймал себя на том, что спор давно ушел от самого кода к списку доступа. Коллега заводил новый флаг с правом переключать его на проде для всей продуктовой команды, человек двадцать. Технически безупречно. Я попросил сузить до трех, и мы полчаса препирались, потому что моя просьба выглядела как бюрократия и как недоверие к команде. А я просто не хотел, чтобы решение о том, что видят пользователи, мог в одиночку принять любой из двадцати, не оставив следа. Сошлись на аудите: переключать можно, но каждое переключение пишется в лог с именем. Компромисс так себе, если честно. Лог никто не читает, пока не случится инцидент.

Когда власть выглядит как инфраструктура, ее вообще перестают замечать. Никто не отдает распоряжений, просто система так устроена. Из тысяч мелких, технически оформленных выборов и складывается то, каким продукт окажется для конкретного человека.

Зачем это держать в голове

Здесь легко возразить: слушай, это просто работа, флаги полезны, ты сам сто раз это сказал, не выдумывай философию на ровном месте. Возражение честное, и наполовину я с ним согласен. Отказываться от флагов абсурдно, я бы первый не стал. Но отказ я и не предлагаю. Я предлагаю привычку видеть во флаге еще и слепок решения: кто его принял и на каком основании.

Инженер, который держит это в уме, проектирует немного иначе. Он спрашивает, кто получит доступ к панели и зачем. В описании флага он оставляет причину: для чего завели и когда планируется снять. Он замечает зеленый тумблер, который висит второй год, и не проходит мимо.

Помогает ли это на самом деле? Не уверен. Я по-прежнему завожу флаги, по-прежнему двигаю ползунки, и половина моих собственных флагов документирована кое-как. Изменилась одна мелочь: двигая ползунок с 5 на 25, я на секунду задумываюсь, чей опыт сейчас меняю и спрашивал ли этих людей хоть кто-нибудь. Обычно нет. Ползунок я все равно двигаю. Но в эту секунду настройка ненадолго снова становится решением, и заменить эту секунду мне пока нечем.

К индексу текстов© Петр Толкачев · MMXXVI