Всем привет, меня зовут Сергей Прощаев, я Tech Lead и руководитель направления Java | Kotlin разработки в FinTech & E‑commerce и преподаю на курсах разработки и архитектуры в ОТУС.

В этой статье расскажу, почему руководитель команды обычно узнаёт о концентрации знаний в день заявления об уходе, как посчитать её заранее по истории git и что в этом расчёте меняют коммиты, сделанные вместе с агентом.

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

Через месяц в одном из модулей падает интеграция со сторонним API, и выясняется, что два «ответственных» видели этот код только в списке изменённых файлов на ревью. Команда неделю разбирается в проблеме по логам и комментариям в коде.

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

Что я посчитал

Чтобы не спорить на ощущениях, я взял метод из работы Авелино и соавторов, представленной на конференции ICPC в 2016 году. Они предложили считать truck factor, то есть bus factor, автоматически по истории git.

Для каждого файла считается степень авторства разработчика (DOA): создал ли он файл, сколько раз менял и сколько правок внесли другие. Величина нормируется по максимуму для файла, и автором считается тот, у кого нормированный DOA выше 0,75, а абсолютный не ниже 3,293.

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

Ядро расчёта занимает несколько строк:

import math


def doa(is_first_author: bool, own_changes: int, other_changes: int) -> float:
    # Avelino et al., ICPC 2016: первое авторство весит больше всего,
    # свои правки добавляют, чужие правки медленно отнимают
    return (3.293 + 1.098 * int(is_first_author) + 0.164 * own_changes
            - 0.321 * math.log1p(other_changes))

В исходной работе 65% из 133 популярных проектов GitHub имели truck factor не больше двух. Я применил эту методику к шести открытым проектам на JVM и Python по зафиксированным коммитам от 29 сентября до 23 октября 2026 года. Это не полное воспроизведение: файлы кода я отбирал по расширению и без каталогов вроде vendor и build, а не через Linguist, как авторы.

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

Авторство считается по всей истории, а «активные» — это авторы с коммитами за 365 дней до зафиксированного коммита, DOA по одним свежим правкам я не пересчитывал. Обе метрики оценивают авторство по истории правок, а не знание кода. Их ограничения разберу в конце.

Проект

Файлов кода

Truck factor по всей истории

Truck factor среди активных

Ничьё сейчас

Ничьё без лидера

fastapi

1220

1

1

3,6%

78,6%

javalin

372

1

1

16,4%

97,0%

kotlinx.coroutines

1105

2

1

29,7%

73,2%

ktor

2631

4

1

26,4%

62,6%

okhttp

690

1

1

1,6%

62,5%

spring‑petclinic

50

4

1

46,0%

74,0%

Открытый проект не равен команде в компании, об этом ниже. Но механика ошибок одна и та же, и шесть из них я разберу по порядку.

Перед схемой коротко о том, как файл становится ничьим. На схеме ниже путь от истории правок до вывода.

Как файл становится ничьим: авторство считается по истории, а не по списку ответственных
Как файл становится ничьим: авторство считается по истории, а не по списку ответственных

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

Ошибка 1. Считать устойчивость команды по всей истории

  • Симптом. Отчёт показывает у модуля четырёх авторов, и руководитель спокоен.

  • Неверное объяснение. «Раз авторов несколько, уход одного переживём».

  • Настоящая причина. Git помнит всех. В ktor и spring‑petclinic truck factor по всей истории равен четырём, а среди тех, кто коммитил за последний год, — единице. Остальные авторы больше не коммитят, но расчёт продолжает на них опираться.

  • Последствие. Риск недооценён ровно в тот момент, когда его можно было снять дёшево.

  • Исправление. Считать truck factor только по активным людям и смотреть на долю ничьих файлов. Я проверил, не держится ли вывод на выбранном окне в 12 месяцев: при окне в 6 и 24 месяца доля ничьих файлов в пяти проектах из шести меняется на 0,3–3,7 процентного пункта. Сильно сдвигается только маленький spring‑petclinic: 56% при окне в полгода и 30% при двух годах.

  • Когда возникает. В проектах, где команда успела смениться хотя бы наполовину.

Ошибка 2. Верить файлу владельцев кода

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

  • Неверное объяснение. «Владельцы назначены, значит, знания распределены».

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

  • Последствие. Руководитель планирует уход человека по документу, который уже не отражает реальность.

  • Исправление. Раз в квартал сверять файл владельцев с картой авторства. Если расчёт не приписывает владельцу ни одного файла в модуле, это повод проверить, знает ли он модуль на деле: дать ему небольшую задачу там или разобрать с ним последний инцидент.

  • Когда возникает. Когда файл владельцев завели при запуске модуля, а состав с тех пор менялся.

