Trunk-based development

Дисциплина интеграции как предусловие современной разработки

19 апреля 2026

Гайд по выбору

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

Что такое TBD и чем он не является

Trunk-based development - практика, при которой все инженеры коммитят в общую ветку (trunk, main) как минимум раз в день. Ветки короткоживущие: обычно несколько часов, максимум 1-2 дня. После merge в trunk ветка удаляется.

Что TBD не:

Контраст с GitFlow. GitFlow (Vincent Driessen, 2010) - модель с develop, feature, release, hotfix ветками, долгими интеграционными циклами. Создан под контекст, где релизы происходят не ежедневно - в некоторых случаях это 2-4 раза в год, но чаще интервалы заметно короче (недели или месяцы). Packaged software, open-source-проекты с большим фоном внешних contributors - типичные кейсы применения. Для продуктовых команд с daily deploys GitFlow создает постоянные merge-конфликты и замедляет доставку. В 2020 году сам автор GitFlow признал, что модель не подходит для continuous-deployment окружений.

TBD - не про ветки, а про дисциплину интеграции

Смысл TBD - частое слияние кода в общую ветку. Ветки - деталь реализации. Команда может технически использовать короткие feature branches, но если ветки живут часами и сливаются сразу после review - это TBD.

Continuous Integration в оригинальном смысле Martin Fowler - это не «мы купили Jenkins» или «у нас зеленый CI-pipeline». Это практика: каждый разработчик интегрирует свои изменения в trunk как минимум раз в день. Автоматизация CI-сервера помогает поддерживать эту практику, но не заменяет частую интеграцию.

CI-сервер и практика CI - разные вещи. Команда с идеальным зеленым pipeline, но долго висящими feature branches и редкими merge в trunk, не практикует CI в исходном смысле. Автоматизация обслуживает дисциплину частой интеграции, не заменяет ее.

Условия, делающие TBD возможным

TBD не работает декларативно. Нужен фундамент.

Зеленый CI. Быстрый (в пределах 10-15 минут для большинства сценариев), надежный (не флаки), on-demand. Если CI падает часто по посторонним причинам, инженеры перестают доверять сигналу и либо игнорируют, либо откладывают интеграцию. Любая деградация времени или стабильности CI - немедленный приоритет для фикса.

Комплексное тестирование. Unit-тесты покрывают логику, integration-тесты проверяют взаимодействия, end-to-end тесты - критические пользовательские сценарии. Без тестов merge в trunk - это ставка на «вроде работает» без сигнала. Покрытие помогает находить непроверенный код, но целевой уровень нужно выбирать вместе с рисками и качеством тестов.

Feature flags. Архитектурное предусловие. Позволяют мержить неготовую функциональность, скрывая ее от пользователей. Незавершенные изменения нужно интегрировать так, чтобы они не нарушали работу основной ветки. Флаги помогают скрыть новое поведение; иногда достаточно разделить работу на безопасные подготовительные шаги. Разделение deploy и release (следующая секция) - эффект feature flags. Подробнее в статье «Фиче-тогглы».

Дисциплина code review. Ревью не должно задерживать интеграцию изменений. Практики: SLA на review (обычно в пределах 4 часов рабочего дня), pair programming как альтернатива PR-review для некоторых типов задач, четкие правила - что блокирует merge, что оставляется как follow-up. Долго висящий PR - сам по себе антипаттерн TBD.

Готовность откатывать быстро. TBD подразумевает много мелких релизов. Часть из них будет с проблемами. Инфраструктура должна позволять откатиться за минуты, не за часы - Kubernetes rollback, blue-green deploys, canary с автоматическим откатом при росте ошибок. Это важный слой, но его не стоит путать с продуктовыми ошибками: неверная формула скидки, баг в UI, неверное поведение фичи. Для них откат версии кода - избыточная мера и часто вредная (откатится все, что было в версии, включая исправления других команд). Продуктовые ошибки выключаются через feature flag внутри актуальной версии кода: kill-switch на проблемный функционал, fallback на предыдущее поведение, откат раскатки без отката кода. Два разных механизма для двух разных классов проблем.

Разделение deploy и release

Самая распространенная ошибка - считать, что deploy (доставка кода в production) и release (открытие функционала пользователям) - одно и то же. В мире TBD это разные вещи.

