# Границы open-core и защита коммерческого кода

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

Этот документ определяет:

- как разделять открытый и коммерческий функционал;
- какие части должны оставаться в публичном репозитории;
- какие части должны выноситься в private delivery;
- как защищать коммерческий код без ложной ставки на обфускацию и "антидекомпиляцию".

## 2. Базовый принцип

Коммерческий код нужно защищать не попытками спрятать уже опубликованный исходный код, а правильной границей поставки.

Принцип:

- открытый код остается действительно открытым;
- коммерческий код не попадает в public repository;
- коммерческие сервисы и модули поставляются из приватного контура;
- критичные правила лицензирования, metering и security policy исполняются на серверной стороне.

## 3. Что считается открытым контуром

В публичном репозитории должны оставаться:

- доменная модель Community;
- `admin-api`, `mcp-server` и `ui`, необходимые для Community;
- `REST` в открытой редакции;
- секреты, auth profiles, agent publishing, logs и usage;
- статический ключ AI-агента;
- контейнерное развертывание Community;
- optional cache abstraction и Community fallback path без внешнего cache store;
- документация, тесты и демо-сценарии Community.

## 4. Что считается коммерческим контуром

В приватный контур должны выноситься:

- short-lived token service;
- one-time token service;
- `GraphQL` и `gRPC unary`, если они выводятся из Community;
- `SSO`, `2FA`, расширенная `RBAC`, `audit log`;
- `WebSocket`, `SOAP`, `gRPC streaming`, если они не включаются в Community;
- advanced streaming execution modes;
- metering и billing;
- cloud control plane;
- managed shared cache layer defaults;
- enterprise licensing and entitlement checks;
- private operational tooling and support tooling.

## 5. Модель разделения репозиториев

### 5.1. Public repository

Этот репозиторий должен содержать только:

- Community runtime;
- extension points;
- capability model;
- честные product contracts для открытой редакции.

### 5.2. Private repositories

Коммерческие возможности должны жить отдельно:

- либо в приватных crates;
- либо в приватных приложениях и сервисах;
- либо в отдельных private repositories с собственной поставкой.

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

- `crank-community` — public Community repo;
- `crank-enterprise` — private self-hosted extensions;
- `crank-cloud` — private cloud control plane и hosted-only logic.

Важно:

- создание `crank-community`, `crank-enterprise` и `crank-cloud` должно быть отдельным осознанным шагом;
- до этого момента в текущем репозитории нужно завершить capability model, extension seams и public contracts;
- физическое вынесение private code нельзя начинать раньше, чем эти три целевых repositories созданы и для них определены delivery boundaries.
- на текущий момент public repository `crank-community` уже создан; следующий обязательный внешний шаг — создание private repositories `crank-enterprise` и `crank-cloud`.

## 6. Техническая стратегия разделения

### 6.1. Capability-first design

Открытый код должен опираться на capability model:

- edition capabilities;
- protocol capabilities;
- auth capabilities;
- security capabilities.

Это позволяет:

- скрывать недоступные функции в UI;
- не смешивать Community и commercial code paths;
- добавлять private implementations без форка всей архитектуры.

### 6.2. Extension seams

В public repo должны быть только контракты и точки расширения:

- trait boundaries;
- service contracts;
- edition flags;
- protocol registry abstraction;
- token issuer abstraction;
- cache store abstraction;
- feature availability checks.

Дополнительно для runtime layer:

- premium protocol adapters должны подключаться как feature-gated seams;
- `REST`-база должна собираться без `GraphQL/gRPC/SOAP/WebSocket` crates;
- `UnsupportedProtocol` должен оставаться публичным fallback contract для disabled protocol paths.

Private code должен подключаться как реализация этих контрактов, а не как условные ветки по всему коду Community.

### 6.3. Server-side enforcement

Критичные коммерческие ограничения должны исполняться только на сервере:

- edition capabilities;
- token issuance policy;
- licensing checks;
- metering;
- protocol availability;
- per-operation security rules.

Фронтенд может только отображать состояние. Он не должен быть единственным местом, где проверяется "можно / нельзя".

## 7. Что не является реальной защитой

Нельзя считать надежной защитой:

- минификацию frontend-кода;
- обфускацию JavaScript;
- "сложность" Rust binary как основную линию защиты;
- попытку скрыть коммерческую логику в публичном репозитории через feature flags, если исходный код уже доступен.

Все это может немного повысить порог извлечения, но не решает задачу защиты коммерческого IP.

## 8. Реальная защита коммерческого кода

### 8.1. Не публиковать исходный код

Основное правило:

- коммерческий исходный код не должен попадать в public repo.

### 8.2. Поставлять private artifacts

Коммерческий контур должен поставляться как:

- private container images;
- private binary artifacts;
- private `Helm` charts;
- private configuration bundles.

### 8.3. Подписывать артефакты

Для коммерческой поставки должны использоваться:

- подписанные контейнерные образы;
- проверяемая provenance metadata;
- versioned private releases.

### 8.4. Хранить ключевую логику на сервере

Наиболее чувствительные части должны оставаться на серверной стороне:

- licensing;
- token issuance;
- cloud metering;
- enterprise access policy;
- hosted control plane logic.

### 8.5. Не включать private UI в OSS bundle

Если функция коммерческая, ее UI не должен полноценно поставляться в Community build.

Допустимы:

- capability-driven hiding;
- ограниченный teaser copy.

Недопустимы:

- полностью рабочие commercial screens в open-source bundle;
- наличие private API contracts без server-side gating.

## 9. Что нужно сделать в кодовой базе

Для подготовки к коммерческой реализации в open-source коде должны появиться:

- edition capability model;
- protocol capability model;
- auth capability model;
- интерфейсы для token issuer и enterprise access services;
- server-side policy checks;
- UI gating по capability flags;
- отдельные delivery manifests для Community.

Первый обязательный шаг на практике:

- canonical public deployment manifest должен жить отдельно от root development convenience files;
- Community release path должен опираться на `deploy/community/*`;
- private `Enterprise` и `Cloud` manifests не должны проектироваться как вариации того же root compose-файла.

Подготовительные bootstrap artifacts для будущих репозиториев должны храниться отдельно от production manifests.
В текущем репозитории для этого используются:

- `templates/repositories/crank-community/*`
- `templates/repositories/crank-enterprise/*`
- `templates/repositories/crank-cloud/*`

## 10. Связанные документы

- `docs/product-editions.md`
- `docs/community-release-checklist.md`
- `docs/repository-split-map.md`
- `docs/agent-auth-model.md`
- `docs/module-decomposition.md`
- `docs/frontend-roadmap.md`
- `docs/refactoring-roadmap.md`
- `docs/implementation-plan.md`