Ошибка 3. Ревью одним и тем же человеком

  • Симптом. Любой PR в модуль одобряет один и тот же старший разработчик, потому что «он лучше всех знает этот код».

  • Неверное объяснение. «Ревью и есть передача знаний: все видят изменения».

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

  • Последствие. Модуль держится на одном человеке, хотя через него проходят все.

  • Исправление. Ротация в паре: второй ревьюер выбирается из тех, у кого в модуле нет файлов, первые ревью проходит вместе с автором и разбирает не только дифф, но и ограничения модуля, а следом получает там свою задачу. Я бы предложил начинать с модулей, где «Ничьё без лидера» выше половины, а не со всей кодовой базы сразу.

  • Когда возникает. В командах, где ревью назначается вручную и по привычке достаётся самому опытному.

Ошибка 4. Считать документацию страховкой

  • Симптом. После тревожного разговора команда пишет страницу в вики с описанием модуля, и тема закрыта.

  • Неверное объяснение. «Всё записано, новый человек прочитает».

  • Настоящая причина. Документация переносит описание, но не умение. Пока человек сам не поменял код и не довёл изменение до продакшена, он не знает, где в модуле острые углы. Поэтому в расчёте степень авторства растёт только от собственных правок.

  • Последствие. В день инцидента страница есть, а того, кто по ней что‑то делал, нет.

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

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

Ошибка 5. Передавать дела за две недели отработки

  • Симптом. Заявление подано, уходящий проводит три созвона по своим модулям, запись лежит в облаке.

  • Неверное объяснение. «Главное — успеть выгрузить знания из головы».

  • Настоящая причина. Двух недель не хватает на то, что копилось годами. Таблица выше показывает масштаб: если завтра уйдёт самый крупный из активных авторов, без автора останется от 62,5 до 97% файлов проекта.

  • Последствие. Передача дел превращается в лекцию, а лекция быстро забывается.

  • Исправление. Готовиться к уходу до заявления. Карта ничьих файлов «если уйдёт лидер» считается заранее, и по ней видно, кому и какие задачи давать уже в этом квартале. Когда заявление всё‑таки придёт, две недели уйдут на остаток, а не на всё сразу.

  • Когда возникает. Всегда, когда о концентрации знаний вспоминают только в момент ухода.

Ошибка 6. Записывать код агента на автора коммита

  • Симптом. За год в модуль вошли десятки коммитов, сделанных вместе с агентом. Автором коммита везде числится человек, а на вопрос «почему здесь так» он отвечает «так предложил агент».

  • Неверное объяснение. «Человек принял изменение, значит, он его понимает».

  • Настоящая причина. Расчёт берёт из git поле Author, и правка с агентом засчитывается человеку, который в нём стоит. В ktor за последний год 43 коммита с агентом затронули 198 файлов, и в 128 из них расчёт считает автором этого человека. Агента расчёт распознаёт по двум признакам: по трейлеру, служебной строке вида Co-authored-by: в конце сообщения коммита, или по имени и адресу самого автора коммита. Это эвристика: агент без таких следов останется незамеченным, а служебную учётку правило может принять за агента. Код, принятый из чата без следов, неотличим от написанного руками.

  • Последствие. Карта авторства показывает человека там, где он, возможно, только принял дифф. Насколько это сдвигает цифры, я проверил пересчётом: в нём ни один коммит с распознанным агентом за всю историю, а не только за год, не засчитывается человеку ни как создание файла, ни как правка, но из истории не удаляется и остаётся чужой правкой файла. Состав активных я оставил прежним. Сценарий нарочно жёсткий: даже правку, которую человек переписал сам, он не считает человеческой. Это проверка чувствительности, а не оценка доли кода, написанного агентом. Truck factor не изменился ни в одном проекте, ни по всей истории, ни среди активных. А вот ничьих файлов в ktor стало 29,7% вместо 26,4%, и без лидера 65,5% вместо 62,6%, в javalin 16,7% вместо 16,4%. Агент уже прячет часть ничьих файлов: в ktor больше трёх процентных пунктов, и это только те случаи, которые удалось распознать по метаданным git.

  • Исправление. Договориться в команде подписывать коммиты с агентом трейлером и считать такие правки отдельно. Для файлов, которые за год затронули коммиты с агентом, второй ревьюер обязателен, а автор изменения на ревью объясняет решение своими словами.

  • Когда возникает. В командах, где агентом пользуются давно, а правила ревью остались прежними.

История: проект с одним мейнтейнером

Самая известная история про проект, который держался на одном человеке, случилась с XZ Utils, библиотекой сжатия, которая стоит почти в каждом дистрибутиве Linux. В июне 2022 года в рассылке проекта, в ветке про XZ for Java, один из участников написал, что прогресса не будет, пока не появится новый мейнтейнер, и отдельно упрекнул XZ for C в редких коммитах.

Мейнтейнер Лассе Коллин ответил, что его возможности сильно ограничены из‑за долгих проблем со здоровьем, что это неоплачиваемый проект и что он уже немного работал с Jia Tan, у которого в будущем может быть роль больше.

