Самый частый вопрос от CTO про executable engineering standard: «это же просто SonarQube?». Нет. Но и не вместо. Эти инструменты живут на разных уровнях абстракции и дополняют друг друга, а не конкурируют.
Эта статья — таблица сравнения по 12 параметрам и разбор «когда что использовать».
Резюме за 30 секунд
- SonarQube / ESLint / Detekt — для багов уровня кода и стиля. Регексы, AST-анализ, безопасность.
- Code review глазами тимлида — для архитектуры и домена. Не масштабируется на команду 20+.
- AI-скиллы с corpus правил — для архитектуры и домена. Масштабируется. Дополняют линтеры, не заменяют.
Все три должны работать одновременно в зрелой команде. Линтер ловит NPE, скилл ловит «событие зарегистрировано не в корне агрегата», человек смотрит на «правильно ли вообще выбрана граница агрегата».
Полная таблица сравнения
| Параметр | SonarQube/ESLint | Тимлид-ревью | AI-скилл с corpus |
|---|---|---|---|
| Что проверяет | стиль, security-баги, complexity | архитектура, домен | архитектура, домен |
| Глубина понимания | синтаксис + AST | семантика + контекст | семантика + контекст (через corpus) |
| Кто исполняет | статический анализатор | человек | LLM-агент |
| Кодифицировано | плагины + конфиг | в голове | markdown в репо |
| Citeable в обзорах | да (java:S1234) | нет | да (R-AGG-X4) |
| Масштабируется | да | нет (bottleneck) | да |
| Latency обзора | секунды (CI) | дни (тимлид reads) | минуты (claude run) |
| False positives | средне (~10–20%) | низко | средне (~10–15%) |
| Понимает домен | нет | да | да |
| Версионируется | релиз плагина | устные правила | git diff на corpus |
| Открытость | open-source движок | в голове | репо команды |
| Lifecycle правил | релизы плагинов | неформально | git, semantic diff |
Где они НЕ конкурируют
Возьмём один и тот же PR — handler оплаты заказа:
public void handle(PayOrder cmd) {
Order order = orders.findById(cmd.orderId()).get();
order.setStatus(OrderStatus.PAID);
order.setPaidAt(Instant.now());
orders.save(order);
events.publishEvent(new OrderPaid(order.id(), order.total()));
}
SonarQube скажет:
java:S3655—Optional.get()безisPresent()— может броситьjava:S1192— string literal "PAID" дублируется (если есть в других местах)
AI-скилл ucp-ddd-tactical-review скажет:
R-AGG-X4— событие зарегистрировано не в корне агрегатаR-ENT-X3— публичные сеттеры вместо бизнес-методаR-EVT-X4—events.publishEvent()без транзакционных гарантий
Тимлид скажет:
- «Этот use case вообще должен быть
Order.pay()или application servicePaymentSaga? У нас же платёж асинхронный и приходит через webhook.»
Три уровня. Три инструмента. Все три нужны.
Когда что брать
Только линтер
- Команда < 5 инженеров.
- Простой CRUD-проект, не доменно-сложный.
- Нет архитектурных стандартов в голове техлида.
Линтер + тимлид-ревью
- Команда 5–10.
- Есть техлид с устоявшейся архитектурой.
- Архитектура держится на людях, не формализована.
Линтер + AI-скиллы + тимлид
- Команда 10+.
- Несколько сервисов, риск drift между ними.
- Архитектурные паттерны достаточно устоялись, чтобы их кодифицировать.
Линтер + тимлид (без AI-скиллов)
- MVP-этап, всё меняется еженедельно.
- Команда не доверяет AI-обзорам.
- Архитектура ещё не устоялась.
Что общего у всех трёх
Все три — это инструменты обзора, а не замены ответственности. Линтер не пишет код за вас. Тимлид не подписывает PR за разработчика. AI-скилл не принимает архитектурные решения. Все они — усилители, не подменители.
Качество ревью на любом из трёх уровней зависит от качества исходных стандартов:
- ESLint без хорошей конфигурации — шум.
- Тимлид без устоявшихся принципов — субъективные капризы.
- AI-скилл без хорошего corpus правил — generic-обзор уровня «улучши читаемость».
Качественный corpus правил — то, что отличает зрелую команду от cargo-cult adoption.
Что AI-скиллы делают, чего не делают линтеры
Есть один класс правил, который традиционные линтеры принципиально не достанут:
- Правила про доменный слой. «Имя value object — существительное в единственном числе». Линтер не знает что такое value object и какое имя «доменное», а какое нет.
- Правила про границы. «Один use case изменяет один агрегат, остальные через события». Линтер не знает где проходят границы агрегатов в вашей доменной модели.
- Правила про намерение. «Имя класса соответствует доменному термину из ubiquitous language». Линтер не знает ubiquitous language.
- Правила про контекст. «На Tier B JSON-сериализация через jackson, на Tier C — через MapStruct». Линтер не знает Tier и не выбирает правила в зависимости от него.
LLM умеет всё это потому что читает прозу правил вместе с прозой кода. Для LLM «доменный термин» и «не доменный» — это вопрос контекста, а не AST-узла.
Что линтеры делают, чего не делают AI-скиллы
И обратное:
- Скорость. Линтер за 3 секунды просмотрит 100K строк. Скилл — десятки секунд на PR.
- Детерминированность. Линтер на одном и том же коде даст один и тот же результат. LLM — с вариациями.
- Низкоуровневые баги. NPE, deadlock, off-by-one. Это работа AST-анализатора.
- Security-сканирование. SQL injection, XSS, hardcoded secrets — паттерны более чёткие.
Дальше
- Executable engineering standard — основная статья про подход
- Каталог стандартов — текущий corpus, 600+ правил
usecase-pattern-skills— открытые скиллы под Claude Code