Files
shturman/docs/domains/f-plugin-host.md

135 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Домен F — Plugin host & экосистема
> Рантайм и экосистема плагинов **поверх App-Host**: жизненный цикл (install/update/remove),
> валидация и подпись манифеста, дистрибуция, dev-tools. API/манифест — [plugin-sdk](../contracts/plugin-sdk.md);
> исполнение/sandbox — App-Host (ядро); **F — оркестрация и экосистема**.
Статус: **v2 (на ревью).** v2 — после adversarial-ревью (17 находок).
Связано с: [plugin-sdk.md](../contracts/plugin-sdk.md) (API) · [security-privacy.md](../contracts/security-privacy.md) (sandbox/подпись/id) · [ipc.md](../contracts/ipc.md) (`PluginManager`, `AppHost`) · [a-base-system.md](a-base-system.md) (§3 durable-write/storage, §8 память) · домен C (capability-review UX) · все домены (точки расширения)
---
## 1. Назначение и границы
- **F:** жизненный цикл плагинов + валидация манифеста + дистрибуция + dev-tools + enforcement версий + бюджет ресурсов.
- **App-Host (ядро, `ru.shturman.AppHost`)** физически запускает/супержит/песочит. **F оркестрирует, App-Host исполняет.**
- **plugin-sdk** = API/манифест; **security-privacy** = sandbox/capabilities/доверие. F их **использует, не дублирует**.
- **Границы:** не ядро; не обходит capability-модель; не трогает CAN/safety.
## 2. Жизненный цикл плагина
`discover → validate → install → activate → run → update → remove`. F оркестрирует; запуск/sandbox — App-Host.
**First-party** апы путь НЕ проходят (в подписанном base-образе, security-privacy §5).
- **Где живёт/исполняется:** пакет (manifest + бинарь + ассеты) — в `/data/apps/<id>/`. **Код — отдельное
exec-поддерево** (`/data/apps/<id>/bin`, монтируется exec в bubblewrap); данные (`storage`) — **noexec**.
Политика exec/mount на `/data` — совместно с a-base §3 (открытый вопрос §10).
- **Передача в App-Host (IPC):** после `validate`+`install` `PluginManager` зовёт **`AppHost.LoadApp(id)`**
(читает манифест, конфигурит bubblewrap + фильтр-прокси + `sender→манифест`), затем id доступен `StartApp`.
`RemovePlugin`/`UpdatePlugin`**`AppHost.UnloadApp(id)`** (снести sandbox/прокси/identity-binding — иначе висит авторизация на шине).
- **Teardown (remove/update):** если работает → `StopApp` → await `AppStopped` (таймаут/force-kill) →
Perm-Broker отзывает гранты + подписки VehicleData падают по owner-exit → удалить `/data/apps/<id>`
(опц. экспорт). (`NameOwnerChanged` — сеть безопасности при крэше, не плановый путь; план зовёт `StopApp` явно.)
- **Атомарность install/update** (power-safe #5, контракт a-base §3): распаковка в staging `/data/apps/<id>.new/`
→ fsync → **атомарный `rename`** на живой каталог → fsync(parent); прежняя версия цела до успеха (откат);
health-check до commit (аналог RAUC mark-good); идемпотентное доедание `<id>.new` на next boot.
## 2a. Бюджет ресурсов плагина
App-Host из манифеста на activate ставит **cgroup-лимиты** (`MemoryMax`/`MemoryHigh`, `CPUQuota`, `pids.max`):
дефолтный потолок + опц. больший в манифесте (виден в ревью — как дисковая квота plugin-sdk §4.4).
В OOM-иерархии (a-base §8) сторонний плагин — **низкий приоритет** (ниже Stage 1-ядра и офлайн-LLM):
убивается раньше killer-фичи → `AppCrashed` → деградация (#4). CPU-троттлинг — чтобы busy-loop не съел UI (#11).
## 3. Валидация манифеста (целостность — только с подписью)
- **Schema-валидация** (plugin-sdk §2): поля; capabilities из таксономии; `len(tiles)≤ui_tiles`; `ui_screens`;
`vehicle_read` только из каталога data-model; i18n-строки (`ru` обязателен).
- **`shturman_api`:** неподдерживаемая → `Error.Unsupported` (plugin-sdk §7); **EOL установленного** (§3 ниже).
- **id-целостность** (security-privacy §5): отказ при коллизии с установленным/встроенным. **Манифестный id**:
`ru.shturman.*` (весь tree) **закрыт** для сторонних — их id = свой reverse-DNS (`dev.example.*`). *(Отдельно:
D-Bus OWN-экспорт плагина — платформа выдаёт префикс `ru.shturman.plugin.<id>.*`, это не манифестный id.)*
- **Sideload-гигиена (распаковка привилегированным до sandbox):** отбой path-traversal/symlink-escape;
лимит несжатого размера/числа записей (анти-zip-bomb); проверка места `/data`/квоты до распаковки (без частичной порчи).
- **Целостность во времени (без подписи неполна):** App-Host **ре-валидирует манифест на КАЖДОМ activate**
(capabilities из файла, не кэш с момента approve); **пин одобренного capability-набора** (хэш) — расширение
на диске после approve → форс ре-ревью, не молча. Полная целостность — только с подписью (store-фаза).
- **Аудит:** install/update/remove + grant/revoke — события **нормативного audit-log** (владелец A §9 /
security-privacy): id, версия, capability-набор, время (без payload). `PluginManager` эмитит их вместе с сигналами §7.
## 4. Дистрибуция
- **Sideload** (локальный пакет, на свой риск, без подписи) — v3.
- **Курируемый стор/реестр** с ревью + **обязательной подписью** — later. Пакет: каталог `manifest.yaml` + бинарь + ассеты + `locales/`.
## 5. Capability-review и управление (UX — домен C)
- Install-time: запрашиваемые capabilities + предупреждения о рисковом (`vehicle_read`+`network`; неподдерживаемые сигналы) — security-privacy §5/§7.
- Review/revoke грантов — UI домена C.
## 6. Dev-tools и тест-харнесс (#13)
- **v0 (без рантайма):** SDK-крейт `shturman-sdk`, **scaffolding** плагина, **валидатор манифеста**.
- **dev-run:** быстрый локальный запуск плагина в dev-VM (App-Host есть с v0); sandboxed install-flow — v3.
Нужен `justfile`-таргет в dev-environment.
- **Тест-харнесс plugin-host (#13):** библиотека **плохих манифестов** (коллизия id, неподдерж. `shturman_api`,
`tiles>ui_tiles`, capability вне таксономии, `vehicle_read` вне каталога, попытка `ru.shturman.*`) +
**тест-плагины** (crash-loop, mem-hog, quota-overflow, capability-escape, slow-shutdown, power-loss при update).
Завести в dev-environment (fault-injection) + интеграционный тир CI.
## 7. IPC
- **`ru.shturman.PluginManager`** (домен F, в реестре ipc §3): `InstallPlugin(pkg)`, `RemovePlugin(id)`,
`UpdatePlugin(id)`, `ListPlugins()`; сигналы `PluginInstalled/Removed/Updated` (+ эмит audit-записей).
- **Передача в App-Host:** `AppHost.LoadApp(id)` / `UnloadApp(id)` (ipc §3). Управление плагинами —
**привилегированная операция**, недоступна самим плагинам через прокси.
## 8. Функции
| функция | MVP/later | зависит от | фаза |
|---------|-----------|------------|------|
| SDK-крейт `shturman-sdk` | **MVP** | — | v0 |
| Dev-tools: scaffolding + валидатор манифеста | **MVP-dev** | — | v0 |
| Dev-run плагина в VM (через App-Host) | **MVP-dev** | App-Host, dev-environment | v0+ |
| Тест-харнесс plugin-host (#13) | **MVP-dev** | dev-environment | v0+ |
| Жизненный цикл (install/update/remove) + LoadApp/UnloadApp | later | App-Host, PluginManager, plugin-sdk | v3 |
| Атомарный install/update (staging+rename, a-base §3) | later | a-base §3 | v3 |
| Бюджет ресурсов (cgroup + OOM-приоритет) | later | a-base §8 | v3 |
| Schema/`shturman_api`/id-валидация + ре-валидация + capability-pin | later | plugin-sdk, security-privacy | v3 |
| Sideload (+ гигиена распаковки) | later | App-Host, PluginManager | v3 |
| Capability-review UX (с C) + аудит операций | later | C, security-privacy, A §9 | v3 |
| Подпись манифеста/бандла + keyring | later | security-privacy (схема §6); v4-trust-anchor (signed OTA) | v3+/v4 |
| Курируемый стор/реестр | later | — | later |
## 9. Зависимости
- **Вниз/вбок:** App-Host (запуск/sandbox/прокси/Load-Unload), plugin-sdk (API/манифест), security-privacy
(capabilities/доверие/подпись/namespace), a-base (§3 durable-write/exec-mount, §8 память/OOM, §9 audit-log),
data-model (валидация `vehicle_read`), C (review/revoke UI), dev-environment (dev-tools/харнесс).
- **Вверх:** механизм расширения third-party для всех доменов.
## 10. Открытые вопросы
- 🟡 **Exec/mount-политика `/data`** (exec-поддерево бинаря vs noexec) — совместно с a-base §3.
- 🟡 **Схема подписи** (формат, keyring издателей, ревокация, охват = манифест+бинарь) — со стором. → security-privacy + F.
- 🟡 **WASM-тир структурно несовместим с identity-моделью:** in-process WASM не имеет своего D-Bus-соединения/PID/cgroup
→ sender-identity-гейтинг (VehicleData/Settings/OWN) к нему неприменим без host-side брокера в рантайме. Не просто «паковка». → architecture §7 / security-privacy.
- ◻️ **`shturman_api` EOL/депрекация** установленных: warn→grace→block-launch (не тихий крэш), роль UpdatePlugin/ревью. (тайминг — ipc §2).
- ◻️ **Governance стора** (модерация, доверие издателей).
---
## Журнал решений (домен F)
| Решение | Выбор | Дата |
|---------|-------|------|
| Граница | F — оркестрация; App-Host исполняет (LoadApp/UnloadApp); plugin-sdk — API | 2026-06-16 |
| Где живёт | `/data/apps/<id>/`; код — exec-поддерево, данные — noexec; политика с a-base §3 | 2026-06-16 |
| Жизненный цикл | install/activate/teardown с явным StopApp+отзыв грантов; first-party вне пути | 2026-06-16 |
| Атомарность | staging + атомарный rename (a-base §3 durable-write); откат; идемпотентное доедание | 2026-06-16 |
| Ресурсы | cgroup-лимиты из манифеста; плагин — низкий OOM-приоритет (a-base §8) | 2026-06-16 |
| Валидация | ре-валидация на каждом activate + capability-pin; sideload-гигиена распаковки; аудит операций | 2026-06-16 |
| Namespace | манифестный id `ru.shturman.*` закрыт для сторонних; OWN-экспорт `ru.shturman.plugin.<id>.*` — выдаёт платформа | 2026-06-16 |
| Доверие | install-approve+sandbox (sideload на риск); подпись+keyring — со стором | 2026-06-16 |
| Фазы | SDK/dev-tools/харнесс — v0; плагин-экосистема — v3 | 2026-06-16 |