---
doc_id: ARC-CK8S-C4N-0001
type: c4-container
title: kodex — C4 Container
status: active
owner_role: SA
created_at: 2026-04-26
updated_at: 2026-05-25
related_issues: [599, 600, 601, 602, 655, 711, 747, 753, 781]
related_prs: []
approvals:
  required: ["Owner"]
  status: approved
  request_id: "owner-2026-04-26-platform-architecture-frame"
  approved_by: "ai-da-stas"
  approved_at: 2026-04-26
---

# C4 Container: kodex

## Кратко

Целевая платформа строится как набор сервисов-владельцев с моделью «БД на сервис». Пограничные компоненты остаются тонкими, исполнители не владеют доменной правдой, а операторский интерфейс получает агрегированную картину через проекции чтения.

## Контейнерные зоны

| Зона | Контейнеры | Ответственность |
|---|---|---|
| Пограничный слой и интерфейс | `web-console`, `user-gateway`, `staff-gateway`, `integration-gateway`, `platform-mcp-server`, `codex-hook-ingress` | Пользовательский интерфейс, входящие HTTP/webhook/MCP запросы, Codex hook events, авторизация и маршрутизация по направлениям доступа. |
| Сервисы-владельцы | `access-manager`, `project-catalog`, `provider-hub`, `package-hub`, `agent-manager`, `fleet-manager`, `runtime-manager`, `billing-hub`, `interaction-hub`, `operations-hub` | Каноническое доменное состояние и бизнес-правила. |
| Инфраструктурные контуры данных | `platform-event-log` | Общий журнал доменных событий и checkpoint потребителей без владения бизнес-доменом. |
| Исполнители | `worker`, `agent-runner` | Фоновые задачи, сверка и агентные сессии без владения доменной истиной. |
| Хранилища | PostgreSQL, Vault, объектное хранилище | Платформенное состояние, секреты, временные медиа. |
| Среда исполнения | Kubernetes, реестр контейнерных образов | Слоты, задания, нагрузки плагинов, проектные нагрузки и образы. |

## Диаграмма

