# Магазин пакетов

## Назначение

Раздел описывает будущий магазин пакетов как устанавливаемый пакет, а не как жёстко встроенную часть ядра платформы.

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

## Каноническое решение

- Авторский магазин пакетов `kodex` поставляется из приватного репозитория `github.com/codex-k8s/kodex-package-store` как пакет.
- Мы устанавливаем этот пакет в собственную платформу и через него публикуем доступные пакеты.
- Другая установка платформы может использовать наш магазин, свой магазин или только пользовательские источники.
- Отдельный пакет из приватного репозитория `github.com/codex-k8s/kodex-package-platform-site` поставляет сайт платформы и пользовательскую документацию платформы: API, разработка пакетов, добавление пакетов в магазин и каталог.
- В `kodex` оба репозитория объявлены в `.gitmodules` и checkout-ятся внутри `packages/**` после проверки доступа.

## Разделение ответственности

| Контур | Ответственность |
|---|---|
| Пакет магазина | Бизнес-логика магазина, выдача каталога, правила публикации, коммерческие условия магазина. |
| `package-hub` | Подключение источника магазина, локальный доступный каталог, установка пакетов, версии, manifest, верификация и события. |
| `billing-hub` | Счета, платежи, распределение выручки и финансовая отчётность. |
| `provider-hub` | Provider-native состояние репозитория магазина и пакетов, webhook, PR и лимиты провайдера. |

`package-hub` не должен читать магазин на каждый пользовательский запрос. Он синхронизирует доступный каталог в свою БД, а интерфейсы и сервисы читают локальное состояние.

## Чтения из package-hub

Пакет магазина и пакет пользовательского контента платформы не требуют отдельных сущностей или отдельных gRPC-операций. Они читаются через общую пакетную модель:

| Нужно получить | Как читать |
|---|---|
| Доступные пакеты магазина | `ListPackages` с фильтром `package_kind=store`. |
| Установленный магазин в scope | `ListPackageInstallations` с фильтром `package_kind=store` и нужной областью установки. |
| Проверенный manifest магазина | `GetPackageManifest` по выбранной версии пакета. |
| Доступные пакеты сайта и пользовательской документации платформы | `ListPackages` с фильтром `package_kind=platform_content`. |
| Установленный пакет пользовательского контента платформы | `ListPackageInstallations` с фильтром `package_kind=platform_content` и нужной областью установки. |
| Проверенный manifest пользовательского контента | `GetPackageManifest` по выбранной версии пакета. |

Эти чтения дают локальную пакетную истину: источник, пакет, версию, manifest, установку и статусы. Внешний магазин выдаёт каталог через свой клиентский контракт, provider-native состояние репозиториев остаётся в `provider-hub`, runtime-размещение остаётся в `runtime-manager` и `fleet-manager`.

## Виды пакетов магазина и контента

| Вид | Что означает | Manifest |
|---|---|---|
| `store` | Устанавливаемый пакет магазина, который выдаёт доступный каталог пакетов. | Обязана capability `store`; capability `guidance` и `platform_content` запрещены. Пакет может требовать runtime, секреты, действия доступа и API платформы, если это нужно бизнес-логике магазина. |
| `platform_content` | Пользовательский сайт и документация платформы: API, разработка пакетов, добавление пакетов в магазин и каталог. | Обязана capability `platform_content`; capability `guidance` и `store` запрещены. Пакет не должен требовать секреты, действия доступа или API платформы. Runtime допустим только для доставки статического или пользовательского контента. |

Пакет `platform_content` не является руководящим пакетом для агентов. Если документ должен попадать в workspace агента как правило работы, он должен поставляться как `guidance`.

`package-hub` не хранит файлы сайта, справки, API-материалов или каталога магазина в PostgreSQL. Он хранит только проверенный manifest, метаданные, версию, установку и статусы.

## Политика submodule и установки пакетов

- Source submodule пакетов объявляются в `.gitmodules` и размещаются в `packages/**`.
- Пакетная платформа хранит метаданные установленных пакетов в БД.
- Начальные метаданные пакета можно предзаполнить из JSON-манифеста внутри репозитория пакета.
- Пакетная платформа должна получать пакет по зафиксированному `tag` или `commit`.
- Для платных пакетов поставка идёт через прокси платформы, а checkout разрешается только после проверки прав.
- Для downstream-репозиториев отдельный workflow удаляет магазин, сайт и необязательные пакеты, которые не должны попадать в конкретную установку.

## Именование platform-owned пакетов

- Platform-owned package repos именуются по схеме `kodex-package-<name>`.
- Имя должно описывать устанавливаемый пакет, а не проект-потребитель.
- Для сайта и пользовательской документации используется slug `kodex-package-platform-site`.

## Что не делать

- Не вшивать единственный магазин пакетов в ядро платформы.
- Не смешивать публичный сайт платформы с руководящими пакетами для агентов.
- Не считать каталог доступных пакетов источником состояния установки: состояние установки хранится локально в платформе.
- Не считать подключение submodule достаточной установкой пакета: установка требует записи в `package-hub`, проверки manifest, прав, версии и секретов.
- Не считать `package-hub` бизнес-системой магазина: правила публикации, продажи и выдачи внешнего каталога остаются внутри пакета магазина.
