Эта статья — про 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 / ESLintCode 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