```mermaid
C4Container
title kodex - контейнерная диаграмма

Person(user, "Пользователь", "Пользовательский интерфейс, голос, задачи и комментарии")
Person(owner, "Владелец", "Решения по контрольным точкам и релизам")
Person(operator, "Оператор", "Наблюдение и управление")

System_Ext(provider, "GitHub/GitLab", "Нативные артефакты провайдера")
System_Ext(k8s, "Kubernetes", "Среды исполнения и нагрузки")
System_Ext(registry, "Реестр контейнерных образов", "Образы")
System_Ext(vault, "Vault", "Секреты")
System_Ext(idp, "SSO/OIDC IdP", "Идентификация")
System_Ext(models, "Поставщики моделей", "API моделей")
System_Ext(channels, "Внешние каналы", "Уведомления и обратная связь")

System_Boundary(kodex, "kodex") {
  Container(web, "web-console", "Vue, Vuetify", "Операторская и пользовательская консоль")
  Container(userGateway, "user-gateway", "Go", "HTTP-вход для внешних пользователей")
  Container(staffGateway, "staff-gateway", "Go", "HTTP-вход для сотрудников и администраторов")
  Container(integrationGateway, "integration-gateway", "Go", "Webhook и внешние интеграции")
  Container(mcp, "platform-mcp-server", "Go, MCP", "Инструментальная поверхность платформы")
  Container(hookIngress, "codex-hook-ingress", "Go", "Входной контур нормализованных Codex hook events")

  Container(access, "access-manager", "Go", "Пользователи, организации, группы, права, внешние аккаунты")
  Container(projects, "project-catalog", "Go", "Проекты, репозитории, services.yaml, релизные политики")
  Container(providerHub, "provider-hub", "Go", "Зеркало провайдера, webhook, лимиты, операции провайдера")
  Container(packageHub, "package-hub", "Go", "Пакеты, магазины, установка, версии")
  Container(agent, "agent-manager", "Go + LLM", "Процессы, роли, промпты, агентные запуски, приёмка")
  Container(fleet, "fleet-manager", "Go", "Серверы, кластеры, размещение")
  Container(runtime, "runtime-manager", "Go", "Слоты, workspace, задания, сборка, выкладка, очистка")
  Container(billing, "billing-hub", "Go", "Записи затрат, биллинговые аккаунты, счета")
  Container(interaction, "interaction-hub", "Go", "Диалоги, согласования, уведомления, каналы")
  Container(operations, "operations-hub", "Go", "Проекции чтения, операторские ленты, очереди")
  Container(platformEvents, "platform-event-log", "Миграции + PostgreSQL", "Общий журнал доменных событий и checkpoint потребителей")

  Container(worker, "worker", "Go", "Исполнитель фоновых задач и сверки")
  Container(runner, "agent-runner", "Контейнерный агент", "Исполнение ролевого агента внутри слота")

  ContainerDb(pg, "PostgreSQL-кластер", "PostgreSQL", "Хранилище по модели БД на сервис")
  ContainerDb(obj, "Объектное хранилище", "S3-compatible", "Временные голосовые и медиа-вложения")
}

Rel(user, web, "Работает", "HTTPS")
Rel(owner, web, "Принимает решения", "HTTPS")
Rel(operator, web, "Наблюдает", "HTTPS")
Rel(web, staffGateway, "Вызывает операторские и администраторские сценарии", "HTTPS")
Rel(web, userGateway, "Вызывает пользовательские сценарии", "HTTPS")
Rel(userGateway, idp, "OIDC auth", "HTTPS")
Rel(staffGateway, idp, "SSO/IAP/VPN auth", "HTTPS")
Rel(userGateway, access, "Команды и чтение доступа", "gRPC")
Rel(staffGateway, access, "Администрирование доступа", "gRPC")
Rel(staffGateway, projects, "Команды и чтение проектов", "gRPC")
Rel(staffGateway, agent, "Команды запусков и процессов", "gRPC")
Rel(staffGateway, interaction, "Команды диалогов и согласований", "gRPC")
Rel(staffGateway, operations, "Проекции для пользовательского интерфейса", "gRPC")
Rel(provider, integrationGateway, "Доставляет webhook-события", "HTTPS")
Rel(channels, integrationGateway, "Доставляет callback внешних каналов", "HTTPS")
Rel(integrationGateway, providerHub, "Маршрутизирует проверенные provider webhook", "gRPC")
Rel(integrationGateway, interaction, "Маршрутизирует проверенные callback внешних каналов", "gRPC")
Rel(agent, mcp, "Использует инструменты платформы", "MCP")
Rel(runner, mcp, "Использует инструменты платформы", "MCP")
Rel(runner, hookIngress, "Отправляет нормализованные Codex hook events", "HTTP/gRPC")
Rel(mcp, access, "Маршрутизирует инструменты доступа", "gRPC")
Rel(mcp, projects, "Маршрутизирует инструменты проектов", "gRPC")
Rel(mcp, providerHub, "Маршрутизирует инструменты провайдера", "gRPC")
Rel(mcp, packageHub, "Маршрутизирует инструменты пакетов", "gRPC")
Rel(mcp, agent, "Маршрутизирует инструменты запусков и сессий для внешних вызывающих сторон", "gRPC")
Rel(mcp, fleet, "Маршрутизирует инструменты серверов и кластеров", "gRPC")
Rel(mcp, runtime, "Маршрутизирует инструменты среды исполнения", "gRPC")
Rel(mcp, billing, "Маршрутизирует инструменты биллинга", "gRPC")
Rel(mcp, interaction, "Маршрутизирует инструменты обратной связи и согласований", "gRPC")
Rel(mcp, operations, "Маршрутизирует инструменты операторского чтения", "gRPC")
Rel(hookIngress, agent, "Маршрутизирует hook events жизненного цикла", "gRPC")
Rel(hookIngress, runtime, "Маршрутизирует hook events среды исполнения", "gRPC")
Rel(hookIngress, providerHub, "Маршрутизирует provider artifact signals", "gRPC")
Rel(hookIngress, interaction, "Маршрутизирует запросы разрешений и обратной связи", "gRPC")
Rel(projects, access, "Проверяет организацию и членство", "gRPC")
Rel(providerHub, access, "Получает разрешение на использование внешнего аккаунта", "gRPC")
Rel(packageHub, access, "Проверяет права установки", "gRPC")
Rel(agent, projects, "Получает рабочее пространство, область процесса и политику", "gRPC")
Rel(agent, providerHub, "Читает состояние провайдера и отправляет сигналы обновления", "gRPC")
Rel(agent, runtime, "Запрашивает слоты и задания среды исполнения", "gRPC")
Rel(agent, interaction, "Запрашивает обратную связь, согласования и уведомления", "gRPC")
Rel(runtime, fleet, "Получает правила размещения и контур кластера", "gRPC")
Rel(runtime, projects, "Читает workspace, placement и release policy", "gRPC")
Rel(packageHub, providerHub, "Читает репозитории-источники пакетов", "gRPC")
Rel(billing, runtime, "Потребляет записи использования среды исполнения", "gRPC/events")
Rel(billing, packageHub, "Потребляет использование пакетов и ценовые данные", "gRPC/events")
Rel(operations, access, "Строит проекции доступа", "gRPC/events")
Rel(operations, projects, "Строит проекции проектов", "gRPC/events")
Rel(operations, providerHub, "Строит проекции провайдера", "gRPC/events")
Rel(operations, agent, "Строит проекции агентных запусков", "gRPC/events")
Rel(operations, runtime, "Строит проекции слотов и заданий", "gRPC/events")
Rel(operations, interaction, "Строит проекции согласований и уведомлений", "gRPC/events")
Rel(access, platformEvents, "Публикует outbox-события", "SQL")
Rel(operations, platformEvents, "Читает события для проекций", "SQL/checkpoint")
Rel(access, pg, "Своя БД", "SQL")
Rel(projects, pg, "Своя БД", "SQL")
Rel(providerHub, pg, "Своя БД", "SQL")
Rel(packageHub, pg, "Своя БД", "SQL")
Rel(agent, pg, "Своя БД", "SQL")
Rel(fleet, pg, "Своя БД", "SQL")
Rel(runtime, pg, "Своя БД", "SQL")
Rel(billing, pg, "Своя БД", "SQL")
Rel(interaction, pg, "Своя БД", "SQL")
Rel(operations, pg, "Своя БД проекций чтения", "SQL")
Rel(platformEvents, pg, "Отдельная БД общего журнала", "SQL")
Rel(providerHub, provider, "API и операции через CLI", "HTTPS")
Rel(runtime, k8s, "Управляет слотами и заданиями", "Kubernetes API")
Rel(runtime, registry, "Публикует и выкладывает образы", "OCI")
Rel(access, vault, "Хранит и проверяет ссылки на секреты платформы", "Vault/Secret metadata")
Rel(providerHub, vault, "Получает секрет через resolver-клиент после разрешения доступа", "Vault/Kubernetes Secret/env")
Rel(interaction, channels, "Доставляет уведомления", "Контракты плагинов")
Rel(agent, models, "Использует модели", "API провайдера")
Rel(worker, access, "Исполняет назначенную фоновую работу", "gRPC")
Rel(worker, providerHub, "Сверка", "gRPC")
Rel(worker, runtime, "Платформенные задания", "gRPC")
Rel(runner, provider, "Работает с Issue, PR и комментариями", "gh/API")
Rel(interaction, obj, "Хранит ссылки на медиа", "S3 API")
```

