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

Почему одна и та же чистка снова и снова возвращается
Повторяющаяся работа по «очистке» редко выглядит драматично. Снова падает тест в той же области. Кто-то третий раз за два месяца чинит кривой сервис. Названия, логирование или обработку ошибок снова «приводят в порядок».
Но важнее не сам фикс, а этот повторяющийся рисунок. Если одна и та же чистка возвращается каждый спринт, у команды не разовая проблема в коде. У неё проблема с решениями, и она постоянно просачивается в код.
Команды часто называют всё это «техническим долгом», будто он живёт только в кодовой базе. Часть его действительно там. Старый код, слабые тесты и поспешные интеграции — это реальность. Но повторяющаяся чистка обычно начинается раньше: когда за областью никто чётко не отвечает, сроки обещают до того, как работу поняли, или продуктовое решение остаётся наполовину принятым.
Неполное решение быстро создаёт лишнюю работу. Один человек думает, что функция временная, другой считает её постоянной, а третий строит решение, опираясь сразу на оба предположения. Код впитывает эту путаницу. Инженеры приводят в порядок поверхность, а на следующем спринте та же неясность всплывает снова.
Обычно этот паттерн легко заметить:
- Одни и те же файлы снова и снова меняются ради «маленьких исправлений».
- Инженеры избегают части продукта, если только не вынуждены к ней прикоснуться.
- После обновления функций баги возвращаются.
- Никто не может сказать, кто решает, когда нужно убирать шероховатости.
Рефакторинг помогает, но он не удержится, если команда продолжает подпитывать систему тем же хаосом. Код ломается заметно. Сначала его ломают командные решения.
Здоровые команды спрашивают не только «Что нам надо почистить?». Они спрашивают: «Почему это вообще дошло до полуготового состояния и кто позволил этому остаться?»
Этот вопрос меняет работу. Вместо того чтобы считать долг случайным износом, вы начинаете видеть цепочку целиком: неясная ответственность ведёт к расплывчатым решениям, расплывчатые решения — к поспешному коду, а поспешный код — к чистке, которая так и не заканчивается.
Где менеджмент создаёт долг, сам того не замечая
Часто долг появляется задолго до того, как кто-то пишет неаккуратный код. Он начинается на встречах, где никто не отвечает за финальное решение, приоритеты меняются по настроению, а сроки называют ещё до того, как команда вообще посмотрела на работу.
Когда у функции нет понятного владельца, мелкие решения остаются размытыми. Дизайн подразумевает одно, разработка предполагает другое, а продукт оставляет крайние случаи открытыми. Команда закрывает пробелы быстрыми заплатками, потому что выпуск всё ещё кажется срочным. Эти заплатки часто живут месяцами.
Размытые приоритеты создают такой же хаос. Если менеджер говорит «это важно», но не может сказать, что важнее всего — скорость, качество, объём или стоимость, — люди решают сами. Один разработчик урезает тесты. Другой пропускает чистку. Третий делает только happy path. Каждое решение по отдельности выглядит разумным. Вместе они создают переделку.
Обычно последовательность выглядит так:
- На встрече с продажами или основателем обещают дату.
- Команда узнаёт о работе уже после того, как обещание стало публичным.
- Объём остаётся размытым, потому что никто не хочет тормозить план.
- Открытые вопросы закрывают временной логикой.
- Команда выпускает работу, а потом весь следующий спринт исправляет то, что сделали в спешке.
Долг — это не только проблема инженерии. Менеджмент создаёт его, когда руководители воспринимают оценку сроков как формальность, а не как входные данные. Как только срок становится важнее оценки, оценка перестаёт быть планом и превращается в тушение пожара.
Неполные продуктовые решения ещё быстрее распространяют долг. Команда слышит «поддерживаем скидки», но никто не определяет правила. Кто может их применять? Можно ли их складывать? Когда они истекают? Инженеры догадываются, поддержка находит исключения, а код снова меняется, когда реальные пользователи упираются в крайние случаи.
Цена — это не только грязный код. Команды теряют доверие к планам. На чистку никогда не остаётся по-настоящему времени, потому что следующее поспешное обещание уже стоит в календаре.
Хороший менеджмент делает меньше размытых запросов, назначает одного владельца на каждое решение и ждёт оценки, прежде чем что-то обещать. Звучит просто. Но это убирает удивительно много повторной чистки.
Как выглядит отсутствие владельца
Команда может писать хороший код и всё равно накапливать долг, если никто не владеет решениями вокруг него. Проблема часто начинается за пределами кодовой базы. Один человек ставит срок, другой определяет функцию, третий утверждает релиз, и никто не отвечает за компромиссы, когда эти решения сталкиваются.
Это проявляется в мелочах, которые дорого обходятся. Проблема в поддержке снова и снова возвращается, но продукт говорит, что поведение «и так достаточно хорошее». Разработка ставит одну заплатку, потом ещё одну через месяц. Дизайн хочет одно, продажи обещали другое, а финальное решение никто не принимает. Общая ответственность звучит вежливо. На практике она часто означает общую вину и медленные исправления.
Инженеры обычно ставят заплатки вокруг открытых вопросов, потому что пользователи не могут ждать идеального ответа. Если команда всё ещё не решила, как работают возвраты или что считать завершённым заказом, кто-то пишет логику, которая в основном работает, и надеется, что бизнес потом всё определит. Потом обычно не наступает. Временное решение становится настоящей системой, а работа с долгом превращается в повторяющуюся чистку, а не в профилактику.
Продуктовая команда может увидеть это на таком простом примере, как доступ к аккаунту. Поддержка хочет быстрый сброс. Безопасность хочет более строгие проверки. Продукт хочет меньше тикетов. Разработка спрашивает, кто отвечает за правила в крайних случаях — например, если у пользователя старый номер телефона и нет доступа к почте. Если никто не отвечает, инженеры строят исключения. Эти исключения расползаются в админку, скрипты поддержки и логи аудита.
Признаки того, что проблема застряла между ролями, легко заметить:
- Люди говорят «мы решили», но к решению не прикреплено одно имя.
- Тикеты кочуют между продуктом, разработкой, поддержкой и продажами без понятного следующего шага.
- Инженеры задают бизнес-вопросы на дейликах и получают частичные ответы.
- Команды снова и снова выпускают обходные решения для одной и той же проблемы.
- Все согласны, что проблема важна, но никто не выделяет время, чтобы закрыть её.
Когда вы видите такие паттерны, код — это только поверхность проблемы. Настоящий пробел — в ответственности за решение. Пока один человек не возьмёт на себя финальную роль, команда будет снова и снова платить за одно и то же недоделанное решение.
Как поспешные обещания превращаются в переделку
Поспешное обещание обычно начинается вне разработки. Основатель говорит потенциальному клиенту: «Сможем отправить на следующей неделе», или продажи отвечают «да» до того, как кто-то вообще запишет объём. Сначала команда получает дату, а определение — потом.
Это давление меняет работу. Команды редко режут видимую часть функции. Они режут тихую работу, которая делает функцию устойчивой после релиза.
Они пропускают более глубокие тесты и проверяют только happy path. Оставляют крайние случаи на потом. Откладывают чистку кода. Выпускают без понятного мониторинга или плана отката.
На бумаге команда уложилась в срок. На деле она заняла время у следующих двух спринтов.
Неясный объём делает ущерб ещё хуже. Запрос вроде «добавьте экспорт» звучит мелко, пока реальные пользователи не начинают спрашивать про права доступа, фильтры, ограничения по размеру файла и логи аудита. Если никто не принимает эти решения заранее, инженеры угадывают, QA проверяет то, что может, а support находит недостающее уже после релиза.
Простой пример показывает этот паттерн. Стартап обещает клиенту кастомную панель до конца месяца. Чтобы успеть к сроку, команда переиспользует старый код запросов, пропускает нагрузочное тестирование и оставляет правила доступа наполовину готовыми. На демо всё выглядит нормально, и все двигаются дальше.
Потом начинается второй проход. Более крупные аккаунты загружают панель слишком медленно. Один клиент видит данные, которые не должен видеть. Финансы говорят, что одна цифра не совпадает с уже используемым отчётом. Теперь команда чинит баги под давлением вместо того, чтобы делать следующую функцию.
Потом приходит третий проход. Инженеры приводят в порядок запросы, добавляют пропущенные тесты, ужесточают права доступа и переписывают части, которые изначально не соответствовали реальной потребности. Первоначальное обещание выглядело как одна поставка, но в итоге создало три раунда работы.
Профилактика долга начинается до первого коммита. Руководителям, которые хотят меньше чистки, нужно замораживать объём, назначать одного владельца и давать команде право возражать против сроков, которые с самого начала не имели смысла.
Простой пример из продуктовой команды
Небольшая SaaS-компания хочет одну функцию: кнопку «приостановить подписку». Продукт говорит, что клиенты просят об этом, отток растёт, и команду нужно выпустить всё до конца месяца. Запрос звучит достаточно ясно, но в нём не хватает деталей, от которых зависит, выдержит ли функция реальное использование.
Никто не фиксирует базовые правила. Можно ли приостанавливать годовой план? Биллинг останавливается сразу или только к следующему продлению? Сохраняют ли приостановленные аккаунты свои данные, участников команды и доступ к API? Что происходит, если у аккаунта уже есть неоплаченный счёт?
Разработка собирает быструю версию за четыре дня. Кнопка меняет статус аккаунта и останавливает письма о продлении. В демо всё работает. Все двигаются дальше.
Проблемы начинаются после запуска:
- На первой неделе клиенты с годовой подпиской нажимают паузу и ждут частичный возврат.
- На второй неделе некоторые приостановленные аккаунты всё ещё используют премиум-функции, потому что одна проверка доступа читает старое поле биллинга.
- На третьей неделе support начинает разбирать злые сообщения по одному.
- На четвёртой неделе финансы находят расхождения в счетах и просят инженеров их объяснить.
Теперь команда делает ту же чистку сразу с трёх сторон. Support пишет ручные ответы. Инженеры ставят заплатки вокруг биллинга и доступа. Продукт принимает поздние решения под давлением. Никто не планировал эту работу, но она заполняет следующий спринт.
В коде, конечно, есть баги, но первая ошибка была раньше. Продуктовые решения остались наполовину готовыми, дату запуска обещали до того, как правила были определены, и никто не владел функцией целиком после релиза.
Команда с ясной ответственностью могла бы притормозить на один лишний день и перечислить недостающие случаи до выпуска. Эта небольшая пауза сэкономила бы часы работы поддержки, исправления возвратов и аварийные патчи. Во многих стартапах долг начинается тогда, когда размытый запрос принимают за готовое решение.
Как проследить долг обратно к решениям
Повторяющаяся чистка оставляет след. Если идти по нему достаточно далеко, обычно находишь поспешное решение, неясного владельца или продуктовый выбор, который так и не был завершён.
Начните с последних двух-трёх месяцев повторных исправлений. Игнорируйте разовые баги. Смотрите на работу, которая возвращается снова: тот же патч в биллинге, тот же скрипт в support, тот же обходной путь во фронтенде после каждого релиза.
Запишите каждый пункт простыми словами. Отметьте, что сломалось, кто это трогал и почему в первый раз команда выбрала обходной путь. Держите формулировки простыми, чтобы люди могли обсуждать проблему, не споря о словах.
Потом сгруппируйте пункты по причинам. У большинства команд всплывают одни и те же кластеры:
- никто не отвечал за область целиком
- кто-то пообещал дату или функцию до того, как команда согласовала объём
- продукт принял частичное решение и оставил крайние случаи открытыми
Такая группировка меняет разговор. Вместо «разработке надо это почистить» вы можете спросить, кто принял первое решение, которое привело к обходному пути.
Найдите первое решение
Для каждого повторного исправления вернитесь к первому моменту, когда команда выбрала скорость вместо ясности. Иногда этот момент очевиден. Основатель пообещал кастомный рабочий процесс, чтобы закрыть сделку. Продакт-менеджер утвердил запуск с известными пробелами. Тимлид разделил ответственность между двумя инженерами, и после релиза ни один из них не почувствовал себя ответственным.
Небольшой пример помогает. Допустим, команда всё время переписывает логику экспорта для разных клиентов. Код может быть грязным, но глубже проблема может быть в том, что продажи обещали кастомные CSV-форматы ещё до того, как продукт решил, что должен включать стандартный экспорт. Долг сидит в коде, но источник — в бизнес-обещании.
Определите следующий шаг
Когда источник найден, запишите следующее решение, которое должна принять команда. Говорите прямо. Назначьте одного владельца. Уберите исключение. Задайте правило для кастомных запросов. Отложите функцию, пока продукт не закроет открытые вопросы.
Затем назначьте одного человека, который закроет каждый открытый пункт. Не команду. Не канал. Одного человека с датой.
Этот последний шаг важнее всего. Команды часто хорошо документируют долг, но всё равно сохраняют его живым, потому что никто не владеет финальным решением. Когда один человек закрывает цикл, повторная чистка начинает заметно снижаться.
Ошибки, которые удерживают долг в живых
Долг остаётся с командой, когда каждый обходной путь считают разовым исключением. Почти никогда это не так. Та же шероховатость возвращается, потому что никто не устранил причину, по которой её вообще разрешили.
Одна из частых ошибок — винить инженеров за каждый обходной путь. Инженеры действительно иногда принимают плохие решения, но многие обходные пути появляются раньше. Продажи сокращают срок вдвое. Продукт принимает расплывчатое решение. Менеджер говорит «просто выпустите» и оставляет чистку на потом. А потом обычно не наступает.
Ещё одна ошибка — считать работу завершённой до того, как результат увидит support. Функция может пройти QA и всё равно создавать ежедневную боль. Если support постоянно получает одну и ту же жалобу, значит, работа не закончена. Команда просто перенесла стоимость с roadmap в inbox.
Наполовину готовые продуктовые решения тоже поддерживают долг. Команды слышат «оставим гибким» или «решим после запуска», а потом закрывают пробелы быстрыми правилами и специальными случаями. Через месяц уже никто не помнит, какое поведение было намеренным, а что было заплаткой.
Ещё хуже считать чистку необязательной в каждом цикле. По крайней мере, тогда решение честное. Когда менеджеры говорят, что чистка важна, но каждый раз вырезают её ради следующей функции, команда быстро усваивает правило: если срок близко, долг побеждает.
Скачки приоритетов делают проблему сложнее. Команда начинает чинить слабый биллинг-флоу, потом её отвлекают на новый запуск, а через несколько недель она возвращается уже с меньшим контекстом и большим числом багов. Так небольшая ремонтная работа превращается в дорогую переделку.
Продуктовая команда может выпустить новый onboarding-флоу за три дня, чтобы успеть к сроку партнёра. Support сообщает о сбитых с толку пользователях, инженеры чинят крайние случаи, продукт всё ещё не решил, какие шаги обязательны, а руководство переключает внимание на следующий запуск. Сначала ничего не выглядит драматично. Через три месяца команда всё ещё трогает тот же флоу.
Хорошее управление долгом начинается тогда, когда руководители перестают спрашивать, кто создал беспорядок, и начинают спрашивать, кто сейчас отвечает за компромисс.
Быстрая проверка на эту неделю
Выделите 30 минут и посмотрите на один спринт, один релиз или один месяц тикетов поддержки. Вы не ищете все недостатки. Вы проверяете, не возвращается ли одна и та же проблема только потому, что никто за неё не отвечает, никто её не определил или кто-то слишком рано что-то пообещал.
Начните с повторяющейся работы. Если команда дважды чинила один и тот же баг, заново переписывала одну и ту же интеграцию или снова и снова латала один хрупкий экран, учитывайте это. Один повтор может быть неудачей. Три повтора обычно указывают не на проблему кода, а на проблему решений.
Для короткого обзора достаточно:
- Выберите от трёх до пяти проблем, которые вернулись после того, как команда уже трогала их один раз.
- Напишите по одному владельцу рядом с каждой рискованной областью. Если за минуту никто не может договориться о владельце, вот в чём проблема.
- Поднимите недавние обещания клиентам, продажам или основателям. Проверьте, какие из них были даны до оценки работ.
- Найдите функции, где люди до сих пор спорят о том, что значит «готово».
- Спросите команду, какой обходной путь она использует снова и снова.
Это работает, потому что разговор остаётся конкретным. «Кодовая база кажется грязной» — это расплывчато. «Мы четыре раза меняли правила оформления заказа, потому что продукт так и не задал крайние случаи возвратов» — уже то, что можно исправить.
Небольшая продуктовая команда может увидеть это на одной встрече. Допустим, основатель продавил отчётную функцию ради демо, разработка угадала объём, а ясных правил приёмки никто не написал. Через две недели клиенты просят экспорт, фильтры ведут себя странно, а support получает три версии одной и той же жалобы. Путь очевиден: чистка ведёт обратно к поспешному обещанию и отсутствующему решению.
Если вам нужен один показатель, используйте вот этот: сколько раз за неделю команде пришлось возвращаться к старой работе, потому что исходное решение было неясным? Этот показатель говорит больше, чем метка в бэклоге. Когда он снижается, значит, процесс поставки, скорее всего, становится здоровее.
Что делать дальше
Начните с одной проблемы, которая снова и снова возвращается. Выберите задачу на чистку, которую ваша команда делала хотя бы дважды за последний месяц: чинить сломанный handoff, переписывать один и тот же модуль, латать поспешный релиз или распутывать функцию, которой никто не владел полностью. Затем задайте три простых вопроса: кто принял исходное решение, кто сейчас владеет этой областью и какое обещание заставило команду срезать углы?
Такой небольшой аудит обычно говорит больше, чем ещё один разбор багов. Большая часть повторяющегося долга не случайна. Он растёт там, где продуктовые решения остаются размытыми, сроки обещают слишком рано или ответственность меняется каждый спринт. Управлять долгом проще, когда вы называете решение, стоящее за беспорядком, а не только код, который всем надоел.
Короткой еженедельной проверки достаточно, чтобы начать:
- Проследите один повторяющийся элемент чистки обратно к пропущенному решению, неясному владельцу или поспешному обещанию.
- Назначьте каждой активной продуктовой области одного понятного владельца.
- Ужесточите обещания по срокам. Продажи, основатели и продуктовые лиды должны согласовывать объём с разработкой до того, как озвучат дату.
- Если те же паттерны продолжают появляться, попросите внешний взгляд, прежде чем команда начнёт считать их нормой.
Не нужен большой новый процесс. Нужны более ясная ответственность, меньше случайных обещаний и привычка прослеживать повторяющуюся работу обратно к решению, которое её вызвало.
Если ваша команда снова и снова ходит по кругу вокруг одних и тех же проблем, поможет внешний CTO-обзор. Oleg Sotnikov на oleg.is работает как Fractional CTO и startup advisor, помогая стартапам разбирать ответственность, архитектуру и привычки поставки, не переворачивая компанию с ног на голову. Иногда этого достаточно, чтобы одна и та же чистка не появлялась снова в следующем спринте.
Часто задаваемые вопросы
Как понять, что это технический долг, а не обычный баг?
Относитесь к этому как к долгу, если одна и та же область снова и снова требует исправлений. Обычная ошибка появляется один раз; повторная переделка обычно означает, что команда оставила решение неясным или поторопилась с работой.
Почему одна и та же переделка снова и снова возвращается?
Потому что команда исправила код, но не исправила причину. Если никто не владеет этой областью, продукт оставляет правила открытыми или продажи слишком рано обещают сроки, та же проблема возвращается в новом виде.
Что проверить в первую очередь, если одна часть продукта постоянно ломается?
Начните не с последнего патча, а с первого обходного решения. Спросите, кто принял исходное решение, что осталось не определено и кто сейчас отвечает за эту область.
Может ли один рефакторинг решить проблему повторяющейся переделки?
Нет. Рефакторинг помогает коду, но он не даст долгого эффекта, если команда продолжает подсовывать в ту же функцию размытый объём работ и поспешные решения.
Кто должен отвечать за функцию, которая постоянно вызывает переделки?
Выберите одного человека, который может принять финальное решение по объёму, компромиссам и тому, что считается готовым. Общая ответственность звучит красиво, но обычно она оставляет команду в ожидании и вынуждает латать пробелы.
Сроки в спешке — это действительно большой источник долга?
Да. Когда основатели или продажи обещают дату до того, как разработка посмотрит на работу, команда режет тесты, крайние случаи и чистку кода, чтобы успеть к обещанию. В результате одна поставка превращается в две или три волны исправлений.
Стоит ли считать тикеты в поддержку сигналом долга?
Да, потому что поддержка видит боль, которую QA и демо могут не заметить. Если support каждую неделю разбирает одну и ту же путаницу или обходной сценарий, значит функция ещё не готова.
Что может сделать менеджер на этой неделе, чтобы снизить долг?
Сначала замедлитесь достаточно, чтобы назначить одного владельца для каждой рискованной области и подтвердить объём работ до того, как кто-то назовёт сроки. Затем выберите одну повторяющуюся проблему из последнего спринта и проследите её до решения, которое её породило.
Какой простой показатель стоит отслеживать?
Следите за тем, как часто команда снова возвращается к старой работе из-за того, что исходное решение было неясным. Если этот показатель падает, значит, планирование и ответственность, скорее всего, стали лучше.
Когда нам стоит попросить внешнюю помощь CTO?
Привлекайте внешнюю помощь, когда команда неделями переделывает одно и то же, а никто не может назвать одного владельца или одно ясное правило. Fractional CTO может увидеть пробелы в решениях, подтянуть привычки поставки и помочь разорвать цикл без тяжёлых процессов.