Принятие: почему платформу обходят и что с этим делать
Пятница, 17:40. Команда checkout чинит расчёт скидки при частичном возврате. Платформенный
пайплайн падает на проверке политик: образ подтянул библиотеку с известной уязвимостью, а её
обновление ломает сериализацию. Правильный путь — тикет на исключение, ответ в понедельник,
выкат во вторник. Фактический — собрать образ локально, взять роль, выданную полгода назад
«на время разбора инцидента», и сделать kubectl apply. В 18:05 исправление в проде,
и в понедельник об этом никто не вспоминает.
Через полгода у команды checkout свой пайплайн, свой Dockerfile, форк шаблона годовой
давности и убеждение, что платформа мешает выкатываться. При этом в отчёте о принятии
checkout числится подключённым: карточка в каталоге есть, репозиторий заведён из шаблона,
галочка стоит. Эта глава — про разрыв между галочкой и реальностью: как найти обходы,
как разобрать их по причинам, какие из них лечатся функциями, какие — надёжностью, какие —
разговором, а какие честнее признать и закрыть. Общая рамка —
карта трека, продуктовая логика и базовые метрики
принятия — Платформа как продукт.
Обход — это арифметика, а не саботаж
Инженер продуктовой команды в момент выбора решает простую задачу: каким способом довести изменение до прода дешевле. «Дешевле» — не в деньгах компании, а в его собственных часах, нервах и риске сорвать срок. У платформенного пути и у обходного есть по четыре слагаемых.
| Слагаемое | Платформенный путь | Обходной путь |
|---|---|---|
| Время выполнения | сборка, проверки, очередь выката, p95 вместо медианы | локальная сборка, один apply |
| Время ожидания чужого решения | тикет на исключение, доступ, ревью политики | ноль |
| Стоимость понимания | где смотреть логи, что означает ошибка POL-114, кого спрашивать |
всё уже знакомо |
| Риск | «а вдруг платформа сломает мне выкат в момент, когда я не смогу починить» | «я контролирую каждый шаг» |
Обходной путь почти всегда проигрывает по совокупной стоимости для компании — он не даёт ни воспроизводимости, ни подписи артефакта, ни учёта расходов, ни владельца в каталоге. Но эти издержки платит не тот, кто выбирает, и не в тот момент, когда выбирает. Это классическая локальная оптимизация: каждый участник ведёт себя разумно, а система деградирует (локальная оптимизация). Отсюда три следствия, и первое из них стоит принять раньше остальных.
Каждый обход — заполненная анкета исследования пользователей. Команда потратила реальные часы, чтобы обойти вашу работу. Это самая честная обратная связь, какая у вас будет, и единственная, за которую пользователи заплатили своим временем.
Второе следствие: обход самозакрепляется. Написанный однажды скрипт в понедельник уже работает, у него нет очереди и чужих проверок; через квартал он обрастает знанием команды, через два — вторым скриптом, который чинит последствия первого. Петля усиливающая: чем дольше команда вне платформы, тем дороже ей вернуться и тем меньше платформа знает о её потребностях (петли обратной связи). Третье: вы узнаете об обходе с задержкой в месяцы — он не проходит через ваши счётчики, а команда не приходит рассказать. Эта задержка и есть причина, по которой платформы «внезапно» обнаруживают принятие 30 % при отчётных 100 % (задержки).
Как рождается обход: хроника одной пятницы
Обход почти никогда не выглядит как решение «мы уходим с платформы». Он выглядит как одно исключение под срок, потом второе.
ответ — следующий рабочий день D->>K: локальная сборка + kubectl apply старой ролью K-->>D: исправление в проде за 25 минут Note over D,K: обход сработал и не имел последствий —
это и есть момент закрепления S-->>D: (в понедельник) исключение выдано D->>K: следующий выкат — тем же скриптом, «так быстрее» Note over P,S: платформа не знает ни об одном из двух выкатов:
в её метриках этих запусков просто нет
Шаги 2 и 3 — корректное поведение обеих сторон. Ломается система между шагами 3 и 5: срок пользователя измеряется в часах, срок поддержки — в днях. Никакая функция платформы этот разрыв не закроет; его закрывают самообслуживанием (исключение выдаётся автоматически с TTL и уведомлением) или дежурством, отвечающим в те же часы, что и инцидент продуктовой команды (самообслуживание, платформенная команда). Шаг 7 — критический и незаметный: обход не имел последствий, то есть команда получила подкрепление, что короткий путь работает. Если ваш ответ на это «надо запретить прямой доступ», вы правы наполовину: запрет без починки срока превращает обход в подпольный, а его вы уже не увидите.
Где искать следы: обход невидим по построению
Главная методологическая ошибка — измерять принятие изнутри платформы: дашборд показывает то, что через неё прошло, а обход в него не попадает никогда. Искать следы надо в системах, мимо которых пройти нельзя: аудит облака, конфигурации CI, счёт за облако, состояние кластера.
| Слой | Как выглядит обход | Где остаётся след | Чем достать |
|---|---|---|---|
| Шаблон сервиса | форк, который перестал обновляться | версия шаблона в файле сервиса | скан репозиториев, распределение по версиям |
| Сборка | свой Dockerfile вместо базового образа | базовый слой образа в реестре | инвентаризация реестра по FROM |
| Пайплайн | прямые вызовы aws, kubectl, helm, terraform |
конфиги CI в репозиториях | grep по всем репозиториям (см. ниже) |
| Доступ | долгоживущий ключ или роль «на разбор» | реестр ролей, дата последнего использования | выгрузка IAM, роли старше 90 дней |
| Изменение инфраструктуры | terraform apply с ноутбука |
журнал аудита облака: principal | SQL по аудиту (см. ниже) |
| Выкат | ручной kubectl apply |
managedFields, аннотация last-applied |
обход кластера, объекты с ручным менеджером |
| Владение | ресурс без метки владельца | счёт за облако, разрез по тегам | отчёт по нераспределённым расходам (стоимость) |
Самая дешёвая проверка — еженедельный рекурсивный grep по конфигурациям CI всех репозиториев
на шаблон вида (aws|gcloud|kubectl|helm|terraform)[[:space:]]+(apply|deploy|create) с подсчётом
попаданий на репозиторий: сложность O(N × M) по числу репозиториев и размеру конфигов, на паре
тысяч репозиториев — минуты. Ложные срабатывания будут (kubectl в скрипте локальной отладки),
поэтому скан даёт гипотезу; подтверждает её журнал аудита, где видно, кто менял прод на самом деле.
-- Доля изменений в проде мимо платформы, по командам за 30 дней.
-- cloud_audit — выгрузка журнала аудита облака (CloudTrail / Cloud Audit Logs).
WITH writes AS (
SELECT resource_team, -- из тега владельца
principal LIKE 'platform-ci/%' AS via_platform, principal, event_time
FROM cloud_audit
WHERE event_time >= now() - INTERVAL '30 days' AND environment = 'prod'
AND event_name ~ '^(Create|Update|Delete|Put|Apply)' -- только изменяющие
)
SELECT resource_team, count(*) AS writes_total,
count(*) FILTER (WHERE NOT via_platform) AS writes_bypass,
round(100.0 * count(*) FILTER (WHERE NOT via_platform) / count(*), 1) AS bypass_pct,
count(DISTINCT principal) FILTER (WHERE NOT via_platform) AS human_principals
FROM writes GROUP BY resource_team
HAVING count(*) FILTER (WHERE NOT via_platform) > 0 ORDER BY bypass_pct DESC;
Три предостережения. Инвентаризация — не расследование: как только результат скана попадает
в разговор со словами «нарушители», вы получаете последнее честное измерение в своей жизни.
Формулировка находки всегда одна — «здесь наш путь оказался дороже, почему?». Не всякий
не-платформенный apply плох: аварийный ручной откат в инциденте законен, и хорошая платформа
предусматривает его явно (инциденты);
отличать надо редкий аварийный доступ с записью и разбором от повседневного. Нет следов —
нет измерения: если аудит не включён, метки владельца не проставляются автоматически, а роли
не инвентаризуются, вы просто не знаете своего принятия — и это первая работа, а не десятая
(инфраструктура как API,
безопасность по умолчанию).
Воронка принятия: четыре разные проблемы под одним числом
«Принятие 60 %» — бесполезное число: непонятно, что чинить. Полезен разрез по когорте: берём все сервисы, заведённые за квартал, и смотрим, где они отваливаются.
Каждая ступень чинится своим инструментом, и путать их дорого: не знают — коммуникация и документация в момент нужды, а не в вики; начали и застряли — первый день, доступы, понятные ошибки, время до первого выката (опыт разработчика); ушли после инцидента — надёжность и отлаживаемость платформы, то есть SLO, а не функции (SLI и SLO); держат запасной путь — доверие, которое чинится годами и ломается за один вечер. Считать воронку удобно из событий, которые у вас и так есть: создание репозитория, первый выкат платформой, обходы из аудита.
"""Когортная воронка принятия. O(n) по числу событий, память O(k) по числу
сервисов; вид события — created / platform_deploy / bypass_write."""
from collections import defaultdict
from datetime import date, timedelta
def funnel(events: list[tuple[str, str, date]], start: date, window: int = 90):
by_service = defaultdict(list)
for service, kind, at in events:
by_service[service].append((kind, at))
end, stages = start + timedelta(days=90), defaultdict(int)
for evs in by_service.values():
created = next((at for k, at in evs if k == "created"), None)
if created is None or not (start <= created < end):
continue # не наша когорта
stages["создан"] += 1
horizon = created + timedelta(days=window)
deploys = [at for k, at in evs if k == "platform_deploy" and at <= horizon]
bypass = [at for k, at in evs if k == "bypass_write" and at <= horizon]
if not deploys:
continue # отвал на первом дне
stages["дошёл до прода платформой"] += 1
# Жив: есть выкат платформой во второй половине окна наблюдения.
if any(at >= created + timedelta(days=window // 2) for at in deploys):
stages["жив через 90 дней"] += 1
# Опирается: последние 30 дней окна — ни одной записи мимо платформы.
if not any(at >= horizon - timedelta(days=30) for at in bypass):
stages["опирается, запасного пути нет"] += 1
return dict(stages)
Ключевое отличие от отчётной метрики: сервис попадает в верхнюю ступень один раз и остаётся в когорте навсегда — воронку нельзя улучшить, добавив в знаменатель новые подключения. Метрики покрытия, глубины, свежести и добровольной доли — Платформа как продукт; дерево метрик — метрики продукта.
Восемь причин обхода и восемь разных лекарств
Одинаковый симптом — «команда выкатывается мимо» — имеет разные причины, и лечение у них не пересекается. Диагностика начинается с вопроса «что именно произошло в тот день».
| Причина | Диагностический признак | Что делать | Чего делать нельзя |
|---|---|---|---|
| Пробел в возможностях | обход воспроизводим: тот же шаг падает у всех, кому нужна эта штука | закрыть функцией или дать люк с указанием причины | обещать «в следующем квартале» третий раз |
| Задержка поддержки | обход в пятницу, тикет закрыт в понедельник | самообслуживание с TTL, дежурство в рабочие часы пользователей | ужесточать SLA на бумаге |
| Недоверие после инцидента | обход начался в конкретную дату, до неё команда была на платформе | разбор с командой, публичный постмортем, аварийный режим | делать вид, что инцидента не было |
| Непрозрачность | «мы не понимали, что происходит, и не могли отладить» | логи пайплайна, понятные коды ошибок, локальное воспроизведение шага | добавлять документацию вместо диагностики |
| Когнитивная нагрузка | обходят новички и маленькие команды, большие — нет | сузить путь по умолчанию, спрятать редкие опции | «мы же всё описали в вики» |
| Производительность | обход коррелирует с p95 сборки, а не с функциями | бюджет времени пайплайна, кеши, параллельность (конвейер) | считать среднее и радоваться |
| Организационные стимулы | у команды квартальная цель, где платформа не учтена | договориться с руководством о цене миграции в плане | требовать «сознательности» |
| Незнание | функция есть год, команда о ней не слышала | заметность в момент нужды: подсказка в CLI, в ошибке, в шаблоне | винить пользователя |
Последняя строчка встречается чаще, чем кажется: в компании на сорок команд у платформы нет канала, который читают все. Полезная эвристика — функция существует с того дня, когда её видно из инструмента, а не с того, когда она описана.
или стал нормой?"} B -- "разовый, есть запись" --> C["Аварийный доступ отработал;
проверить, был ли разбор"] B -- "норма" --> D{"Что не сработало
в первый раз?"} D -- "функции не было" --> E{"Нужна трём
и более командам?"} E -- "да" --> F["В бэклог платформы
со сроком и владельцем"] E -- "нет" --> G["Люк с причиной,
владельцем и сроком"] D -- "ждать было
дольше срока" --> H["Чинить задержку:
самообслуживание, TTL, дежурство"] D -- "подвела
в инциденте" --> I["Постмортем с командой,
SLO, аварийный режим"] D -- "не смогли отладить,
не знали о функции" --> J["Диагностируемость и заметность
в инструменте, а не в вики"] D -- "цели команды
не включают платформу" --> L["Разговор с руководством:
миграция в план"] F --> M{"Пока чиним — обход
остаётся легальным?"} G --> M H --> M M -- "да, с записью и сроком" --> N["Реестр отклонений: виден,
считаем, пересматриваем"] M -- "нет, запрещаем" --> O["Обход уходит в тень,
измерение ломается"]
Нижняя развилка — самая важная. Пока пробел не закрыт, у команды ровно два варианта: легальное зарегистрированное отклонение или нелегальный невидимый обход. Третьего нет, и выбираете здесь вы.
Что чинить первым: обходы не равны друг другу
Возвращать все команды одновременно нельзя — не хватит ни людей, ни терпения пользователей. Приоритизация идёт по двум осям: чем рискует компания и сколько стоит вернуть.
Левый верхний угол — высокий риск при дешёвой починке: отозвать долгоживущие роли, заменив их выдачей доступа по запросу, перенести секреты в хранилище. Это делается первым и даёт быструю победу, потому что команде тоже выгодно. Правый верхний — дорогие и рискованные: своя система выката, отдельный контур; нужен план на квартал и бюджет, а не письмо с требованием. Правый нижний — кандидаты на легализацию: кластер команды машинного обучения с GPU и своим планировщиком может быть нормой на годы, а попытка «унифицировать» съест квартал и испортит отношения. Левый нижний — не трогать (точки воздействия, приоритизация).
Команда, которой золотой путь не подходит
Плохих ответов на этот вопрос два: «подстроим путь под них» (путь разбухает и портится для остальных) и «пусть терпят» (получаете тот же обход, только скрытый). Хороших — четыре, и выбор определяется тем, сколько команд в похожей ситуации.
- Расширить путь. Потребность есть у трёх и более команд, и поведение при изменениях у них совпадает: это не исключение, а недостающая функция.
- Дать люк. Потребность настоящая, но одна: команда подменяет часть пути своей реализацией, оставаясь на платформе во всём остальном (абстракции и люки).
- Признать второй путь. Класс нагрузки не ложится в общую модель — пакетная обработка на GPU, стриминг, монолит с особым запуском. Это явное решение с владельцем и своей ценой владения, а не «они там как-то сами».
- Отпустить с контрактом. Команда уходит целиком, но берёт обязательства, которые платформа выполняла за неё: подпись артефактов, метки владельца, метрики в общий сбор, ротация секретов, дежурство. Контракт письменный и проверяемый автоматикой.
Во всех четырёх случаях отклонение регистрируется, а не живёт в устной договорённости.
# registry/deviations/checkout-deploy.yaml — читается автоматикой;
# найденный обход без такой записи = инцидент процесса, а не вина человека.
service: checkout
kind: deviation # deviation | hatch | second_path | exit_contract
scope: deploy # какой участок пути заменён
reason: "нужно переключать схему БД и код в одном окне; платформенный выкат
не умеет двухфазную схему (задача PLAT-812)"
owner: team-checkout
review_at: 2026-08-18 # срок обязателен: отклонение без срока — это форк
compensating_controls: # что команда делает вместо платформенных гарантий
- артефакт подписывается общим шагом sign-artifact
- метки owner/service в манифесте, проверяются политикой
- выкаты пишутся в общий журнал изменений через API платформы
platform_commitment: { task: PLAT-812, eta_quarter: 2026Q3 }
У отклонения есть жизненный цикл, и вести его надо как технический долг (технический долг).
срок и владелец назначены Запрошено --> Отклонено: путь покрывает случай,
помогаем перейти Действует --> НаПересмотре: наступил review_at НаПересмотре --> Закрыто: пробел закрыт,
команда вернулась НаПересмотре --> Продлено: пробел не закрыт,
обязательство обновлено НаПересмотре --> ВторойПуть: таких команд много,
признаём отдельный путь Продлено --> НаПересмотре: следующий срок Продлено --> Просрочено: продлили молча,
владельца не нашли Закрыто --> [*] ВторойПуть --> [*]
Состояние Просрочено — метрика здоровья платформы, а не команды: рост просроченных отклонений
означает, что платформа систематически не закрывает обещанное. Пустой реестр тоже плохой знак —
он означает не отсутствие обходов, а отсутствие их видимости.
Мандат: когда он честен и что он ломает
Мандат — распоряжение руководства «всем перейти на платформу». Он работает: покрытие становится стопроцентным за квартал. Но он меняет измеряемую величину — после мандата вы измеряете послушание, а не полезность. Мандат честен при трёх условиях одновременно:
- Он про инварианты, а не про удобство. Требовать подписи артефактов, отсутствия долгоживущих ключей и меток владельца законно: это нужно компании независимо от вкусов команды. Требовать «использовать наш YAML» — нет.
- Путь перехода существует и проверен на нескольких командах. Мандат без работающего пути — это налог: команды тратят время, получают меньше, чем имели, и помнят об этом годами.
- Миграцию делает платформа, а не сорок команд. Тот, кто требует изменения, приносит патч (миграции, Software Engineering at Google, гл. 22).
Работает лучше мандата формулировка требуем свойства, не требуем реализации: компании нужны подписанный артефакт, известный владелец, метрики в общем сборе и отсутствие постоянных ключей — а как команда этого достигает, её дело. Золотой путь просто даёт всё это бесплатно, поэтому им и пользуются; и доля выбравших путь при наличии альтернативы остаётся честной метрикой (золотой путь, границы команд). Побочный эффект мандата — потеря переговорной позиции: пока команды приходят добровольно, платформа обосновывает бюджет принятием, после приказа принятие перестаёт быть аргументом.
Депрекация старого пути — единственный честный финал
Принятие не заканчивается ростом кривой. Пока старый путь жив, компания платит за оба: платформа поддерживает новое, кто-то поддерживает старое, экономия не наступает никогда. Закрытие старого пути — отдельный проект со своим планом.
- Сначала пробелы, потом дата. Объявление даты при нерешённых блокерах неизбежно продлевается, и следующему объявлению никто не поверит.
- Миграцию делает платформа. Автопатч с пройденными тестами и просьбой смержить — это единицы часов чужого времени; задача в бэклоге команды — квартал ожидания.
- Окно объявляется в календарных днях и не сдвигается назад. 90 дней — разумный минимум (политика устаревания Kubernetes как образец дисциплины).
- Последние 10 % стоят как первые 60 %. Отстающие — не ленивые, а те, у кого настоящая техническая причина; их разбирают поимённо, а после отключения обязателен разбор: не сумевшие перейти — источник требований к следующей версии пути.
Экономика принятия: где платформа превращается в налог
Платформенная команда не пишет продукт — значит, обязана окупаться сэкономленным временем других. Три инженера платформы это примерно 450 рабочих часов в месяц, не пошедших в продукт, и экономия считается только по тем командам, кто действительно на платформе: команда с запасным скриптом платит за оба пути сразу и не экономит ничего. Расчёт для компании на 20 продуктовых команд:
| Величина | Значение | Комментарий |
|---|---|---|
| Стоимость платформы | 450 ч/мес | 3 инженера |
| Экономия на команду при полном использовании | 30 ч/мес | выкаты, окружения, доступы, дежурство |
| Принятие «опирается» | 40 %, то есть 8 команд | нижняя ступень воронки, а не покрытие |
| Фактическая экономия | 8 × 30 = 240 ч/мес | почти вдвое меньше стоимости |
| Точка окупаемости | 15 команд на нижней ступени | при тех же 30 ч экономии |
Вывод неприятный и полезный: рост принятия дешевле роста функциональности. Довести до нижней ступени ещё семь уже подключённых команд — работа с задержками, надёжностью и доверием; она не требует новых компонентов, зато двигает экономику сразу. Новая функция, наоборот, поднимает стоимость и отодвигает точку окупаемости вправо. Отсюда два правила: бюджет принятия закладывается заранее (здоровая пропорция — 20–30 % времени команды на поддержку, миграции и работу с людьми; не заложите — всё равно потратите, но за счёт сорванных обещаний, платформенная команда) и у каждого компонента есть порог выключения, сформулированный заранее: «если через два квартала этим пользуется меньше трёх команд — закрываем». Закрыть невостребованный компонент не поражение, а высвобождение людей. Полная стоимость с учётом обходов и обучения — Стоимость.
Типовые провалы глазами принятия
Три классических провала (разбор — Платформа как продукт и Абстракции) имеют сигнатуры в метриках принятия: по ним диагноз ставится раньше, чем провал станет очевиден.
Обёртка над облаком, которая только мешает. Сигнатура: высокое покрытие при высокой доле люков и растущем числе тикетов «нужна опция, которой нет в вашем YAML». Проверка: посчитайте, сколько решений обёртка убрала у инженера; если он всё так же выбирает память, лимиты и пробы, только в другом синтаксисе и через посредника, вы добавили косвенность и очередь.
Портал, которым никто не пользуется. Сигнатура: посещаемость есть, доля действий близка к нулю, меньше половины карточек обновились автоматически за месяц, дежурный не открыл портал в инциденте ни разу. Портал отражает принятие, но не создаёт его: команда, обходящая выкат, будет обходить его и с красивым каталогом.
Абстракция поверх трёх разных потребностей. Сигнатура: конфигурации расходятся, растёт число флагов, в поддержку идут вопросы «как заставить это вести себя как раньше». Метрика-индикатор — разброс реально встречающихся комбинаций флагов и доля запросов, требующих изменения общего кода: когда каждая вторая просьба ломает третьего, вы обслуживаете три задачи одним интерфейсом.
Антипаттерны кампании принятия
- Доска позора. Таблица «принятие по командам» без контекста превращает измерение в политику: через месяц данные подкручены, обходы спрятаны.
- Принятие как OKR платформенной команды. Метрика, которую двигает административно тот, кто за неё отчитывается, перестаёт быть метрикой (закон Гудхарта). Цель — сэкономленное время пользователей, принятие — ведущий индикатор.
- Геймификация. Значки и «уровни зрелости сервиса» дают всплеск и обвал: работает до момента, когда команда понимает, что уровень ни на что не влияет.
- Принудительное обновление шаблона. Массовый автопатч без прогона тестов и без права отложить — быстрейший способ сжечь доверие: одна поломка прода автоматикой платформы стоит года объяснений.
- Продажи вместо починки. Евангелизм и «дни платформы» при неисправленных пробелах читаются как издевательство и запоминаются надолго.
- Кампания без пилота на трёх дружественных командах масштабирует ошибку до размеров компании, а молчаливое продление отклонений превращает реестр в кладбище.
- Запрет вместо диагноза: реакция на обход блокировкой доступа до того, как найдена причина, переводит обход в подполье, а вместе с ним — и ваше измерение.
- Миграция чужими руками: сорок задач в сорока бэклогах вместо автопатчей — это сорванный срок отключения старого пути и подорванное доверие к следующему объявлению.
Инструменты и их цена владения
Ни один инструмент не создаёт принятия: в лучшем случае он снижает стоимость платформенного пути, в худшем добавляет свою.
- Backstage — каркас портала: каталог и плагины ценой 0,5–1 постоянного инженера. Отвечает на вопрос «где посмотреть» и ни на один вопрос из воронки (внедрение).
- Kubernetes — общий субстрат выката: снижает стоимость единообразия и повышает стоимость входа. То, что для платформы «просто namespace», для продуктовой команды — новая модель отладки, и часть обходов рождается ровно здесь (Kubernetes).
- Terraform и Crossplane двигают ступень «дошёл до прода», если есть предпросмотр и понятные ошибки; иначе это ещё один язык, в котором надо разбираться (IaC).
- Хранилище секретов и выдача доступов по запросу — почти единственная категория, окупающаяся на принятии сразу: убирает долгоживущие ключи, главный технический источник обходов (секреты).
Правило выбора: считайте цену владения в постоянных людях и спрашивайте, какую ступень воронки инструмент двигает. Нет ответа — это покупка инструмента вместо решения задачи (Choose Boring Technology).
Что мерить
| Метрика | Как считать | О чём говорит |
|---|---|---|
| Доля обходов по записям | изменяющие операции не платформенным принципалом / все, разрез по командам | базовая честная метрика; растёт первой при деградации |
| Нижняя ступень воронки | сервисы без обходов за последние 30 дней окна / когорта | реальное принятие; только оно даёт экономию |
| Время до первого выката | медиана и p90 от создания репозитория | стоимость входа, чинит ступень «застряли» |
| Время ответа поддержки p90 | по тикетам, требующим решения платформы | главный источник обходов «по срокам» |
| Отклонения с истёкшим сроком | из реестра | обещания платформы, которые не выполняются |
| Возвраты | команды, вернувшиеся с обхода за квартал | единственное доказательство, что лечение работает |
| Добровольная доля | команды с реальным выбором, выбравшие платформу / все такие команды | не портится мандатом |
| Экономия против стоимости | часы экономии по нижней ступени против часов платформенной команды | ответ на вопрос «платформа или налог» |
И три ошибки, которые встречаются чаще прочих: мерить принятие по счётчикам платформы; называть обходящие команды нарушителями; выдавать отклонения без срока и владельца, то есть узаконивать вечные форки. Четвёртая — пытаться вернуть вообще все обходы: часть из них дешевле легализовать навсегда, и умение это признать отличает платформу от бюрократии.
Мини-итог
- Обход — не саботаж, а результат честного сравнения двух путей под сроком: издержки платит компания, а выбирает инженер, поэтому его арифметика сходится. И он невидим в метриках платформы по построению — искать надо в аудите облака, конфигах CI, реестре ролей и счёте за облако, относясь к находкам как к исследованию, а не к суду.
- Одно число «принятие» скрывает четыре разные проблемы: не знают, застряли в первый день, ушли после инцидента, держат запасной путь. Экономия считается только по нижней ступени.
- У восьми причин обхода восемь разных лекарств; самая частая причина — не отсутствие функции, а разрыв между сроком пользователя и сроком поддержки.
- Команде, которой путь не подходит, полагается один из четырёх ответов: расширить путь, дать люк, признать второй путь, отпустить с проверяемым контрактом. Все четыре регистрируются со сроком и владельцем; отклонение без срока — это форк.
- Мандат легитимен только на инварианты, при работающем пути и миграции силами платформы: он покупает покрытие ценой сигнала и переговорной позиции. И принятие не закончено, пока жив старый путь, — закрытие это проект с датой, автопатчами и поимённой работой с последними десятью процентами.
- Рост принятия дешевле роста функциональности: он двигает окупаемость сразу, новая функция отодвигает её вправо. Компонент без пользователей за два квартала честнее закрыть.
Источники
- DORA Research 2024 — раздел о платформенной инженерии: рост производительности при неоднозначном влиянии на стабильность, роль принятия.
- M. Skelton, M. Pais. Team Topologies, IT Revolution, 2019 — «тончайшая жизнеспособная платформа» и платформа как продукт с добровольными пользователями.
- C. Fournier, I. Nowland. Platform Engineering, O’Reilly, 2025 — принятие, миграции и разговор с руководством.
- G. Hohpe. Platform Strategy, 2023 — экономика платформ. E. Bottcher. What I Talk About When I Talk About Platforms, 2018 — определение платформы через добровольное потребление.
- CNCF TAG App Delivery. Platforms White Paper и Platform Engineering Maturity Model. T. Winters и др. Software Engineering at Google, гл. 22 Large-Scale Changes — «изменение приносит тот, кто его требует».
- Spotify. Golden Paths, 2020. Netflix. Full Cycle Developers, 2018 — «paved road» как рекомендация, а не принуждение. N. Forsgren и др. The SPACE of Developer Productivity, ACM Queue, 2021. E. Rogers. Diffusion of Innovations, 5-е изд. — «отстающие» как рациональные агенты.
- Kubernetes Deprecation Policy, Backstage: Adopting, D. McKinley. Choose Boring Technology, 2015.
Что дальше
Мы разобрали принятие как инженерную дисциплину: как увидеть обходы, понять их причину, вернуть команды без принуждения и честно закрыть то, что вернуть невозможно. Всё это — работа с существующей платформой в компании, где команд достаточно, чтобы арифметика сходилась. Остался самый практичный вопрос: что делать, если команд пять, инженеров двадцать, а слово «платформа» уже произнесли на планировании. Ответ начинается не с выбора инструмента, а с честного «пока не надо» — и с понимания, какие два-три куска пути окупаются даже в маленькой компании.
Платформа в небольшой компании: с чего начать и когда не начинать