## Сервисы-владельцы

| Сервис | Каноническая ответственность |
|---|---|
| `access-manager` | Пользователи, организации, группы, allowlist, разрешение SSO-principal, права, внешние аккаунты как субъекты политики, административный аудит. |
| `project-catalog` | Проекты, репозитории, проектная политика, `services.yaml`, источники проектной документации, правила веток, релизные политики, политика размещения. |
| `provider-hub` | Webhook, зеркальные проекции, синхронизация, лимиты, операции провайдера и операционное состояние авторизации по внешним аккаунтам. |
| `package-hub` | Каталог пакетов, установленные и доступные пакеты, источники магазинов, версии, верификация, секреты пакетов. |
| `agent-manager` | Процессы, этапы, роли, шаблоны промптов, агентные запуски, сессии, правила автоматизации, машина приёмки. |
| `fleet-manager` | Серверы, Kubernetes-кластеры, здоровье, связность, размещение. |
| `runtime-manager` | Слоты, workspace materialization, платформенные задания, сборка, выкладка, зеркалирование, очистка, prewarm/reuse и статус среды исполнения. |
| `billing-hub` | Биллинговые аккаунты, записи затрат, распределение затрат, основа счёта. |
| `interaction-hub` | Диалоговые ветки, согласования, уведомления, подписки, попытки доставки, обратные вызовы внешних каналов. |
| `operations-hub` | Модели чтения для пользовательского интерфейса, ленты событий, очереди, блокировки, агрегированные статусы. |

## Инфраструктурные контуры данных

| Контур | Ответственность |
|---|---|
| `platform-event-log` | Отдельная БД и миграции общего журнала доменных событий; сервисы-владельцы подключаются к нему как публикаторы или потребители, но не создают его таблицы в своих БД. |

## Тонкие пограничные компоненты