Роль действительно выросла. В 2024 году в архивах релизов 5.6.0 и 5.6.1, собранных и подписанных Jia Tan, нашли бэкдор, уязвимость получила номер CVE-2024-3094. Truck factor проекта я здесь не считал, это не пример цифры.

Для руководителя это история не про личные качества мейнтейнера, а про сочетание трёх вещей: ресурсов на сопровождение мало, полномочия сосредоточены у одного‑двух людей, а независимая проверка критичных изменений и релизных архивов не поймала подмену до релиза.

Механика та же и в команде, где все добросовестны: когда всё держится на одном, преемника выбирают не по плану, а по обстоятельствам, а проверка изменений нужна при любой репутации.

Что делать: план на квартал

Ниже на схеме исправления из шести ошибок собраны в один цикл. Он повторяется раз в квартал.

 Квартальный цикл: замер, карта, четыре действия и повторный замер
Квартальный цикл: замер, карта, четыре действия и повторный замер

Что важно на схеме: исправления запускаются не по поводу ухода человека, а по графику, и каждое следующее начинается с цифры, а не с ощущения.

Сводная таблица

Ошибка

Признак

Что проверить

Устойчивость по всей истории

Авторов много, но часть давно не коммитит

Truck factor только по активным

Вера файлу владельцев

Владелец без своих файлов в модуле

Сверка с картой авторства

Ревью одним человеком

Все PR модуля одобряет один

Доля ревью у второго ревьюера

Документация как страховка

Вики есть, задач в модуле у других нет

Число людей с правками за квартал

Передача дел за две недели

Созвоны вместо задач

Карта «если уйдёт лидер» заранее

Код агента на авторе коммита

Автор не может объяснить решение

Файлы, затронутые коммитами с агентом

Чек‑лист

  1. Посчитать truck factor и долю ничьих файлов по активным авторам.

  2. Посчитать ту же долю на случай ухода самого крупного автора.

  3. Сверить файл владельцев с картой авторства.

  4. Назначить второго ревьюера в модули, где без лидера ничьей станет больше половины файлов.

  5. Дать каждому по задаче в чужом модуле на квартал.

  6. Ввести трейлер для коммитов с агентом и считать их отдельно.

  7. Повторить замер через квартал и сравнить.

Где это не сработает

Авторство по git — приближение. Человек мог разобраться в модуле на дежурствах и ни разу не менять код, и расчёт его не увидит. «Активный» значит коммитил в репозиторий за год, а не работает в команде сегодня.

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

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

Вывод

Эта группа ошибок проверяет навык руководителя видеть риск в цифрах до того, как он стал инцидентом. Truck factor не меняется от совещаний и страниц в вики: он меняется, когда другие люди правят код в чужих модулях.

А с агентами появилась новая слепая зона: git хранит автора коммита, но не знает, кто на деле написал код и понял ли его автор, поэтому понимание надо проверять отдельно.

Ссылка на мой репозиторий с экспериментом

Начать стоит с expected.txt: там все четыре таблицы, на которые опирается статья, включая проверку при окне активности 6 и 24 месяца и пересчёт без правок с агентом. Как считается авторство и truck factor, видно в bus_factor.py, выгрузки истории шести проектов лежат в data/, а пересчёт со сверкой запускается командой ./run.sh.

Источники:

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

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

  • 5 ноября, 20:00. «Knowledge‑centered service и подходы к структурированию баз знаний». Записаться

  • 9 ноября, 20:00. «Качество без микроменеджмента: что должен контролировать CTO». Записаться

Больше актуальных материалов по разработке, управлению и ИТ‑архитектуре — в дайджесте ноября.

Важное напоминание

Комментарии (1)


  1. LaserPro
    04.11.2026 15:21

    Ну будет какая-то цифра, плюс минус километр, которой вообще нельзя верить.

    Пример: сеньор придумал архитектуру фичи, выдал подробное задание миддлу. Мидл имплементировал (или сгенерировал агентом). Позже у сеньора дошли руки, он увидел критические недостатки и поправил их, чтобы этот код вообще имел смысл.

    Но "автор" будет миддл, который только набрал бойлерплейт, ничего не поняв.

    Другой пример: сеньор сам написал важный и сложный код. Может даже с агентом для ускорения рутины, так что стоит co-authored with Claude. Позже в этом коде мелкия правки и дополнения от миддлов, потому что они используют его в своих простых задачах. В итоге в файле очень много правок от людей которые слабо знают как он работает - они просто "дорабатывают по образцу". А авторство уже "перетянули".

    Ещё пример: кому-то выпала задача обновить фреймворк/зависимость/версию языка/стандарт форматирования. И вот он уже автор половины файлов в репозитории, хотя тысячи правок внесены автоматическими инструментами.

    Не будет автоматический скоринг работать корректно. Лид должен сам следить за тем кто что делает и кто что знает, общаться с командой