Review Time: сколько код ждёт проверки
PR открыт в понедельник утром.
Первый комментарий появляется во вторник вечером. Автор отвечает в среду. Ревьюер возвращается в четверг. В пятницу изменение наконец сливается.
Само ревью заняло минут сорок. Но календарно код ждал почти неделю.
Если смотреть только на среднее время ревью, эту проблему легко не заметить.
Одной цифры недостаточно
Review Time лучше разделять на несколько интервалов.
Time to First Review — время от открытия PR до первого содержательного комментария или одобрения.
Показывает, насколько быстро команда вообще начинает проверку. Комментарий бота, запуск CI или автоматическое назначение ревьюера считать не стоит.
Time to Approval — время от открытия PR до получения необходимых approvals.
Сюда входят ожидание, обсуждение и циклы исправлений. Если PR несколько раз возвращается автору, это будет видно именно здесь.
Time to Merge — время от открытия PR до merge.
Кроме ревью, сюда попадают CI, ручной merge, зависимость от других изменений и ожидание релизного окна.
Разница между этими интервалами помогает понять, где именно лежит код.
Почему среднее обманывает
Представим:
девять PR слились за два часа;
один PR висел десять дней.
Среднее значение сгладит ситуацию. Процесс будет выглядеть терпимо, хотя один тип изменений регулярно попадает в очередь на неделю.
Поэтому я бы смотрел не только среднее, но и:
медиану;
85-й или 90-й перцентиль;
долю PR старше выбранного порога;
распределение по размеру и типу изменений;
время до первого содержательного отзыва.
Например, медиана Time to First Review у команды составляет три часа. На первый взгляд всё хорошо.
Но 15% PR ждут больше двух дней.
Значит, проблема не во всём процессе. Нужно искать конкретные репозитории, типы изменений или узких экспертов, возле которых образуется очередь.
Какие сигналы стоит проверить
PR регулярно ждут первого комментария больше рабочего дня;
большая часть ревью проходит через одного человека;
маленькие изменения обрабатываются так же долго, как крупные;
между ответами автора и ревьюера возникают длинные паузы;
PR проходят несколько одинаковых циклов доработки;
approvals уже собраны, но merge происходит значительно позже.
Высокий Review Time может означать что угодно: большой WIP, отсутствие владельца ревью, нехватку экспертизы, слишком крупные PR или архитектурный спор, который начался уже после написания кода.
Иногда причина ещё проще: за создание нового кода разработчика хвалят, а время на помощь коллегам считается отвлечением от работы.
Как не превратить метрику в дубинку
Review Time не нужен для рейтинга «самых медленных ревьюеров».
Количество комментариев тоже ничего не говорит о качестве проверки. А требование мгновенно отвечать на каждый PR быстро приводит к поверхностным approve.
Полезнее смотреть на командный поток:
где изменения чаще всего останавливаются;
сколько времени занимает ожидание, а сколько обсуждение;
какие размеры и типы PR задерживаются;
изменилась ли картина после новых договорённостей.
Из практических шагов можно начать с простого:
договориться о времени первого отзыва;
выделить окна для ревью;
уменьшать размер изменений;
автоматически назначать ревьюеров;
выносить архитектурные вопросы до написания большого PR;
отмечать блокирующие и необязательные комментарии;
показывать старые PR на ежедневном обзоре;
ограничить количество одновременно открытых PR.
Definition of Ready помогает лучше готовить задачи. Working Agreements задают правила ревью. Review Time показывает, работают ли эти договорённости в реальности.
Эта метрика нужна не для того, чтобы люди быстрее ставили approve. Она показывает время, когда готовое изменение лежит без движения.
Что чаще задерживает ваши PR: ожидание первого ревью, долгие обсуждения, исправления или проверки после approval?
PR открыт в понедельник утром.
Первый комментарий появляется во вторник вечером. Автор отвечает в среду. Ревьюер возвращается в четверг. В пятницу изменение наконец сливается.
Само ревью заняло минут сорок. Но календарно код ждал почти неделю.
Если смотреть только на среднее время ревью, эту проблему легко не заметить.
Одной цифры недостаточно
Review Time лучше разделять на несколько интервалов.
Time to First Review — время от открытия PR до первого содержательного комментария или одобрения.
Показывает, насколько быстро команда вообще начинает проверку. Комментарий бота, запуск CI или автоматическое назначение ревьюера считать не стоит.
Time to Approval — время от открытия PR до получения необходимых approvals.
Сюда входят ожидание, обсуждение и циклы исправлений. Если PR несколько раз возвращается автору, это будет видно именно здесь.
Time to Merge — время от открытия PR до merge.
Кроме ревью, сюда попадают CI, ручной merge, зависимость от других изменений и ожидание релизного окна.
Разница между этими интервалами помогает понять, где именно лежит код.
Почему среднее обманывает
Представим:
девять PR слились за два часа;
один PR висел десять дней.
Среднее значение сгладит ситуацию. Процесс будет выглядеть терпимо, хотя один тип изменений регулярно попадает в очередь на неделю.
Поэтому я бы смотрел не только среднее, но и:
медиану;
85-й или 90-й перцентиль;
долю PR старше выбранного порога;
распределение по размеру и типу изменений;
время до первого содержательного отзыва.
Например, медиана Time to First Review у команды составляет три часа. На первый взгляд всё хорошо.
Но 15% PR ждут больше двух дней.
Значит, проблема не во всём процессе. Нужно искать конкретные репозитории, типы изменений или узких экспертов, возле которых образуется очередь.
Какие сигналы стоит проверить
PR регулярно ждут первого комментария больше рабочего дня;
большая часть ревью проходит через одного человека;
маленькие изменения обрабатываются так же долго, как крупные;
между ответами автора и ревьюера возникают длинные паузы;
PR проходят несколько одинаковых циклов доработки;
approvals уже собраны, но merge происходит значительно позже.
Высокий Review Time может означать что угодно: большой WIP, отсутствие владельца ревью, нехватку экспертизы, слишком крупные PR или архитектурный спор, который начался уже после написания кода.
Иногда причина ещё проще: за создание нового кода разработчика хвалят, а время на помощь коллегам считается отвлечением от работы.
Как не превратить метрику в дубинку
Review Time не нужен для рейтинга «самых медленных ревьюеров».
Количество комментариев тоже ничего не говорит о качестве проверки. А требование мгновенно отвечать на каждый PR быстро приводит к поверхностным approve.
Полезнее смотреть на командный поток:
где изменения чаще всего останавливаются;
сколько времени занимает ожидание, а сколько обсуждение;
какие размеры и типы PR задерживаются;
изменилась ли картина после новых договорённостей.
Из практических шагов можно начать с простого:
договориться о времени первого отзыва;
выделить окна для ревью;
уменьшать размер изменений;
автоматически назначать ревьюеров;
выносить архитектурные вопросы до написания большого PR;
отмечать блокирующие и необязательные комментарии;
показывать старые PR на ежедневном обзоре;
ограничить количество одновременно открытых PR.
Definition of Ready помогает лучше готовить задачи. Working Agreements задают правила ревью. Review Time показывает, работают ли эти договорённости в реальности.
Эта метрика нужна не для того, чтобы люди быстрее ставили approve. Она показывает время, когда готовое изменение лежит без движения.
Что чаще задерживает ваши PR: ожидание первого ревью, долгие обсуждения, исправления или проверки после approval?
👍2
«Своя модель» не делает AI-агента своим
Когда в компании обсуждают агентную платформу, разговор часто сводится к двум вариантам:
— поднимаем OpenCode и локальную модель;
— покупаем Claude Code или Codex и ходим во внешний API.
Но это ложный выбор.
Агентный стек — не один продукт. Это минимум пять компонентов:
обвязка × модель × инструменты × идентичность × границы исполнения
И каждый из них может находиться под разным контролем.
Например:
— открытый клиент не делает модель локальной;
— локальная модель не ограничивает права инструментов;
— внутренний MCP не становится безопасным только потому, что он внутренний;
— внешний API необязательно опасен, если контекст фильтруется, а модель не получает прямого доступа к рабочим системам.
Отсюда важный вывод: слово «свой» тоже ничего не объясняет.
Нужно отдельно проверять четыре вещи:
1. Контролируем ли мы исходный код?
2. Эксплуатируем ли компонент самостоятельно?
3. Контролируем ли путь и хранение данных?
4. Обеспечиваются ли права и запреты технически?
Особенно интересна рекомендуемая корпоративная архитектура. Не обязательно форкать каждого агента и самостоятельно размещать все модели. Гораздо важнее владеть двумя точками контроля.
Модельный шлюз решает:
— какие данные можно отправлять;
— в какую модель и регион;
— разрешён ли резервный маршрут;
— сколько может стоить задача.
Инструментальный шлюз решает:
— кто инициировал действие;
— что именно разрешено изменить;
— от чьего имени выполняется операция;
— нужна ли дополнительная проверка.
Это критично, потому что атакуют обычно не саму модель, а цепочку полномочий.
Агент прочитал README, письмо или задачу в Jira. Внутри оказалась вредоносная инструкция. Модель восприняла её как часть контекста и вызвала инструмент с рабочими правами.
Просьба в системном промпте «не отправляй секреты» здесь не поможет.
Поэтому модель может предложить действие, но не должна сама определять, имеет ли право его выполнить. Это задача IAM, политики и инструментального шлюза.
Что я бы проверил перед внедрением агента в команду:
— где реально исполняются команды;
— куда уходят промпты, результаты инструментов и логи;
— есть ли общие долгоживущие токены;
— разделены ли чтение, подготовка изменения и запись;
— закрыт ли исходящий трафик по умолчанию;
— что произойдёт при недоступности локальной модели;
— можно ли отдельно отключить модель, MCP или записывающий инструмент;
— связывает ли аудит пользователя, модель, инструмент и фактический результат.
И ещё один практический совет: пилот стоит начинать не с максимальной автономности.
Один репозиторий. Один класс данных. Чтение или создание merge request вместо прямой записи. Никаких широких рабочих токенов.
Цель пилота — не доказать, что агент умеет вызывать двадцать инструментов. Цель — понять, сколько полезной работы команда принимает, как часто агент ошибается и сколько времени уходит на проверку.
Безопасность и суверенность — свойства всей цепочки, а не логотипа модели. Владеть в первую очередь нужно местами, где пересекаются данные, полномочия и необратимые действия.
По мотивам разбора восьми конфигураций агентного стека Александра Поломодова.
#AI #AI4SDLC #TeamLead #EngineeringManagement #MCP
Когда в компании обсуждают агентную платформу, разговор часто сводится к двум вариантам:
— поднимаем OpenCode и локальную модель;
— покупаем Claude Code или Codex и ходим во внешний API.
Но это ложный выбор.
Агентный стек — не один продукт. Это минимум пять компонентов:
обвязка × модель × инструменты × идентичность × границы исполнения
И каждый из них может находиться под разным контролем.
Например:
— открытый клиент не делает модель локальной;
— локальная модель не ограничивает права инструментов;
— внутренний MCP не становится безопасным только потому, что он внутренний;
— внешний API необязательно опасен, если контекст фильтруется, а модель не получает прямого доступа к рабочим системам.
Отсюда важный вывод: слово «свой» тоже ничего не объясняет.
Нужно отдельно проверять четыре вещи:
1. Контролируем ли мы исходный код?
2. Эксплуатируем ли компонент самостоятельно?
3. Контролируем ли путь и хранение данных?
4. Обеспечиваются ли права и запреты технически?
Особенно интересна рекомендуемая корпоративная архитектура. Не обязательно форкать каждого агента и самостоятельно размещать все модели. Гораздо важнее владеть двумя точками контроля.
Модельный шлюз решает:
— какие данные можно отправлять;
— в какую модель и регион;
— разрешён ли резервный маршрут;
— сколько может стоить задача.
Инструментальный шлюз решает:
— кто инициировал действие;
— что именно разрешено изменить;
— от чьего имени выполняется операция;
— нужна ли дополнительная проверка.
Это критично, потому что атакуют обычно не саму модель, а цепочку полномочий.
Агент прочитал README, письмо или задачу в Jira. Внутри оказалась вредоносная инструкция. Модель восприняла её как часть контекста и вызвала инструмент с рабочими правами.
Просьба в системном промпте «не отправляй секреты» здесь не поможет.
Поэтому модель может предложить действие, но не должна сама определять, имеет ли право его выполнить. Это задача IAM, политики и инструментального шлюза.
Что я бы проверил перед внедрением агента в команду:
— где реально исполняются команды;
— куда уходят промпты, результаты инструментов и логи;
— есть ли общие долгоживущие токены;
— разделены ли чтение, подготовка изменения и запись;
— закрыт ли исходящий трафик по умолчанию;
— что произойдёт при недоступности локальной модели;
— можно ли отдельно отключить модель, MCP или записывающий инструмент;
— связывает ли аудит пользователя, модель, инструмент и фактический результат.
И ещё один практический совет: пилот стоит начинать не с максимальной автономности.
Один репозиторий. Один класс данных. Чтение или создание merge request вместо прямой записи. Никаких широких рабочих токенов.
Цель пилота — не доказать, что агент умеет вызывать двадцать инструментов. Цель — понять, сколько полезной работы команда принимает, как часто агент ошибается и сколько времени уходит на проверку.
Безопасность и суверенность — свойства всей цепочки, а не логотипа модели. Владеть в первую очередь нужно местами, где пересекаются данные, полномочия и необратимые действия.
По мотивам разбора восьми конфигураций агентного стека Александра Поломодова.
#AI #AI4SDLC #TeamLead #EngineeringManagement #MCP
❤3💯2👍1
Decision Log: как перестать принимать одно и то же решение заново
На встрече команда обсудила три варианта и выбрала B. Через неделю кто-то спрашивает:
— А почему не A? Он же проще.
Обсуждение начинается сначала. Те же аргументы, те же возражения, те же полчаса в календаре.
Проблема обычно не в плохой памяти команды. Просто сохранился итог, но потерялся ход мысли.
Запись «решили делать вариант B» почти бесполезна. Без контекста непонятно:
— какую задачу решали;
— какие варианты рассматривали;
— почему отказались от остальных;
— на каких данных строилось решение;
— с какими последствиями согласились.
Для этого нужен Decision Log — журнал принятых решений.
Это не протокол встречи. Протокол отвечает на вопрос «что обсуждали», а Decision Log — «что решили и почему». В него не нужно переносить всю дискуссию и список выступавших. Достаточно зафиксировать:
— решение;
— дату;
— владельца;
— контекст и ограничения;
— рассмотренные альтернативы;
— причины выбора;
— ожидаемые последствия и риски.
Например:
Хранить Decision Log лучше там, где команда уже работает: в Notion, Confluence, Wiki репозитория или отдельной папке с ADR. Важен не инструмент, а три условия: журнал легко найти, на конкретное решение можно дать ссылку, записи не исчезают в переписке.
Старое решение не становится правильным навсегда. Его стоит пересмотреть, если изменились исходные условия, появились новые данные, проявились неучтённые последствия или наступил заранее указанный срок ревизии.
Но пересмотр должен начинаться не с «мне не нравится вариант B», а с «вот что изменилось с момента, когда мы его выбрали».
DACI помогает команде принять решение. Decision Log не позволяет этому решению через неделю снова превратиться в дискуссию.
На встрече команда обсудила три варианта и выбрала B. Через неделю кто-то спрашивает:
— А почему не A? Он же проще.
Обсуждение начинается сначала. Те же аргументы, те же возражения, те же полчаса в календаре.
Проблема обычно не в плохой памяти команды. Просто сохранился итог, но потерялся ход мысли.
Запись «решили делать вариант B» почти бесполезна. Без контекста непонятно:
— какую задачу решали;
— какие варианты рассматривали;
— почему отказались от остальных;
— на каких данных строилось решение;
— с какими последствиями согласились.
Для этого нужен Decision Log — журнал принятых решений.
Это не протокол встречи. Протокол отвечает на вопрос «что обсуждали», а Decision Log — «что решили и почему». В него не нужно переносить всю дискуссию и список выступавших. Достаточно зафиксировать:
— решение;
— дату;
— владельца;
— контекст и ограничения;
— рассмотренные альтернативы;
— причины выбора;
— ожидаемые последствия и риски.
Например:
Решение: использовать вариант B.
Контекст: запуск через шесть недель, команда не успеет освоить новую технологию.
Альтернативы: A дешевле, C лучше масштабируется.
Почему B: уже есть экспертиза и готовая инфраструктура.
Последствия: через год решение может стать узким местом.
Пересмотреть: если нагрузка вырастет втрое или появится отдельная команда поддержки.
Хранить Decision Log лучше там, где команда уже работает: в Notion, Confluence, Wiki репозитория или отдельной папке с ADR. Важен не инструмент, а три условия: журнал легко найти, на конкретное решение можно дать ссылку, записи не исчезают в переписке.
Старое решение не становится правильным навсегда. Его стоит пересмотреть, если изменились исходные условия, появились новые данные, проявились неучтённые последствия или наступил заранее указанный срок ревизии.
Но пересмотр должен начинаться не с «мне не нравится вариант B», а с «вот что изменилось с момента, когда мы его выбрали».
DACI помогает команде принять решение. Decision Log не позволяет этому решению через неделю снова превратиться в дискуссию.
👍3❤2💯1