Эта статья — про review-сторону методологии (corpus правил + AI-проверка PR). Use Case Pattern также включает design-сторону — генерацию целых сервисов из бизнес-брифа через скиллы
ucp-spec-design,ucp-pattern-design,ucp-ddd-tactical-design. См. Use Case Pattern для широкой картины.
У вас уже есть линтер для запятых. У вас нет линтера для агрегатов, доменных событий и границ транзакций. Вот эту дыру и закрывают AI-скиллы с corpus правил.
Тезис в одном абзаце: те решения, которые годами жили в головах техлидов и теряются с увольнением — теперь могут быть версионируемым corpus в репо команды, и AI-агент их применяет на каждом PR с цитированием конкретного правила. Не PDF, который никто не читает. Не wiki, которая устаревает за квартал. Исполняемый стандарт.
В этой статье:
- что такое executable engineering standard и чем он отличается от обычного style guide;
- сравнение с SonarQube, ESLint, традиционным code review (таблица);
- архитектура «rule corpus + executor» — два слоя, один источник истины;
- пример AI-обзора PR со ссылками на правила;
- когда такой стандарт не нужен (честно).
1. Что не работает в существующих подходах
Посмотрим как обычно выглядит «архитектурный стандарт» в команде из 20+ инженеров:
Вариант A — Confluence-страница на 40 экранов. Кто-то техлид написал в 2022. Команда читает один раз при онбординге. Через год правила устарели — стек поменялся, появились Java records, в проекте теперь jOOQ а не JPA. Страницу никто не обновляет. Через два года новые сотрудники ссылаются на неё как на «легаси-документацию».
Вариант B — code review глазами тимлида. Работает в команде из 5. На команде 25 — тимлид становится bottleneck. На каждой PR одни и те же комментарии: «инварианты в агрегате, не в Handler-е», «это не value object, добавь equals», «timestamp без TZ — поправь». Через полгода тимлид выгорает или уходит — знание уходит с ним.
Вариант C — линтер (SonarQube, ESLint, Detekt). Ловит стилевые проблемы и баги уровня кода: cyclomatic complexity, unused variables, null pointers. Не ловит архитектурные: границы агрегатов, naming доменных событий, разделение Domain Service vs Application Service. Не должен ловить — линтер для этого слишком плоский.
Все три варианта реальны, ни один не масштабируется.
2. Executable engineering standard как ответ
Идея проста: возьмём то, что хорошо себя показало в линтерах — кодифицированные правила с уникальными идентификаторами — и применим к архитектурным решениям, которые линтеры обычно не достают.
правило = {уникальный код, краткая формулировка, объяснение, пример ОК, пример НЕ ОК}
Где раньше тимлид писал в комменте: «вынеси регистрацию события из Handler-а в корень агрегата», теперь AI-агент пишет:
Нарушение
R-AGG-X4— событиеOrderPaidзарегистрировано вOrderHandler, должно регистрироваться в самом корнеOrderчерезregisterEvent(...). Источник: https://vikulin-va.ru/domain-driven-design/tactical-patterns/#r-agg-x4
Разработчик кликает ссылку — попадает на правило с примерами и обоснованием. Спорить с правилом → открывает PR в репо стандарта, обсуждает в команде, правило обновляется.
Ключевое отличие от обычного style guide: правило исполняется при каждом PR, цитируется в обзоре с прямой ссылкой, версионируется в git вместе с кодом.
3. Сравнение: SonarQube / ESLint / тимлид-ревью / executable standard
| SonarQube / ESLint | Code review тимлидом | Executable standard + AI | |
|---|---|---|---|
| Что проверяет | стиль, security-баги, уровень кода | архитектура, домен, корнер-кейсы | архитектура, домен, корнер-кейсы |
| Кто исполняет | статический анализатор | человек | LLM-агент |
| Кодифицировано | плагины, regex-правила | в голове тимлида | markdown corpus в репо |
| Citeable в обзорах | да (java:S1234) | нет (свободный текст) | да (R-AGG-X4) |
| Масштабируется | да | нет (тимлид-bottleneck) | да |
| Понимает домен | нет | да | да (через corpus) |
| Версионируется | через релиз linter-а | никак | через git |
| Открыто/закрыто | open-source | приватно в голове | репо команды |
| Lifecycle правил | релизы плагинов | устные договорённости | git diff на corpus |
Executable standard заполняет пересечение трёх свойств, которое одиночные подходы не дают: понимает архитектуру (как тимлид) + масштабируется (как линтер) + видим/редактируем командой (как git-репозиторий).
4. Архитектура: rule corpus + executor
Стандарт состоит из двух слоёв, один источник истины.
┌─────────────────────────────────────────────────┐
│ Слой 1: rule corpus (markdown) │
│ │
│ • правила с кодами `R-AGG-3`, `PG-T-013`, ... │
│ • прозой для людей, structured для AI │
│ • живут в репо: site/ + .claude/docs/ │
│ • версионируются git-ом │
└─────────────────────────────────────────────────┘
↓ читает
┌─────────────────────────────────────────────────┐
│ Слой 2: AI-skills (executor) │
│ │
│ • маленькие промпты-скиллы (~50 строк каждый) │
│ • вызываются на git diff команды │
│ • цитируют правила по коду │
│ • живут в .claude/skills/ │
└─────────────────────────────────────────────────┘
↓ применяется к
┌─────────────────────────────────────────────────┐
│ PR команды → review с конкретными ссылками │
└─────────────────────────────────────────────────┘
↓ кликаешь ссылку →
правило на сайте
Что важно архитектурно:
- Правила не зашиты в скилл. Скилл — тонкий, ~50 строк промпта. Правила — толстый corpus (~600+ кодов). Это позволяет менять правила, не трогая скиллы. Аналог — ESLint плагин, где конфиг отдельно от движка.
- Один источник истины — два render-а. Та же
.mdфайл через flexmark рендерится в HTML на сайте (для людей) и читается AI как plain text (для LLM). Никогда не расходятся. - Скиллы вызываются разработчиком явно. Не «AI ревьюит всё подряд». Команда
claude reviewили хук — на выбор. Контроль остаётся у человека.
5. Пример: real PR review
Допустим, разработчик запушил такой код:
public class OrderHandler {
private final OrderRepository orders;
private final ApplicationEventPublisher events;
@Transactional
public void handle(PayOrder cmd) {
Order order = orders.findById(cmd.orderId()).orElseThrow();
order.setStatus(OrderStatus.PAID);
order.setPaidAt(Instant.now());
orders.save(order);
events.publishEvent(new OrderPaid(order.id(), order.total()));
}
}
AI-скилл ucp-ddd-tactical-review после claude review выдаст:
Findings (3 critical, 1 minor)
R-AGG-X4— антипаттерн: регистрировать события вне корня агрегата (line 12) СобытиеOrderPaidопубликовано вOrderHandler, а не в самомOrder. Должно:order.pay(...)внутри которогоregisterEvent(...). Источник: https://vikulin-va.ru/domain-driven-design/tactical-patterns/#r-agg-x4
R-ENT-X3— антипаттерн: публичные сеттеры для всех полей (line 11)setStatus()иsetPaidAt()нарушают инкапсуляцию. Изменение состояния — только через бизнес-методы (order.pay(amount)). Источник: https://vikulin-va.ru/domain-driven-design/tactical-patterns/#r-ent-x3
R-EVT-X4— антипаттерн: AFTER_COMMIT для критичных эффектов (line 13)events.publishEvent()без транзакционных гарантий — событие потеряется при падении после commit. Нужен Outbox или синхронный@EventListenerв той же транзакции. Источник: https://vikulin-va.ru/domain-driven-design/tactical-patterns/#r-evt-x4
Разработчик в IDE видит 3 finding-а, кликает первую ссылку, читает обоснование, переписывает:
public class OrderHandler {
private final OrderRepository orders;
@Transactional
public void handle(PayOrder cmd) {
Order order = orders.findById(cmd.orderId()).orElseThrow();
order.pay(cmd.amount());
orders.save(order); // save публикует события через DomainEventPublisher
}
}
// в Order.java
public void pay(Money amount) {
if (status != OrderStatus.CONFIRMED) {
throw new IllegalStateException("Cannot pay: " + status);
}
this.status = OrderStatus.PAID;
this.paidAt = Instant.now();
registerEvent(new OrderPaid(id, amount, paidAt));
}
Цикл «правило → AI-обзор → ссылка → понимание → правка» занимает ~10 минут вместо «спор в комменте PR с тимлидом → ожидание ответа на 2 дня → разворот → конфликт-merge». Тимлид появляется только если разработчик хочет обсудить само правило.
6. Когда executable standard НЕ нужен
Честно. Подход не для всех.
Не нужен если:
- Команда меньше ~5 инженеров. Тимлид-ревью покрывает всё, формализация — overhead. Возьмёте, когда команда вырастет.
- MVP-этап / стартап-pivot месячного цикла. Архитектура меняется слишком быстро. Кодификация устареет за неделю. Сначала найдите PMF, потом стандартизируйте.
- Codebase 80% legacy без планов рефакторинга. Применять новые правила к коду 5-летней давности — генератор раздражения. Вводить нужно вместе с greenfield-сервисами.
- Команда не доверяет AI-обзорам. Сначала культурная подготовка, потом скиллы. Иначе скиллы выключат, corpus застынет.
Ясно нужен когда:
- Команда 10+, мульти-сервисный проект. Тимлид-bottleneck реальный, у каждого сервиса архитектура расходится без формализации.
- Greenfield/новый сервис. Самое выгодное место — записать паттерны, пока они свежие в голове.
- Текучка/растущая команда. Знание уходит с людьми. Corpus — память команды, которую не унесут с собой.
- Жёсткий compliance/safety домен. Авто, медицина, финансы — где «у нас принято» недостаточно, нужна аудит-trail почему ревью прошло.
7. Что executable standard НЕ делает
Чтобы избежать завышенных ожиданий:
- Не пишет архитектуру за вас. Решение про границы агрегатов, выбор Tier (A/B/C), какой стек — за человеком.
- Не заменяет архитектора. Обзор — это поддержка решения, не замена; решает человек.
- Не декларирует «правда». Каждое правило в репо — обсуждаемо. Несогласен — открой PR в
usecase-pattern-skills. - Не работает на legacy без адаптации. Применять
R-AGG-X3к coupled-сервису 2018 года = генерировать боль. Вводить с границы новых модулей. - Не ловит баги уровня кода (NPE, deadlock, off-by-one). Это работа SonarQube/ESLint. AI-стандарт — слой ВЫШЕ.
8. Дальше
- Use Case Pattern — методология, на которой строятся правила
- Стандарты — текущий corpus: 22 категории, 600+ правил, 12 AI-скиллов
- Тактические паттерны DDD: правила — пример corpus в действии
usecase-pattern-skillsна GitHub — открытые скиллы под Claude Code