- `web-console` не принимает доменных решений, не собирает состояние напрямую из БД нескольких сервисов-владельцев и не утверждает actor identity в production-сборке. Первый активный интерфейсный срез в `services/staff/web-console` вызывает только `staff-gateway`, использует сгенерированный TypeScript-клиент из `specs/openapi/staff-gateway.v1.yaml`, ожидает `X-Kodex-Actor-*` от trusted edge/backend-session слоя и оставляет отсутствующие серверные сценарии как пустые или отключённые состояния.
- `user-gateway`, `staff-gateway` и `integration-gateway` отвечают за входящий HTTP-трафик по своим направлениям, авторизацию, маршрутизацию, пограничную обработку webhook/callback событий и ограничение частоты запросов на границе, но не хранят доменную правду.
- Первый активный контур `staff-gateway` обслуживает `web-console` для входящих решений владельца, просмотра runtime summary одного `AgentRun`, safe activity timeline и self-deploy наблюдения: owner inbox идёт через gRPC-вызовы `interaction-hub`, runtime summary/activity timeline/self-deploy plan summary — через `agent-manager.GetAgentRunRuntimeStatus`, `agent-manager.ListAgentActivities` и `agent-manager.ListSelfDeployPlans`, а pre-plan self-deploy readiness при отсутствии plan уточняется только через существующие read RPC `project-catalog.GetSelfDeploySignal` и `project-catalog.ListRepositories`. Self-deploy summary показывает безопасные стадии `signal`, `plan`, `gate`, `approval`, `build_context`, `build`, `deploy`, `health` по данным `agent-manager`, но не читает Kubernetes и не управляет runtime jobs. Gateway не хранит decision state, не владеет `Run`/runtime job/activity timeline/deploy plan/project/provider/governance lifecycle и не агрегирует provider/agent/runtime/governance состояние за пределами явно типизированных safe DTO.
- `integration-gateway` принимает внешние webhook и callback события, проверяет источник, подпись, размер payload, лимиты и backpressure, затем вызывает сервис-владелец по gRPC. Активные MVP-маршруты — provider webhook -> `provider-hub.IngestWebhookEvent` и generic channel callback -> `interaction-hub.RecordChannelCallback`; бизнес-нормализация, provider inbox и callback lifecycle остаются у сервисов-владельцев.
- `platform-mcp-server` даёт MCP-инструментальную поверхность для agent-manager, агентов в слотах и будущих интеграций. Agent-manager и agent-runner обращаются к нему как клиенты MCP. Сам `platform-mcp-server` проверяет источник, очищает данные вызова и маршрутизирует разрешённые инструменты во все сервисы-владельцы по gRPC. Он не становится владельцем агентных запусков, заданий, состояния провайдера, пакетов или проектов.
- `codex-hook-ingress` принимает нормализованные Codex hook events от hook emitter или локального sidecar. Он не является MCP-сервером и не хранит бизнес-состояние; его задача — проверить источник, очистку и маршрутизировать событие сервису-владельцу.

## Порядок реализации gateway-сервисов

Общий `api-gateway` не вводится. HTTP-поверхности разделяются по направлению доступа, чтобы операторские сценарии, внешние пользовательские сценарии и входящие интеграции не смешивали разные политики доступа и жизненные циклы.

| Компонент | Когда реализуется | Причина |
|---|---|---|
| `staff-gateway` | Первый узкий контур доступен для owner inbox/Human gate decision path; следующие срезы расширяют его по мере появления экранов `web-console`. | Это основной HTTP-вход для консоли сотрудников MVP; пользовательский интерфейс не должен ходить напрямую во внутренние gRPC-сервисы. |
| `integration-gateway` | После базового `provider-hub`, когда определён набор webhook, обратных вызовов и входящих событий от провайдеров и внешних интеграций. | `integration-gateway` должен принимать внешние события, но маршрутизировать их в `provider-hub` и другие сервисы-владельцы без собственной доменной логики. |
| `user-gateway` | На границе MVP или после MVP, когда появятся подтверждённые сценарии внешних пользователей. | Это не блокирует внутренний MVP консоли сотрудников, потому что начальные сценарии выполняются сотрудниками и владельцем через `web-console` и `staff-gateway`. |

## Исполнители

- `worker` исполняет фоновую работу, повторы и сверку по поручению сервисов-владельцев.
- `agent-runner` исполняет ролевую агентную работу в слоте и возвращает результат через нативные артефакты провайдера и платформенные контракты.
- Исполнители не ходят напрямую в чужие БД и не вводят собственные канонические статусы.

## Хранилища

- PostgreSQL используется как общий инфраструктурный кластер, но данные разделены по сервисам-владельцам.
- `platform-event-log` использует отдельную БД внутри PostgreSQL-кластера и владеет только журналом событий и checkpoint потребителей.
- Таблицы разных сервисов-владельцев не связываются через `FOREIGN KEY`, межбазовый join или каскадные операции.
- Vault или другой настроенный secret backend хранит секреты платформы и её зависимостей; проекты могут использовать свои хранилища секретов.
- Доменные сервисы не получают секреты через публичные API: после проверки доступа они используют общий resolver-клиент, который держит значение только в памяти процесса на время операции.
- Полные технические логи остаются в контуре среды исполнения и логирования, а PostgreSQL хранит только краткие хвосты и диагностические выдержки.

## Апрув

- request_id: `owner-2026-04-26-platform-architecture-frame`
- Решение: approved
- Комментарий: C4-контейнеры входят в сквозной архитектурный каркас платформы.