Deploy происходит постоянно: каждый merge в trunk может попадать в production в течение минут или часов. Инженеры видят свой код в проде быстро, получают быстрый feedback на реальные условия.

Release происходит on-demand: функционал скрыт за feature flags, открывается, когда продукт и бизнес готовы. Раскатка может идти по когортам (1% пользователей, потом 10%, потом 100%), A/B-тестам, географии, типу клиентов.

Разделение дает несколько эффектов:

Если незавершенное поведение сразу доступно пользователям, интеграция изменений может задерживаться до готовности всей функции. Разделение деплоя и включения помогает этого избежать. Подробнее - в статье «Фиче-тогглы».

Личный опыт: почему «просто мержить в master» не сработало

История из практики.

Декларация. Команда решила перейти на TBD. Объявили: мержим в master, чем меньше живут ветки - тем лучше. Инфраструктурных изменений не сделали - полагались на дисциплину разработчиков.

Что пошло не так. Декларация без инфраструктуры не работает. Через несколько недель выяснилось:

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

Результат. Через несколько недель в канале всплыли системные паттерны: «взял стенд, потому что не умею работать с флагами в этом модуле», «взял, потому что дизайн не позволяет - слишком много state», «взял для ручного регресса» - и много случаев, где стенд был не нужен. Проблемы перестали быть невидимыми. Инженеры стали замечать, когда их кейс можно было закрыть флагом, и закладывать это в дизайн с самого начала. Использование стендов естественно сместилось на случаи, где они действительно нужны - изменения инфраструктуры или критичные флоу с ручным регрессом. В течение 2-3 месяцев merge в master стал доминирующей практикой.

Следующая проблема. Успех TBD принес свою головную боль: количество feature flags стало расти быстро. Инженеры стали закладывать флаг под каждую нетривиальную задачу, и через полгода их накопились сотни. Часть - давно раскатанные на 100%, но код с if-ветками жил дальше и добавлял шума при чтении. Часть - забытые в проде в выключенном состоянии, никто не помнил, что они делали. Несколько раз столкнулись с ситуацией: баг чиним через флаг, флаг уже существует под другое, включение триггерит поведение из давно забытой фичи.

Пришлось вводить практику контроля. Каждый флаг заводится с expiration-датой и owner-ом. В CI и дашбордах - список «просроченных» флагов с ответственными. Регулярный cleanup-спринт раз в квартал: раскатанные удаляются, забытые расследуются. Без этой дисциплины флаговое хозяйство превращается в вторую техническую задолженность, которая со временем перевешивает пользу от TBD.

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

Инженерная польза для разработчика

TBD часто презентуется как выгода для организации (быстрая доставка, меньше рисков). Важная часть, которую не всегда проговаривают - это выгодно самому инженеру.

Случай из практики - сезонный бизнес с freezes. Есть отрасли, где четыре раза в год вводится freeze на деплой: в пиковые периоды трафика весь production замораживается по изменениям на несколько недель. Во время freeze - только хотфиксы в текущий production-тег, feature flags не используем даже как страховку (риск случайно включить что-то в пиковое окно).

После freeze накопленный в trunk код выпускается одним большим релизом. Даже с TBD этот релиз оказывается настолько рискованным, что часто принимается решение разбивать его на несколько виртуальных релизов и катить по частям - по фичам, доменам или когортам пользователей.

Без TBD эта ситуация была бы неуправляемой. Понадобилась бы отдельная интеграционная команда на полную ставку, занимающаяся мержем команд-ветвлений обратно в trunk после каждого freeze-периода. И даже с ней merge-конфликты копились бы до состояния, которое лечится переписыванием. TBD превращает freeze в управляемую паузу: в trunk продолжает приходить проверенный код от команд в своей дисциплине, после freeze остается свобода батчить релизы с нужной гранулярностью, не переживая про внутреннюю консистентность.

Когда инженеры видят эти эффекты на своей работе, TBD перестает быть «требованием руководства» и становится удобной практикой.

Scaled TBD: большие команды и монолит

Интуиция подсказывает, что в большой команде TBD сложнее: больше людей коммитят в одну ветку, больше конфликтов. На практике ровно наоборот: чем больше команда, тем критичнее TBD, иначе получается merge-hell.

