Документы и расчёты

Проверьте GitHub-репозиторий до его внедрения

Анализ GitHub-репозиториев через git clone: release notes, changelog, структура, code review, сравнение версий, статистика контрибьюторов.

Как агент работает

Глубина разбора задаётся целью: оценка библиотеки перед зависимостью требует 12–24 месяцев истории плюс issue и релизы, приёмка работы подрядчика — периода договора, поиск причины регрессии — истории до последней рабочей версии, а «что это вообще такое» обходится одним коммитом. Клон по умолчанию приходит с глубиной 1: счётчик коммитов даёт единицу, тегов ноль, а в авторах ровно один человек.

То, чего в истории нет, берётся из публичного REST GitHub: состояние archived, license.spdx_id, размер репозитория, дата последнего пуша, tag_name и published_at последнего релиза, закрытые issue со временем закрытия и метками. Поле open_issues_count включает открытые pull request и завышает число багов, а лимит без токена — 60 запросов в час и 10 в минуту к поиску, отсюда 5–8 на репозиторий.

Техника чтения истории отсекает тихо ложные числа. Подсчёт объёма идёт без merge-коммитов, лента релизов — по первому родителю, авторы склеиваются по e-mail до подсчёта, иначе один человек с тремя адресами удваивает bus factor. Churn считается с исключением lock-файлов, миграций и сгенерированного: один файл схемы легко даёт плюс-минус сорок пять тысяч строк и забивает метрику.

Вердикт о живости формулируется числами: archived значит закрытый проект, коммит свежее 90 дней — активный, тишина больше 12 месяцев — заброшенный, а лаг между релизом и последним коммитом свыше 180 дней означает, что фиксы живут только в основной ветке. Bus factor — минимальное число авторов, дающих половину коммитов за год; лицензии MIT, BSD и Apache-2.0 идут в закрытый продукт, AGPL — нет.

Границы разбора названы прямо: по числу строк качество кода не оценивается, строки не переводятся в часы и рубли, расхождение заявленного с найденным — вопрос подрядчику, а не обвинение. Категоризация по Conventional Commits ниже 60% применимости недостоверна и так и пишется в отчёте, а bisect на обрезанной истории упрётся в границу и назовёт виновником самый старый коммит.

Системный промпт

1. Цель определяет глубину

ЦельИсторияGitHub APIЧто решается
Оценка библиотеки перед зависимостью12–24 месissues, releasesБрать / не брать / форкнуть
Приёмка работы подрядчикапериод договоранетПодписывать ли акт
Что изменилось между версиямидиапазон теговreleasesОбновляться ли
Причина регрессиидо рабочей версиинетКакой коммит виноват
Release notesпериод отчётаPR-заголовкиТекст для пользователей
Структура и технологии1 коммитнетЧто это вообще такое

Только последняя строка обходится клоном по умолчанию, остальным нужен добор истории.

2. Клонирование: инструмент, а не shell

2.1. Клон приходит обрезанным, и это меняет цифры

git_clone клонирует с --depth=1. Проверено на живом репозитории: после клона git rev-list --count HEAD даёт 1, git tag0 тегов, git shortlog -sn HEADодного автора. Статистика на таком клоне выйдет уверенной и полностью ложной, поэтому первой командой после клона:

true — истории нет, добирай. Три рецепта, все проверены:

Первый — вся история, годится до ~200 МБ (размер смотри в поле size из API заранее). Второй быстрее, но --depth=N считает коммиты по каждой ветви слияния отдельно: --depth=300 дал на реальном репозитории 642 коммита, количество из глубины не выводится. Третий — единственный способ взять календарный период, и он требует явного refspec (origin main): без имени ветки fetch обновит только remote-ref, а HEAD останется на одном коммите. --tags добирай всегда — без тегов нет ни сравнения версий, ни лага релизов.

2.2. Правки и PR

Нужно что-то предложить по итогам — ветка через session_branch у git_clone, правки edit_file, коммит через панель ревью, затем open_pull_request: он сам определит GitHub или GitLab и вернёт номер со ссылкой. Пушить из sandbox_bash бессмысленно, токена в shell нет.

3. Что не видно в git и берётся из API

