# aact: архитектуру проверяет машина

> Architecture-as-code tools: паттерны, aact check на C4-диаграммах, чтение вердикта, метрики

_Источник: https://sii.sergeivolchkov.ru/materials/architecture/aact_



Диаграмма as-code даёт неожиданный бонус: её можно **проверять
автоматически**, как код линтером. Это делает aact — architecture-as-code
tools: CLI и библиотека для валидации, анализа и генерации архитектуры,
описанной в PlantUML C4 или Structurizr.

<RepoCard owner="Byndyusoft" repo="aact" note="Исходники правил, каталог паттернов, ADR и тесты. Правило непонятно — открывай его тест: там видно, что именно считается нарушением." />

Критерий приёмки: `npx aact@beta check` проходит с **0 violations**.
Эту же проверку запускает автопроверка на вашем PR.

## Быстрый старт [#быстрый-старт]

Всё описанное ниже — третья версия, поэтому везде `aact@beta`
(просто `npx aact` поставит старую v2).

```bash
# Создаёт aact.config.ts и стартовый architecture.puml
# с одним умышленным нарушением — чтобы было что чинить
npx aact@beta init

# Покажет нарушение CRUD-правила (orders → orders_db напрямую)
npx aact@beta check

# Авто-фикс: добавит orders_repo как посредника к БД
npx aact@beta check --fix
```

