← назад к разделу

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

Проблема не в бизнесе и не в жадности. Проблема в том, что долг предъявляют в терминах, которые ничего не значат для того, кто принимает решение о деньгах.

Долг — это не «плохой код»

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

Отсюда сразу следуют две вещи.

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

Не всякий долг надо гасить. Заём, по которому вы больше не платите проценты, гасить незачем. Модуль, который никто не трогает два года, написан ужасно — и это ничего не стоит: платежей по нему нет. Переписывать его ради красоты — это тратить деньги на чужой закрытый счёт.

Практическое следствие для лида: долг определяется не качеством кода, а размером процентов. Не «здесь плохо», а «здесь мы платим столько-то каждую неделю».

Как посчитать проценты

Проценты по долгу всегда во что-то упираются: во время людей, в деньги или в риск. Считать их точно не нужно — нужен порядок величины, за который вы готовы отвечать.

Три величины, которые понимает любой заказчик.

Время на задачу в этой части системы. Возьмите последние 10 задач: пять в проблемном модуле, пять в здоровом. Если в проблемном средняя задача идёт пять дней, а в здоровом — полтора, разница в три с половиной дня и есть еженедельный процент. Умножьте на число задач в квартал.

Доля аварий и правок после выката. Если из десяти инцидентов за квартал семь пришли из одного модуля — это не «плохой код», это счёт: столько-то ночных подъёмов, столько-то часов на исправление, столько-то часов недоступности для клиентов.

Время от готовности до продакшена. Если выкат занимает сорок минут ручных шагов и делается по ночам, стоимость каждого релиза считается прямо: сорок минут × число релизов + запрет на быстрые исправления днём.

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

Разговор с бизнесом: переводим на язык решений

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

Было: «нам нужен месяц на рефакторинг модуля заказов, там всё плохо».

Стало: «каждая задача в модуле заказов идёт на три дня дольше, чем в остальном коде. За квартал это двадцать задач и шестьдесят человекодней. Две недели работы одного инженера убирают примерно половину разницы — вернём тридцать дней в следующем квартале и продолжим возвращать дальше».

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

Что важно в этом разговоре:

  • Никогда не просите «месяц на техдолг» целиком. Большой непрозрачный кусок без промежуточного результата — самая слабая позиция. Просите под конкретный платёж с конкретным эффектом.
  • Называйте, что перестанет болеть. «Уйдут ночные подъёмы по этому сервису» действует сильнее, чем «код станет чище».
  • Обещайте меньше, чем можете. Одно выполненное обещание про долг открывает следующее; одно невыполненное закрывает тему на полгода.
  • Показывайте платёж, а не только долг. Через квартал вернитесь с теми же цифрами: было пять дней на задачу, стало три. Это единственный способ получить кредит доверия на следующую инвестицию.

Когда платить, а когда терпеть

Простой фильтр, который решает большинство случаев.

СитуацияЧто делать
Место активно меняется, каждая правка дорогаяПлатить: проценты идут постоянно
Место — источник большинства аварийПлатить: проценты в риске и в ночных подъёмах
Место мешает начать следующую крупную работуПлатить, но как часть этой работы, не отдельно
Место стабильно и почти не меняетсяТерпеть: платежей нет
Систему через полгода выключаютТерпеть: долг спишется вместе с ней
«Здесь некрасиво написано»Не долг вовсе — либо чинить по ходу, либо не трогать

Отдельный случай — долг, который вы берёте прямо сейчас. Так тоже бывает и это нормально: срочная задача под дату, обход вместо решения. Правило одно: заём фиксируется письменно там же, где принято решение — что сделали временно, почему, что будет платежом и при каком условии возвращаемся. Незаписанный заём через два месяца превращается в «так исторически сложилось», и уже никто не помнит, что это была осознанная сделка. Хорошее место для такой записи — решение с последствиями (ADR): там уже есть раздел про последствия, и заём в нём выглядит естественно.

Как встроить выплату в обычный поток

Отдельные «спринты рефакторинга» почти всегда заканчиваются плохо: их отменяют при первом же срочном запросе, а сделанное наполовину хуже, чем не начатое.

Работает другое — постоянная доля мощности команды. Скажем, пятая часть времени идёт на инженерные инвестиции: тесты на критичный путь, наблюдаемость, автоматизация выката, разбор проблемного модуля по кускам. Доля не обсуждается каждый спринт, она согласована один раз как часть контракта с заказчиком.

Что это даёт: выплата перестаёт быть предметом переговоров и становится частью нормы. Плюс защищает от типичной ловушки, когда команда сама съедает свою долю первой же «очень срочной» задачей — если доля в плане, её видно, когда её съели.

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

Третье — закрывать вход. Пока нет исполняемого стандарта и проверки на входе в основную ветку, новый долг набегает быстрее, чем гасится старый. Сначала кран, потом ведро.

Что можно измерять постоянно

Чтобы разговор про долг был предметным, три-четыре числа стоит снимать регулярно — не ради отчёта, а чтобы видеть направление:

  • среднее время задачи по модулям — где дороже всего;
  • доля инцидентов по сервисам — где риск;
  • время от слияния до продакшена — насколько дорог выкат;
  • доля задач с правками после выката — насколько надёжны изменения.

Всё это уже собирается вашими системами. Отдельные «индексы качества кода» из статических анализаторов сюда добавлять не стоит: они измеряют код, а разговор идёт о деньгах и времени. Статический анализ хорош как ворота для нового кода, а не как аргумент в разговоре с заказчиком.

Коротко

  • Технический долг — это осознанный заём: ускорение сейчас в обмен на регулярный платёж потом. Плохой код от незнания — это дефект, а не долг.
  • Гасят не то, что некрасиво, а то, по чему идут проценты: время задач, аварии, дорогой выкат.
  • Проценты считают в величинах, которые уже есть в трекере и журнале инцидентов, и предъявляют как инвестицию с окупаемостью, а не как просьбу.
  • «Месяц на рефакторинг» — самая слабая форма запроса. Конкретный платёж с измеримым эффектом — самая сильная.
  • Долг, который берут сознательно, записывают там же, где принимают решение — иначе через два месяца это уже «так сложилось».
  • Выплата живёт в потоке: постоянная доля мощности, уборка по дороге и закрытый вход для нового долга.

Что почитать дальше

  • Решения с последствиями: ADR — где фиксировать осознанный заём и его условия возврата.
  • Исполняемый инженерный стандарт — как закрыть вход, чтобы новый долг не набегал.
  • Как принять команду: первые 90 дней тимлида — с чего начинать инженерные инвестиции в проблемной команде.