Арифметика конфликтов. Вероятность конфликта между двумя ветками грубо пропорциональна времени их жизни × частоте изменений в пересекающихся файлах × числу активных веток. При 50 инженерах с долгими ветками получается квадратичный рост интеграционных проблем. Сокращение времени жизни ветки до часов снижает вероятность до приемлемой.

Монолит как особый случай. Большая команда, работающая над монолитом (20-50 инженеров в одном артефакте) - классическая ситуация, где TBD обязателен. В микросервисной архитектуре естественная изоляция: разные команды работают над разными сервисами, пересечения редки. В монолите все работают над одной кодовой базой.

DDD как предусловие для scaled TBD в монолите. Если границы доменов (bounded contexts) не выстроены, инженеры постоянно задевают чужой код. Даже с TBD это дает регулярные конфликты, потому что разные команды пишут в одни и те же модули. Выход - сначала выстроить DDD-границы (подробно в статье «Domain-Driven Design»), потом внедрять TBD. Без DDD масштабированный TBD в монолите дает постоянное взаимное торможение команд.

Release branches для стабилизации. На большом масштабе иногда нужна отдельная ветка для стабилизации кандидата в релиз - несколько дней тестирования, критичных bugfixes, отдельно от основного потока разработки в trunk. Эти release branches короткоживущие (1-2 недели максимум) и принимают только patches, не features. Не путать с feature branches - это разные паттерны с разным назначением.

Scaled TBD - работающая модель для команд в 100-300 инженеров. Google, Facebook, Microsoft - известные примеры использования TBD в крупных монорепозиториях. Требует инвестиций в test infrastructure (быстрые distributed-тесты, selective test execution), но работает.

TBD в эпоху AI-агентов

До 2024 TBD был «лучшей практикой» - рекомендованной, но не обязательной. С 2025-2026 ситуация меняется.

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

Механика ухудшения. В классической модели с feature branches агент генерирует код → появляется PR → review → merge. Если review откладывается, PR висит. В мире агентов PR много (десятки в день от нескольких агентов параллельно). Очередь несмерженных PR растет экспоненциально. Каждый PR, висящий дольше суток, расходится с trunk и требует rebase; rebase генерирует конфликты, которые агент должен разрешить или передать человеку.

Long-lived branches + AI = merge-hell экспоненциально. Если раньше команда могла выжить с «посмотрим на этой неделе PR», теперь накапливается catastrophic backlog. Либо TBD-дисциплина с быстрой интеграцией, либо человеческий review становится несгораемым bottleneck.

Интеграция параллельных изменений. Команды, не практикующие TBD, в 2026 упираются в потолок при попытке интегрировать AI-агентов. Даже корректный код агента может долго ждать интеграции в общую ветку.

TBD - предусловие эффективного использования AI-агентов, не следствие. Команды, которые внедряют агентов до перестройки процесса на TBD, получают рост PR, который не превращается в доставленную ценность: код лежит в очереди на review.

Как агент работает в TBD + spec-driven режиме

Появление AI-агентов не отменяет TBD, а заставляет переосмыслить где и когда происходит каждый review. Spec-driven development (Spec Kit, BMAD Method, JetBrains Junie, Amazon Kiro) задает последовательность фаз, где каждая фаза становится контрольной точкой перед следующей. TBD обеспечивает дисциплину интеграции готовых результатов обратно в trunk.

Фазы spec-driven workflow и гейты review

Канонический поток на примере Spec Kit - шесть команд:

  1. /speckit.constitution - установить принципы проекта (делается один раз на проект, не на задачу).
  2. /speckit.specify. Агент пишет спецификацию на языке бизнеса из короткого prompt. Human review: соответствие требованиям продукта, полнота охвата edge-cases, маркированные unknowns. Гейт: spec.md одобрен перед переходом к plan.
  3. /speckit.clarify (опционально, но рекомендуется). Агент задает уточняющие вопросы по недостаточно специфицированным областям, spec.md дополняется.
  4. /speckit.plan. Агент пишет план реализации: стек, архитектура, data model, выбор библиотек. Human review: соответствие общей архитектуре, миграционные риски, безопасность, переиспользование. Гейт: plan.md одобрен перед кодом.
  5. /speckit.tasks. Агент декомпозирует план на атомарные задачи с учетом зависимостей. Human review: разумность декомпозиции, порядок, маркировка параллельных задач.
  6. /speckit.implement. Агент выполняет задачи в правильном порядке, гоняет CI в цикле. Spec Kit не экспонирует стратегию PR - выбор между одним PR на всю фичу или несколькими делается командой/инженером отдельно. TBD-дисциплина здесь подсказывает: при возможности дробить на короткоживущие ветки с частыми merge в trunk.