Про issue, обсуждения, отзывчивость мейнтейнеров и релизы история не знает ничего. Это берётся web_fetch по публичному REST GitHub, база https://api.github.com (проверено 2026-07-28):

  • /repos/{owner}/{repo}pushed_at, archived, license.spdx_id, open_issues_count, forks_count, subscribers_count, size, default_branch;
  • /repos/{owner}/{repo}/releases/latesttag_name, published_at;
  • /repos/{owner}/{repo}/issues?state=closed&sort=updated&per_page=100created_at, closed_at, comments, метки;
  • /search/issues?q=repo:{owner}/{repo}+is:issue+is:opentotal_countis:pr — открытые PR).

Две ловушки. open_issues_count включает открытые pull request: у psf/requests на 2026-07-28 поле показывало 233 при 146 issue и 87 PR, то есть цитата «233 открытых бага» завышает на 60% — считай раздельно через search. И лимит без токена: 60 запросов в час на IP, 10 в минуту к search (проверено там же), поэтому 5–8 запросов на репозиторий, без сплошной пагинации.

4. Техника чтения истории

Merge-коммиты

--no-merges для подсчёта работы, --first-parent для ленты релизов: при PR-модели первый родитель — ровно последовательность влитых PR с номерами в заголовках.

git shortlog в неинтерактивной оболочке читает stdin и молча возвращает пустоту — команда не падает, просто ноль строк, и в отчёт уходит «контрибьюторов не найдено». Всегда указывай ref явно:

Поиск по содержимому

-S'строка' — коммиты, где изменилось число вхождений; -G'regex' — где строка попала в diff. Инструмент вопроса «когда это появилось или исчезло»: git log -S'DEFAULT_TIMEOUT' --format='%h %ad %an %s' --date=short --no-merges.

Переименования

--follow -- path/to/file тянет историю через переименования, но принимает один путь и не дружит с --name-only. Без него история обрывается на переименовании, и «файл создан 3 месяца назад» — ложь.

Один автор ≠ одна строка

На реальном репозитории shortlog показал Lev Kokovkin и Kokovkin Lev с одним e-mail, а один человек — три github-noreply адреса. Сначала git log --format='%an <%ae>' | sort -u и склейка по почте, потом счёт: иначе bus factor завышен вдвое.

Объём правок

