# Runtime Config

## 1. Назначение документа

Этот документ фиксирует конфигурацию окружения, storage и базовые operational assumptions для MVP.

Его задача - убрать неявные решения, которые обычно всплывают уже в процессе написания кода.

## 2. Базовые решения для MVP

- каноническая БД: `PostgreSQL`
- локальная разработка и тесты используют ту же `PostgreSQL`-модель хранения
- artifact storage: локальная файловая система
- MCP transport: `Streamable HTTP`
- admin API и mcp-server запускаются как отдельные приложения

## 3. Artifact storage

В MVP sample JSON, `.proto`, `descriptor set` и YAML import payload должны храниться в локальном файловом storage.

Требования:

- все файлы кладутся в контролируемый базовый каталог;
- в БД хранится только `storage_ref`;
- структура каталогов должна быть детерминированной;
- storage слой должен быть абстрагирован, чтобы потом заменить его на S3-compatible backend.

Рекомендуемая структура:

```text
var/crank/
  samples/
  descriptors/
  yaml-imports/
```

## 4. Секреты и auth profiles

Для целевой модели:

- operation хранит только `auth_profile_ref`;
- `AuthProfile` хранит только ссылки на `secret_id`;
- plaintext секреты не должны попадать в YAML export;
- plaintext секреты не должны логироваться;
- runtime получает секрет только на короткое время перед upstream вызовом.

Стартовая реализация:

- `PostgreSQL`-backed secret store;
- `ciphertext` хранится в БД;
- шифрование выполняется через `CRANK_MASTER_KEY`;
- ключ шифрования приходит только из env.

## 5. Переменные окружения

Минимально ожидаются:

- `POSTGRES_HOST`
- `POSTGRES_PORT`
- `POSTGRES_DB`
- `POSTGRES_USER`
- `POSTGRES_PASSWORD`
- `POSTGRES_MAX_CONNECTIONS`
- `POSTGRES_MIN_CONNECTIONS`
- `POSTGRES_ACQUIRE_TIMEOUT_MS`
- `POSTGRES_IDLE_TIMEOUT_MS`
- `POSTGRES_MAX_LIFETIME_MS`
- `CRANK_ADMIN_API_IMAGE`
- `CRANK_MCP_SERVER_IMAGE`
- `CRANK_UI_IMAGE`
- `CRANK_STORAGE_ROOT`
- `CRANK_PUBLISH_BIND`
- `CRANK_ADMIN_BIND`
- `CRANK_ADMIN_RATE_LIMIT_RPS`
- `CRANK_ADMIN_RATE_LIMIT_BURST`
- `CRANK_MCP_BIND`
- `CRANK_MCP_REFRESH_MS`
- `CRANK_MCP_RATE_LIMIT_RPS`
- `CRANK_MCP_RATE_LIMIT_BURST`
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY`
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW`
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS`
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS`
- `CRANK_LOG_LEVEL`
- `CRANK_MASTER_KEY`
- `CRANK_BASE_URL`

Опционально:

- `CRANK_ADMIN_TOKEN`
- `CRANK_DEMO_SEED`
- `CRANK_CACHE_BACKEND`
- `CRANK_CACHE_URL`
- `CRANK_CACHE_DEFAULT_TTL_MS`

Стартовое значение для refresh published tools:

- `CRANK_ADMIN_RATE_LIMIT_RPS=30`
- `CRANK_ADMIN_RATE_LIMIT_BURST=60`
- `CRANK_MCP_REFRESH_MS=5000`
- `CRANK_MCP_RATE_LIMIT_RPS=60`
- `CRANK_MCP_RATE_LIMIT_BURST=120`

Стартовые значения для runtime concurrency limits:

- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY=64`
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS=16`

## 6. Логирование и трассировка

Для MVP нужно использовать:

- structured logging через `tracing`;
- correlation id для test runs и runtime execution;
- раздельные стадии ошибок: schema, mapping, adapter, external service.

## 7. Таймауты и retries

Рекомендуемые стартовые значения:

- default timeout: `10s`
- retry default: `1` attempt, то есть без автоматического повтора

Причина:

- сначала важнее детерминированность и прозрачность;
- aggressive retries могут маскировать реальные ошибки интеграции.

## 8. Режимы запуска

Минимально нужны два режима:

- local development
- demo/deployment

Local development:

- локальное окружение должно иметь доступ к `PostgreSQL`;
- локальный storage;
- app-level auth и bootstrap admin user через `.env`.
- при необходимости UI можно наполнить живыми demo-данными через `CRANK_DEMO_SEED=true`.

Demo/deployment:

- `PostgreSQL`;
- локальный или сетевой storage;
- включенная app-level auth-защита admin-api;
- стабильный `Streamable HTTP` endpoint для MCP.
- containerized runtime через `Docker` и `docker-compose`.
- optional shared cache layer через `Valkey/Redis`.
- registry-backed image rollout через `GHCR` или совместимый registry.

### Cache env

Для optional cache/coordination layer должны быть предусмотрены:

- `CRANK_CACHE_BACKEND`
- `CRANK_CACHE_URL`
- `CRANK_CACHE_DEFAULT_TTL_MS`

Рекомендуемая модель:

- `CRANK_CACHE_BACKEND=memory` по умолчанию;
- `CRANK_CACHE_BACKEND=valkey` или `redis` при наличии внешнего cache store;
- без этих переменных система должна оставаться полностью работоспособной.

### Cache boundaries

В платформе должны существовать два разных cache-контура:

- `platform / coordination cache`
- `response cache`

Первый контур хранит служебное краткоживущее состояние:

- ingress rate limiting;
- replay guard;
- ephemeral coordination state;
- shared snapshots published MCP catalogs between instances;
- будущие short-lived / one-time token helpers.

Второй контур хранит только кэшируемые ответы операций.

Текущий безопасный runtime scope для response cache:

- `REST GET`;
- `GraphQL query`.
- `gRPC unary` только при `GrpcTarget.read_only = true`.

Это не означает автоматическое кэширование всех protocol families. Следующим кандидатом на расширение
может быть только следующий отдельно обоснованный protocol path, а не "cache everything".

Эти контуры не должны смешивать ключи друг с другом.

### Cache key isolation

Базовое правило изоляции:

- разные `workspace` не должны делить одни и те же cache keys;
- разные `agent` внутри одного `workspace` тоже не должны делить одни и те же response cache keys по умолчанию;
- разные `operation` внутри одного `agent` не должны попадать в общий response cache namespace.

Стартовая модель namespace для response cache:

- `workspace + agent + operation + operation version + request fingerprint`

Стартовая модель namespace для platform / coordination cache:

- `workspace + agent + cache scope + logical key`

Это позволяет безопасно использовать один внешний `Valkey/Redis` сразу для нескольких агентов и рабочих областей без взаимного пересечения данных.

### Auth env

Для app-level auth нужны:

- `CRANK_SESSION_SECRET`
- `CRANK_PASSWORD_PEPPER`
- `CRANK_BOOTSTRAP_ADMIN_EMAIL`
- `CRANK_BOOTSTRAP_ADMIN_PASSWORD`
- `CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME`

Для secret store foundation нужен:

- `CRANK_MASTER_KEY`

`CRANK_MASTER_KEY` обязателен и для `admin-api`, и для `mcp-server`, потому что оба приложения
должны уметь резолвить `secret_id` в runtime.

Для опционального demo-seed:

- `CRANK_DEMO_SEED=true`

В deployment workflow больше не используется монолитный `DEPLOY_ENV_FILE`.

`.env` на сервере собирается из отдельных GitHub secrets, причем имя секрета совпадает с именем
runtime env-переменной. Это значит, что:

- `CRANK_MASTER_KEY` хранится как GitHub secret `CRANK_MASTER_KEY`;
- `CRANK_DEMO_SEED` хранится как GitHub secret `CRANK_DEMO_SEED`;
- и так же для остальных runtime-переменных.

Для БД основной runtime-контракт теперь компонентный:

- `POSTGRES_HOST`
- `POSTGRES_PORT`
- `POSTGRES_DB`
- `POSTGRES_USER`
- `POSTGRES_PASSWORD`
- `POSTGRES_MAX_CONNECTIONS`
- `POSTGRES_MIN_CONNECTIONS`
- `POSTGRES_ACQUIRE_TIMEOUT_MS`
- `POSTGRES_IDLE_TIMEOUT_MS`
- `POSTGRES_MAX_LIFETIME_MS`

Для pool behavior используются явные defaults:

- `POSTGRES_MAX_CONNECTIONS=20`
- `POSTGRES_MIN_CONNECTIONS=2`
- `POSTGRES_ACQUIRE_TIMEOUT_MS=5000`
- `POSTGRES_IDLE_TIMEOUT_MS=600000`
- `POSTGRES_MAX_LIFETIME_MS=1800000`

Для runtime concurrency используются явные defaults:

- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY=64`
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS=16`

Для MCP transport ingress throttling используются явные defaults:

- `CRANK_MCP_RATE_LIMIT_RPS=60`
- `CRANK_MCP_RATE_LIMIT_BURST=120`

Для admin-api ingress throttling используются явные defaults:

- `CRANK_ADMIN_RATE_LIMIT_RPS=30`
- `CRANK_ADMIN_RATE_LIMIT_BURST=60`

`CRANK_DATABASE_URL` допускается только как backward-compatible fallback для локальных тестов и
переходного периода, но не как основная deployment-модель.

## 8.1. Delivery artifacts

Для production-like запуска проект должен поставляться с:

- `Dockerfile` для backend приложений;
- `deploy/community/docker-compose.yml` как canonical Community deployment manifest;
- `deploy/community/.env.example` как canonical Community env template;
- optional `Valkey` service как рекомендованный, но не обязательный компонент Community deployment;
- root `docker-compose.yml` и root `.env.example` только как local development convenience files;
- healthcheck endpoints;
- reverse proxy configuration examples.

Подробности вынесены в `docs/deployment.md`.

## 9. Что важно не допустить

- пути к storage, зашитые в код;
- секреты в `.yaml` exports;
- разные конфигурационные модели для local и production без причины;
- смешивание runtime config и business config operation.

## 10. Практический итог

До старта разработки должны быть приняты как минимум такие решения:

- где лежит БД;
- где лежат artifacts;
- как резолвятся `secret_id` и как ротируется `CRANK_MASTER_KEY`;
- на каких bind-address запускаются `admin-api` и `mcp-server`;
- какой transport использует MCP server.