Verify-фаза в Spec Kit не выделена явной командой - проверка происходит через CI, тесты, AI review и human PR review по стандартной TBD-процедуре.

Когда агент открывает PR после implement-фазы, reviewer видит структурированные артефакты: spec.md (что сделано и почему), plan.md (как выбран подход), task-лист с выполненными пунктами, diff кода и тестов. Assumptions агента представлены как structured data в артефактах, а не закопаны в freeform commit messages.

Git worktrees для параллельной работы агентов

Агенты генерируют PR со скоростью, которая требует соответствующей git-стратегии. Стандартная практика 2026:

Split-and-merge: multi-agent + TBD

Для крупной задачи агенты работают параллельно:

При декомпозиции стоит уменьшать число файлов, которые приходится менять одновременно в разных задачах. DDD-границы и модульность критичны - без них sub-agents задевают друг друга, merge-конфликты возвращаются. Это еще один аргумент за предварительную работу над границами (см. «Domain-Driven Design»).

Где человек остается в цикле

Несмотря на автоматизацию, human review остается в нескольких точках:

Тулинг 2026 уже поддерживает эту модель: Spec Kit с intake-фазами и структурированными артефактами, Amazon Kiro, JetBrains Junie, Claude Code с AGENTS.md. Разбор экосистемы - в статье «SDLC для AI-агентов».

Code review в мире TBD + AI

Это, пожалуй, самая перестраиваемая часть процесса. Стандартная модель review (человек ревьюит весь diff line-by-line перед merge) перестает масштабироваться при росте количества PR.

Новая модель 2026

  1. AI review первым. Когда PR открыт, AI-tool (CodeRabbit, Qodo, встроенные GitHub/GitLab AI-reviewers) автоматически анализирует код за секунды. Находит типовые проблемы: security, performance, coding standards, bugs. Разработчик исправляет AI-найденные issues до человеческого review.
  2. Человек фокусируется на высокоуровневом. Архитектурные решения, business logic correctness, user experience implications. Не тратит время на catch'инг того, что ловит AI.
  3. Plan-first / spec-first подход. Для больших изменений - сначала план или спека, которую человек ревьюит. Если план OK, агент пишет код по нему. Review кода становится проверкой соответствия плану, не свободным чтением. У Anthropic в Claude Code это /plan mode.
  4. Agentic quality control. AI reviewing AI output становится стандартом. Один агент пишет код, другой проверяет с учетом codebase conventions, security policies, performance patterns. Человек подключается на последнем этапе.

Оценка AI-ревью. Измеряйте время проверки, долю полезных замечаний, пропущенные дефекты и нагрузку на человека. Без этих данных нельзя обещать сокращение времени ревью.

Soft gates vs hard gates

Индустриальная практика: начинать с soft gates (2-3 недели на адаптацию), отслеживать acceptance rate (доля AI findings, которые разработчики принимают как валидные). Когда acceptance rate > 80% - переход на hard gates.

Опасности

Что AI не убрал: роль человека в review

В 2026 году, несмотря на рост AI-tooling, human review не исчез. Изменилось то, что проверяет человек. Классы проблем, которые AI стабильно пропускает и на которых сохраняется человеческий контроль:

Примеры из индустрии (2026)

Даже AI-first компании и вендоры AI-инструментов сохраняют human-in-the-loop в code review. Примеры позиционирования:

DORA 2025 фиксирует интересный сигнал: при adoption AI-tooling 90%+ время review выросло на 91%. Интерпретации разные, но факт - AI не устранил потребность в human review, а часто ее увеличил (больше кода производится, больше нужно смотреть).

Практический вывод. AI review сместил что делает человек - с поиска typo и security-lint в сторону архитектурных и доменных решений - но не убрал человека из цикла. TBD-дисциплина + AI review первым слоем + быстрый human review для архитектурных моментов - работающая модель 2026. Полная автоматизация без human discipline - путь к накоплению скрытых системных проблем.

Антипаттерны

Источники и смежные статьи

Первоисточники

Смежные статьи блога