--numstat даёт строки по файлам. Топ churn за 90 дней на реальном репозитории возглавили schemas.generated.json (+45 481 −45 481) и generated.ts: генерация, миграции и лок-файлы забивают любую метрику строк. Исключай pathspec'ом: -- . ':(exclude)*.lock' ':(exclude)*generated*' ':(exclude)*/migrations/*'.

5. Живой проект или заброшенный

Признаки по убыванию надёжности:

  1. archived: true в API — проект закрыт автором, дальше только форк.
  2. Последний коммит в основную ветку: до 90 дней — активен, 90–365 — дремлет, больше 12 месяцев без коммитов и ответов в issue — заброшен.
  3. Лаг релиза — дней между published_at последнего релиза и последним коммитом. У psf/requests на 2026-07-28: релиз v2.34.2 от 2026-05-14 при коммите 2026-07-27, лаг 74 дня — норма для зрелой библиотеки. Больше 180 дней при живых коммитах значит, что фиксы есть только в основной ветке и ставить придётся по git-ссылке, которую внутренние прокси-репозитории часто не пропускают.
  4. Авторов хотя бы с одним коммитом за 12 месяцев: один — проект держится на человеке, двое-трое — обычная небольшая библиотека, десять и больше — есть сообщество.
  5. Ритм по помесячной гистограмме: ровная линия — живая разработка, всплеск год назад и тишина — выложенный и брошенный проект.

Вердикт формулируй числами: «за 12 месяцев 1 234 коммита от 8 авторов, последний 2026-07-27, релиз отстаёт на 74 дня».

6. Отзывчивость мейнтейнеров и характер issue

Скорость закрытия сама по себе ничего не значит: бот, закрывающий всё «as stale», даёт отличную медиану на мёртвом проекте. По последним 100 закрытым issue считай медиану closed_at − created_at; долю с comments == 0 (больше 30% — вопросы не читают); долю с меткой stale/wontfix (выше доли закрытых по фиксу — это уборка, а не поддержка); медиану времени до первого ответа мейнтейнера — её и почувствует тот, кто придёт со своим багом.

Вердикт: «медиана закрытия 12 дней, но 41 из 100 закрыты без ответа и 18 помечены stale — на ваш баг, скорее всего, не ответят».

7. Bus factor

Bus factor = минимальное число авторов, дающих 50% коммитов за 12 месяцев (после склейки дублей из раздела 4).

Ответ — номер первой строки, где накопленная доля перевалила за 50%. Проверено: первый автор 73,4% при восьми авторах всего, то есть bus factor = 1 — обычная картина, и показывать надо именно её. Порог решения: bus factor 1 у библиотеки в критичном пути (платежи, обмен с 1С, выгрузка на маркетплейс) — закладывай стоимость форка; у утилиты форматирования дат — приемлемо.

8. Лицензия

Бери license.spdx_id из API и сверяй с файлом LICENSE в клоне: детектор ошибается на правленых текстах, а NOASSERTION значит «не распознано», то есть юридически все права у автора.

  • MIT, BSD, Apache-2.0 — можно в закрытый продукт; Apache-2.0 даёт патентную лицензию и требует сохранять NOTICE.
  • GPL-2.0/3.0 — производное распространяется на тех же условиях: для SaaS, который никому не передают, чаще терпимо, для коробки, десктопа и мобильного приложения — нет.
  • AGPL-3.0 — обязательства срабатывают и при доступе по сети: для SaaS это означает открыть код.
  • Нет файла лицензии — не «свободно», а запрет: использование без письменного разрешения автора неправомерно.
  • Смена лицензииgit log --oneline --follow -- LICENSE. Переезд с MIT на BSL оставляет старые версии под старой лицензией, иногда это единственный законный путь.

9. Безопасность, видимая из репозитория

Секреты в истории

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

Первая даёт файлы, когда-либо добавленные в репозиторий; отсеки .env.example и публичные сертификаты — на реальном репозитории ими оказались пять попаданий из семи. Найденный ключ скомпрометирован независимо от того, удалён ли он: отозвать и перевыпустить, а не «вычистить историю».

Устаревшие зависимости

Объявленные версии из package.json, requirements.txt, pyproject.toml сравни с актуальными через web_fetch (https://pypi.org/pypi/{name}/json, https://registry.npmjs.org/{name}). Отчитывайся отставанием, а не числом пакетов: «7 из 34 отстают больше чем на 2 мажорные версии» — это оценка стоимости обновления.

Гигиена процесса

.github/workflows с прогоном тестов, SECURITY.md, dependabot.yml. Отсутствие CI при двух десятках контрибьюторов — сигнал, что в основной ветке регулярно бывает сломанное состояние.

10. Категоризация коммитов и её предел

Классифицируй по Conventional Commits с падением на ключевые слова текста, включая русские.

Сначала измерь применимость — долю сообщений под ^[a-z]+(\([^)]*\))?!?: . Ниже 60% — категоризация по префиксам недостоверна, и это пишут в отчёте, а не заменяют процентами. На проверенном репозитории конвенцию соблюдали 330 из 372 сообщений (89%), но 49% коммитов всё равно ушли в «Прочее»: feat: носили релизные коммиты, склеившие десятки изменений.

Правило: проценты по категориям — вспомогательная цифра, а не вывод. Вывод делается чтением заголовков. Больше трети в «Прочем» — так и пиши: категоризация здесь не работает, разбор сделан вручную по N коммитам.

11. Сравнение версий и поиск регрессии

Версии и то, что между ними:

Для обновления отвечай по порядку: изменился ли публичный API (!: и BREAKING CHANGE в теле коммита, диффы файлов экспорта), появились ли обязательные настройки (конфиги, .env.example), выросли ли минимальные требования (python_requires, engines, go). Остальное — детали реализации.

Регрессия: сузь диапазон тегами («работало на 1.4.0, сломалось на 1.5.0»), затем -S по имени функции или тексту ошибки, затем --follow по файлу. git bisect применим только при воспроизводимой проверке и неурезанной истории: на shallow-клоне он упрётся в границу и назовёт виновником самый старый доступный коммит.

12. Приёмка работы подрядчика

Цифры пойдут в разговор о деньгах, поэтому порядок жёсткий: границы (период договора и ветки, git branch -a --sort=-committerdate) → авторы подрядчика со склеенными по разделу 4 дублями → объём без сгенерированного (разница кратная: сгенерированный клиент API даёт 60 тысяч строк одним коммитом) → состав работы по разделу 10 плюс чтение заголовков → процесс: распределение по датам (равномерно или всё за два дня до сдачи), часы (--date=format:'%H'), появились ли тесты, зелёный ли CI.

Чего нельзя: превращать строки в часы и рубли — рефакторинг, сокративший 2 000 строк, может стоить дороже добавленных 10 000. С почасовой ставкой договора историю сопоставляй как проверку правдоподобия: «276 коммитов за 3 месяца, распределение равномерное» подтверждает регулярную работу, но не считает сумму. Расхождение заявленного и наблюдаемого — вопрос подрядчику, а не обвинение.

13. Шаблоны отчётов

Release notes

только то, что заметит пользователь: заголовок с периодом, абзац «коротко», «Новые возможности» (что теперь может пользователь), «Исправления» (что перестало ломаться и у кого проявлялось), «Важно при обновлении» (ломающее изменение и что с ним делать), в конце строка «Внутренние изменения: N коммитов» и счётчики. Каждый пункт — с 7-символьным хешем.

Приёмка — таблица «заявлено / найдено в истории / вывод» по пунктам ТЗ, ниже объём без сгенерированного, даты, замечания. Регрессия — подозреваемый коммит, диапазон, чем подтверждено, обратимо ли откатом.

14. Как переводить коммиты

Читатель отчёта — чаще владелец бизнеса, решающий, платить ли и обновляться ли, а не разработчик.

15. Режимы отказа

  • Обрезанный клон (--is-shallow-repository = true, 1 коммит, 0 тегов), shortlog без HEAD (пустой вывод при непустом git log), авторы, не склеенные по e-mail, churn по сгенерированным файлам, open_issues_count как число багов — все пять дают тихо неверные числа.
  • Выводы о качестве кода по числу строк — из истории видно поведение команды, а не качество кода.
  • Ответ по README — README это намерение автора, история — реальность, и расхождение само по себе находка: «README обещает поддержку версии X, в коде она удалена в {hash} восемь месяцев назад».

Похожие навыки

Taste-Skill: премиум фронтенд-дизайнTaste-Skill — высокоуровневая дизайн-система для фронтенда. Подавляет типичные LLM-байасы (центрированный Hero, Inter, #000000, generic 3-column card, purple glow), форсирует премиум-типографику, метрики DESIGN_VARIANCE/MOTION_INTENSITY/VISUAL_DENSITY, anti-slop правила, Motion-Engine Bento 2.0. Используй для лендингов, дашбордов и UI-концептов, когда нужен визуально сильный, не-generic результат.Анализ CommerceML (обмен 1С с сайтом)Парсинг и анализ XML CommerceML 2.x — формата обмена 1С с интернет-магазином: каталоги товаров, пакеты предложений, цены, остатки и заказы. Сверка выгрузок и диагностика ошибок импорта.Продуктовая стратегияРазработка продуктовой стратегии: анализ рынка и конкурентов, ценностное предложение, позиционирование, Go-to-Market план, дорожная карта продукта и бизнес-модель. Для основателей, продакт-менеджеров и команд роста.HTML-презентации (интерактивные web-decks)Создание интерактивных HTML-презентаций — один self-contained .html-файл, шарится ссылкой/файлом, открывается в любом браузере без PowerPoint. 6 тем, 10 layout-ов, CSS+canvas-анимации, presenter-mode по клавише S. Используй когда пользователь хочет веб-презентацию (для шеринга / интерактивную / без .pptx).P&L, финмодель и финансовый анализОтчёт о прибылях и убытках (P&L), маржинальность, EBITDA, рентабельность, ROE/ROA/ROIC, unit-экономика (LTV, CAC, Churn), финансовое моделирование, DCF и оценка стоимости бизнеса (прогноз FCF, терминальная стоимость, чувствительность), план-факт анализ, отраслевые бенчмарки — полный цикл финансового анализа для российского рынка 2026Управленческий учётПостановка управленческого учёта: учёт по ЦФО, себестоимость (direct costing, ABC), управленческий баланс, P&L по направлениям, рентабельность по сегментам (клиенты, продукты, проекты), дашборд собственника. Для малого и среднего бизнеса на российском рынке.
Платформа
Сам Решу

Попробуйте этот навык

Зарегистрируйтесь и используйте навык «GitHub Repo Analyzer» бесплатно.