Дальше правишь `architecture.puml` под свою систему — синтаксис
[C4-PlantUML](https://github.com/plantuml-stdlib/C4-PlantUML).

Остальные команды:

```bash
npx aact@beta check --dry-run    # preview авто-фикса без записи
npx aact@beta analyze            # метрики coupling/cohesion
npx aact@beta model              # нормализованная C4-модель
npx aact@beta view               # live-workbench в браузере
npx aact@beta rule explain crud  # почему правило существует, с примерами
npx aact@beta generate --format plantuml
```

## Скилл для твоего агента [#скилл-для-твоего-агента]

Самая важная для курса команда — установка
[скилла aact-architect](https://github.com/ChS23/aact-architect-skill)
твоему агенту:

```bash
npx aact@beta skill install --claude   # Claude Code
npx aact@beta skill install --codex    # общий путь ~/.agents/skills
npx aact@beta skill install --all      # все клиенты сразу
```

Флаги есть для Claude Code, Codex, Cursor, Copilot и Cline. Отдельного
флага для Vibe нет, но `--codex` кладёт скилл в общий путь
`~/.agents/skills`, откуда его читают и остальные клиенты.

После этого агент знает дисциплину C4 (что является контейнером, а что
нет), каталог паттернов с ADR,
[шаблон ADR](https://github.com/ChS23/aact/blob/refactor/v3-foundations/ADRs/ADR%20template.md)
и сам гоняет `aact check`
после правок диаграммы. Архитектурный бред агента лечится не абзацем
в промпте, а установленным скиллом — это тот же принцип «жёсткие
правила держит машина», применённый к самому агенту.

## Теги: как aact понимает роли контейнеров [#теги-как-aact-понимает-роли-контейнеров]

Правила молчат, когда теги расставлены честно:

* **`acl`** — контейнер-адаптер к внешней системе; без него любая
  связь с `System_Ext` триггерит правило `acl`;
* **`repo` / `relay`** — контейнер, чья единственная работа — владеть
  базой; без него связь с `ContainerDb` триггерит `crud`;
* **`async`** — тег на связи (не на контейнере): помечает
  асинхронное ребро (очередь, Kafka) для `analyze`.

## Каталог паттернов [#каталог-паттернов]

Правила aact — это формализованные паттерны проектирования. Полный
[справочник с ADR и тестами — в репозитории](https://github.com/ChS23/aact/blob/refactor/v3-foundations/patterns.md);
основные:

| Паттерн                | Суть                                                                                         | Почитать                                                                                                         |
| ---------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Anti-corruption Layer  | За интеграцию с внешними системами отвечают отдельные адаптеры, инкапсулирующие знания о них | [ADR](https://github.com/ChS23/aact/blob/refactor/v3-foundations/ADRs/Anti-corruption%20Layer.md)                |
| Пассивные CRUD-сервисы | Сервисы доступа к мастер-данным не имеют лишней логики и зависят только от своей БД          | [ADR](https://github.com/ChS23/aact/blob/refactor/v3-foundations/ADRs/Database%20per%20CRUD-service.md)          |
| API-Gateway            | Внешние REST-вызовы не идут в сервисы напрямую                                               | [тест правила](https://github.com/ChS23/aact/blob/refactor/v3-foundations/test/rules/apiGateway.test.ts)         |
| Database per service   | К базе имеет доступ только один сервис                                                       | [ADR](https://github.com/ChS23/aact/blob/refactor/v3-foundations/ADRs/Database%20per%20CRUD-service.md)          |
| Stable Dependencies    | Зависимости направлены от менее стабильных модулей к более стабильным                        | [тест правила](https://github.com/ChS23/aact/blob/refactor/v3-foundations/test/rules/stableDependencies.test.ts) |
| Acyclic Dependencies   | Граф зависимостей без циклов                                                                 | [тест правила](https://github.com/ChS23/aact/blob/refactor/v3-foundations/test/rules/acyclic.test.ts)            |
| Cohesion > Coupling    | Связность внутри границы выше связанности с внешним                                          | [тест правила](https://github.com/ChS23/aact/blob/refactor/v3-foundations/test/rules/cohesion.test.ts)           |
| Common Reuse           | Используешь часть модуля — зависишь от части, а не от всего                                  | [ADR](https://github.com/ChS23/aact/blob/refactor/v3-foundations/ADRs/Common%20Reuse%20Principle.md)             |

У четырёх паттернов ADR ещё не написан — там ссылка на тест правила.
Это не хуже: тест показывает ровно те конфигурации, которые правило
считает нарушением, и ровно те, которые пропускает. Определение
«сделано» для правила — тоже код, а не абзац.

## Конфиг с обоснованиями [#конфиг-с-обоснованиями]

Конфиг лежит рядом с диаграммой. Живой пример боевого `aact.config.ts`:

```ts
export default defineConfig({
  source: { type: "plantuml", path: "./c4-container.puml" },
  rules: {
    // Включено: релевантно нашей архитектуре
    acyclic: true,            // без циклических зависимостей
    cohesion: true,           // границы: внутренних связей больше, чем внешних
    stableDependencies: true, // зависимости направлены к стабильным модулям
    commonReuse: true,        // Common Reuse Principle

    // Выключено: неприменимо — и написано почему
    acl: false,          // люди — внешние актёры, не контейнеры
    dbPerService: false, // Redis осознанно разделён между app и worker
    apiGateway: false,   // нет API-гейтвея в PoC
  },
});
```

Обрати внимание на стиль: **каждое выключенное правило — с причиной**.
«Выключил, потому что ругалось» причиной не считается: так технический
долг просто перестаёт быть видимым.

## Как читать вердикт [#как-читать-вердикт]

Правило сработало — значит диаграмма (или архитектура) врёт:

| Правило              | Что ловит                                       | Что чинить                                                       |
| -------------------- | ----------------------------------------------- | ---------------------------------------------------------------- |
| `acyclic`            | Циклы зависимостей: A → B → A                   | Выдели общую часть в третий модуль или переверни связь           |
| `cohesion`           | У границы больше внешних связей, чем внутренних | Граница нарезана не там: перенеси компонент или объедини границы |
| `stableDependencies` | Стабильный модуль зависит от часто меняющегося  | Инвертируй зависимость или признай модуль нестабильным           |
| `commonReuse`        | Модуль тянет то, что использует наполовину      | Разбей модуль                                                    |
| `dbPerService`       | К одной БД ходят несколько сервисов             | Выдели сервис-владелец данных                                    |
| `acl`                | Прямая интеграция с внешней системой            | Добавь адаптер-прослойку                                         |

Два честных исхода у каждого срабатывания: либо чинишь архитектуру,
либо осознанно выключаешь правило **с причиной в конфиге** — и это
решение с ценой, как любое другое (см. ADR).

## Метрики: aact analyze [#метрики-aact-analyze]

`analyze` считает связность и даёт цифры для отчёта: количество
элементов, синхронные вызовы, cohesion границ. Пример вывода боевой
системы: 10 элементов, 9 sync-вызовов, cohesion 2/5, 0 violations.
Эти цифры — хорошая строчка в README проекта и в блоке
«почему нам можно верить» на Demo Day.
