|
|
|
Professor Seleznov
|
Когда я начинал CodeClone, это был довольно понятный инструмент: найти структурные клоны в Python-коде и не дать им незаметно расползаться по проекту. Сейчас вышел CodeClone 2.0.0, и это уже другой продукт. Не “ещё один линтер”, не попытка заменить Ruff, mypy, pytest, Bandit или Semgrep, а отдельный слой ревью: он смотрит на структуру Python-кода, отделяет старый технический долг от новых регрессий, связывает находки с покрытием тестами и дает одну и ту же картину в CLI, HTML-отчете, GitHub Actions, VS Code, Claude Desktop, Codex и через MCP. Эта статья не про список флагов CLI. Про флаги есть документация. Здесь я хочу рассказать, во что CodeClone вырос как продукт и зачем вообще нужен такой класс инструмента сейчас, когда разработка всё заметнее смещается в сторону AI-агентов. Если агент может быстро написать код, главный вопрос становится не “кто быстрее сгенерирует diff”, а “какие проверяемые ограничения не дадут этому diff незаметно ухудшить проект”. CodeClone 2.0 как раз про такой слой: структурное ревью, baseline-aware CI, единая модель отчета и MCP-поверхность, рассчитанная не на выгрузку всего подряд, а на нормальный маршрут ревью. Проблема, с которой все началось В реальных проектах качество кода редко ломается одним большим событием. Обычно это происходит тихо:
- где-то скопировали ветку бизнес-логики;
- где-то в guard-условии одна копия начала жить отдельно от другой;
- где-то большой модуль стал точкой, через которую проходит слишком много ответственности;
- где-то публичный API поменялся “между делом”;
- где-то есть сложная функция, но coverage не говорит о ней ничего;
- где-то агенту дали слишком много контекста, и он начал чинить не то.
Классический CI плохо работает с такой картиной. Если включить строгую проверку на зрелом проекте, он завалится на старом долге. Если сделать проверку мягкой, она перестает быть полезной. Если отдать агенту весь отчет, он может потратить контекст на второстепенный шум. CodeClone 2.0 строился вокруг другой идеи:
Отделять структурно важные изменения от фонового шума и давать для них проверяемый контекст: что новое, что уже принято baseline-ом, что влияет на CI и куда стоит смотреть в первую очередь.
Это сильно повлияло на весь дизайн продукта. Почему это стало важнее с AI-агентами С появлением AI-агентов проблема не исчезает, а становится заметнее. Агент может быстро написать код, разнести правку по нескольким файлам, предложить рефакторинг или исправить тесты. Но скорость генерации сама по себе не отвечает на вопросы ревью:
- это новый долг или уже известный?
- изменение затронуло production-код или только тесты?
- публичная поверхность изменилась случайно или осознанно?
- сложный код покрыт тестами или оказался вне coverage scope?
- агент чинит важный hotspot или тратит контекст на второстепенный шум?
- можно ли это безопасно пропустить через CI?
В разработке с агентами особенно важны проверяемые ограничения. Не расплывчатое “сделай хорошо”, а конкретные сигналы: что изменилось, где риск, что является новым, что уже принято baseline-ом, что должно блокировать merge. Поэтому CodeClone 2.0 я всё меньше воспринимаю как просто анализатор. Скорее это слой структурной верификации: он не пишет код за агента и не пытается заменить человека, но помогает удерживать инварианты качества, когда код меняется быстрее, чем раньше. Baseline: старый долг не должен маскировать новые проблемы Главная продуктовая идея CodeClone — управление качеством через baseline. Вместо “у вас в проекте есть проблемы, исправьте всё” инструмент предлагает более практичный контракт:
- Один раз фиксируем текущее состояние проекта.
- При следующих запусках отделяем известный долг от новых регрессий.
- В CI падаем на новом, а не на всем историческом.
Простейший сценарий выглядит так:
uv tool install codeclone codeclone . --update-baseline codeclone . --ci
Для команды это важнее, чем кажется. Такой подход позволяет включить проверку не только на чистом учебном проекте, но и в обычном production-репозитории, где уже есть история, компромиссы и накопленный долг. Baseline в CodeClone — не просто “сохраненный JSON”. Это доверенный артефакт с версионированием, fingerprint-версией, python tag и проверкой целостности. Если baseline не соответствует текущему рантайму или поврежден, CI не делает вид, что все нормально. Он явно говорит: сначала восстановите доверенную точку сравнения. Звучит сухо, но на практике это одна из самых важных частей продукта. Без доверенного baseline любой quality gate быстро превращается либо в шум, либо в декорацию. Один анализ, много поверхностей В CodeClone 2.0 я много раз возвращался к одному правилу:
Анализ должен быть один. Все остальное — его проекции.
CLI, HTML, JSON, Markdown, SARIF, MCP, VS Code extension, Claude Desktop bundle, Codex plugin и GitHub Action не должны изобретать собственную правду. Они должны показывать один и тот же результат в форме, удобной для своего сценария. Это важно по двум причинам. Во-первых, пользователь не должен гадать, почему в HTML одно, в CI другое, а агент через MCP увидел третье. Во-вторых, интеграции становятся безопаснее. VS Code extension не анализирует код заново. Claude Desktop bundle не реализует свой сервер. Codex plugin не добавляет “плагиновые” находки. Все они работают через тот же локальный codeclone-mcp, который читает те же отчеты и контракты. Поэтому CodeClone 2.0 — это не только пакет на PyPI. Это одна проверяемая модель ревью и несколько поверхностей вокруг нее:
- CLI для локального запуска и CI;
- HTML-отчет для человека;
- JSON/Markdown/Text/SARIF для автоматизации;
- MCP для AI-агентов и IDE;
- VS Code extension для нативной работы в редакторе;
- Claude Desktop bundle для установки через .mcpb;
- Codex plugin для локального агентного сценария;
- composite GitHub Action для PR и CI.
MCP: не “отдать агенту весь отчет”, а вести его по ревью MCP стал одной из ключевых частей CodeClone 2.0. Сначала я воспринимал его как удобный интерфейс для агентов. Потом стало понятно, что это отдельная продуктовая поверхность: агентам нельзя просто отдавать мегабайты отчета и надеяться, что они сами разберутся. MCP в CodeClone устроен по принципу triage-first. Типичный путь такой:
- Получить краткую сводку.
- Посмотреть production-first triage.
- Перейти к конкретным hotspot-ам.
- Открыть одну находку.
- Взять remediation-контекст.
- При необходимости отметить находку как reviewed в рамках текущей MCP-сессии.
Ключевые ограничения тоже сознательные:
- MCP read-only по контракту;
- он не меняет исходники;
- не обновляет baseline;
- не пишет cache как источник истины;
- не создает отдельные MCP-only находки;
- требует абсолютный путь к репозиторию, чтобы клиент не анализировал “что-то рядом” случайно.
Для AI-агентов это важнее, чем кажется. Хороший агентный интерфейс — не тот, который “может всё”. Хороший интерфейс сужает пространство действий, держит инструмент в честных границах и экономит контекст. Для агента особенно важно не только наличие инструментов, а форма маршрута. Если первым действием дать широкое перечисление всех находок, агент легко уходит в дорогую и шумную траекторию. Поэтому MCP в CodeClone не проектировался как “список методов к анализатору”. Он проектировался как control surface: сначала краткая картина, потом triage, потом hotspot, потом одна конкретная находка. Установка MCP-части:
uv tool install "codeclone[mcp]" codeclone-mcp --transport stdio
Для локальных клиентов stdio остается нормальным путем. HTTP-транспорт есть, но он должен быть осознанным выбором. HTML-отчет стал полноценной поверхностью ревью В ранних версиях HTML-отчет был скорее красивым выводом результата. В 2.0 он стал полноценной поверхностью ревью. Там есть:
- общий Overview;
- вкладка Clones;
- Quality с метриками и report-only сигналами;
- Dependencies с циклами и распределением глубины цепочек;
- Dead Code;
- Suggestions;
- Findings;
- IDE-ссылки для перехода в редактор;
- provenance-информация: baseline, cache, runtime, версии схем.
При этом HTML не должен придумывать смысл. Он только показывает факты из единого отчета. Если UI говорит “report-only”, это значит именно report-only: сигнал полезен для ревью, но не влияет на gates и не притворяется ошибкой. Это особенно важно для новых слоев, таких как Coverage Join и Security Surfaces. Coverage Join: структурная находка должна знать, что с тестами Одна из самых сильных фич 2.0 — Coverage Join. Сам по себе coverage часто недостаточен. 95% покрытия по проекту не отвечают на вопрос: “покрыта ли конкретная сложная функция, которую я сейчас трогаю?” С другой стороны, структурная метрика без покрытия тоже неполная. Функция может быть сложной, но хорошо покрытой. Или наоборот: не самая страшная по цикломатике, но находится на критичном пути и вообще не попала в coverage.xml. Coverage Join соединяет внешний Cobertura XML с единицами CodeClone:
codeclone . --coverage coverage.xml --fail-on-untested-hotspots --coverage-min 50
В результате появляются два разных типа сигнала:
- coverage hotspots — измеренные функции с риском и недостаточным покрытием;
- scope gaps — функции, которые CodeClone видит, но coverage-файл не измеряет.
Это принципиальное различие. “Плохо покрыто” и “не попало в coverage.xml” — разные ситуации, и в ревью их нельзя смешивать. Для CI это дает полезный gate:
Если функция структурно рискованная и при этом плохо покрыта, изменение требует внимания.
Для агента это ещё важнее: он видит не просто “сложный код”, а сложный код с контекстом тестов. Это помогает не тратить правку на косметику и не трогать рискованные места вслепую. Security Surfaces: не SAST, а карта чувствительных границ Самая опасная фича 2.0 с точки зрения формулировок — Security Surfaces. Очень легко сделать плохой security scanner:
- найти eval;
- найти subprocess;
- покрасить всё красным;
- написать страшные слова про уязвимости.
Я сознательно не хотел этого делать. CodeClone не пытается доказывать security bugs. Для этого нужны SAST-инструменты, threat model, контекст входных данных и проверка достижимости. Вместо этого CodeClone показывает security-relevant boundaries: места, где код работает с чувствительными возможностями и границами доверия. Например:
- запуск процессов;
- динамическая загрузка;
- десериализация;
- файловые мутации;
- криптографические и integrity-примитивы;
- auth/session/token/secret области;
- сетевые границы.
Это report-only inventory. Не утверждение об уязвимости, не CWE-движок и не замена SAST. Зачем тогда это нужно? Потому что для ревью важно знать, что изменение касается чувствительной поверхности. Особенно если там одновременно:
- высокая сложность;
- слабое покрытие;
- перегруженный модуль;
- клоновая дивергенция;
- измененный публичный API.
В 2.0 Security Surfaces уже видны в HTML, CLI, MCP и VS Code extension. Это первый стабильный шаг. Дальше этот слой может дорасти до более умного security pressure, но только если сигнал останется честным. Зависимости: фиксированная “магическая глубина” ушла Во время подготовки 2.0 обнаружилась неприятная вещь: прежний подход к глубине dependency chains был слишком грубым. Фиксированный порог вроде “8 для всех” выглядит аккуратно, но нечестен. Маленький пакет и большой инструмент с CLI, MCP, отчетами, IDE-клиентами и action-слоем нельзя оценивать одной цифрой. В 2.0 Dependencies стали показывать распределение:
- average depth;
- p95 depth;
- max depth;
- longest chains;
- cycles.
Циклы остаются жестким сигналом. А длинные ацикличные цепочки теперь воспринимаются как контекст и hotspot, а не как универсальный приговор. Это хороший пример того, как продукт менялся в процессе разработки: не “натянуть метрику на красивый score”, а пересобрать модель, если она начинает штрафовать без достаточных оснований. API Surface и Adoption: ревью публичного контракта Ещё один слой 2.0 — API Surface Inventory. Он нужен не для того, чтобы сказать “публичных символов много, вам должно быть стыдно”. Он нужен, чтобы видеть изменения публичной поверхности проекта:
- какие модули и символы стали публичными;
- что исчезло;
- где поменялся контракт;
- есть ли регрессии относительно metrics baseline.
Рядом с этим появился Adoption-блок:
- покрытие типов параметров;
- покрытие типов возврата;
- покрытие docstring-ами;
- регрессии по typing/docstring baseline.
Это не про “любите ли вы аннотации”. Это про управляемую эволюцию публичного кода. Если проект предоставляет API, изменения должны быть видны в review surface, а не всплывать после релиза. Overloaded Modules: report-only, но полезно CodeClone 2.0 также показывает overloaded modules. Это не gate и не “god-module найден, срочно режьте”. Скорее ранжированный список модулей, где одновременно сходятся разные признаки нагрузки: размер, связность, сложность, количество ответственностей, участие в других сигналах. На практике это помогает отвечать на простой вопрос:
Если мы хотим улучшить проект не вслепую, с каких файлов начать?
В больших репозиториях это часто полезнее, чем смотреть на один максимальный CC. Нативные клиенты: VS Code, Claude Desktop, Codex В 2.0 CodeClone перестал быть только CLI-инструментом. VS Code extension VS Code extension работает как нативный MCP-клиент:
- запускает локальный codeclone-mcp;
- показывает triage-first обзор;
- дает переход к исходникам;
- показывает Coverage Join и Security Surfaces, если сервер их поддерживает;
- уважает workspace trust;
- не отправляет код наружу и не строит собственный анализ.
Это не “HTML-отчет внутри WebView”. Идея другая: дать разработчику ревью с быстрым переходом к исходникам прямо в редакторе. Marketplace: https://marketplace.visualstudio.com/items?itemName=orenlab.codeclone Claude Desktop bundle Для Claude Desktop есть .mcpb bundle. Он не содержит второго сервера и не переопределяет смысл MCP. Это install wrapper, который помогает подключить тот же локальный codeclone-mcp к Claude Desktop без ручного редактирования конфигов. Сейчас я пробую пройти путь с добавлением бандла в Anthropic Directory. Codex plugin Codex plugin добавляет локальную discovery-поверхность, MCP-конфиг и review skills. Он тоже не анализирует код сам. Его задача — направлять агента по правильному CodeClone workflow: сначала обзор, потом triage, потом конкретные находки. GitHub Action: CodeClone в PR Для CI и PR есть composite GitHub Action:
- uses: orenlab/codeclone/.github/actions/codeclone@v2 with: fail-on-new: "true" sarif: "true" pr-comment: "true"
Он умеет:
- запускать baseline-aware проверку;
- генерировать JSON и SARIF;
- загружать SARIF в GitHub Code Scanning;
- публиковать PR summary comment;
- работать с изменениями в pull request без отдельной логики в проекте.
Action в 2.0 тоже был доведен до стабильной поверхности: аккуратные inputs, безопасная обработка путей, понятный summary, обновленная документация и тесты. Что значит stable в CodeClone 2.0 Слово stable здесь не означает “все идеи закончились”. Оно означает другое:
- базовый пакет ставится как codeclone, без --pre;
- codeclone[mcp] стал нормальной optional extra;
- CLI, report, baseline, cache и MCP имеют описанные контракты;
- интеграции больше не маркируются как preview;
- документация описывает текущую 2.0 release line;
- старые legacy-shim пути убраны;
- ошибки вокруг cache, baseline и runtime compatibility стали явными.
Особенно важны ограничения:
- CodeClone не заменяет линтеры и тесты;
- Security Surfaces не заменяет SAST;
- Coverage Join не заменяет coverage.py;
- MCP не получает права менять репозиторий;
- HTML и IDE не создают отдельную “правду”.
Для инструмента качества кода это, на мой взгляд, критично. Если инструмент обещает больше, чем может доказать, он быстро теряет доверие. Попробовать Минимальный старт:
uv tool install codeclone codeclone . codeclone . --html --open-html-report
CI-сценарий:
codeclone . --update-baseline codeclone . --ci
MCP для локальных агентов и IDE:
uv tool install "codeclone[mcp]" codeclone-mcp --transport stdio
Coverage Join:
codeclone . --coverage coverage.xml --fail-on-untested-hotspots
Полезные ссылки:
Что дальше 2.0 — это не финальная точка, а стабильный фундамент. Ближайшие направления, которые мне самому кажутся наиболее важными:
- лучшее changed-scope ревью для PR;
- развитие Security Surfaces в сторону более полезного, но по-прежнему честного pressure-сигнала;
- более удобный путь для GitHub Action и marketplace-представления;
- улучшение UX нативных клиентов;
- больше реальных кейсов на больших Python-репозиториях.
Если вы попробуете CodeClone на своем проекте, мне особенно интересны не только баги, но и “неудобные” вопросы:
- где сигнал кажется шумным;
- где инструмент слишком осторожен;
- где не хватает контекста для ревью;
- какие MCP-сценарии реально помогают агенту;
- где CI-gates хочется настроить иначе.
CodeClone 2.0 вырос из простого детектора клонов в продукт для структурного ревью. Но его главный принцип остался тем же: не делать вид, что инструмент знает истину о коде, а честно показывать факты, границы и изменения, на которые стоит посмотреть человеку или агенту. Если AI-агенты делают код дешевле в производстве, то инструменты вроде CodeClone должны делать структурные регрессии дороже в доставке. Не за счет магии, а за счет проверяемых контрактов: baseline, canonical report, CI gates, Coverage Join, Security Surfaces и triage-first MCP.-Источник
|
|
|
|