docs(plugin-sdk): v2 — ретро-ревью (6 находок)

- версионирование: shturman_api ↔ набор D-Bus-мажоров; хост экспортирует все
  поддерживаемые мажоры параллельно; неподдерж. версия → Error.Unsupported (не тихо)
- IntentHandler: обязательный dispatch-таймаут; крэш/таймаут/NotAvailable →
  деградированный ответ (#4), пайплайн не виснет (#11)
- vehicle_read: per-vehicle Unavailable (Subscribe ок, SignalChanged молчит, плагин
  деградирует); install-ревью предупреждает о неподдерживаемых сигналах
- авторитет манифеста: extension_points.tiles авторитетны, ui_tiles — квота (len ≤ N)
- storage: квота (ENOSPC плагину не системе — бережёт /data), remove чистит, миграция
- lifecycle: discover/install только для сторонних; first-party — в base-образе, без install
- network host-allowlist приведён к best-effort (синхрон с security-privacy)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 01:02:43 +03:00
parent d9209987e4
commit 64ef300ef4
+47 -13
View File
@@ -4,8 +4,8 @@
> [ipc.md](ipc.md) + [data-model.md](data-model.md) + [security-privacy.md](security-privacy.md). > [ipc.md](ipc.md) + [data-model.md](data-model.md) + [security-privacy.md](security-privacy.md).
> Приоритет №1: даже наши first-party апы строятся на этом SDK. > Приоритет №1: даже наши first-party апы строятся на этом SDK.
Статус: **v1 (на ревью).** Статус: **v2 (на ревью).** v2 — после ретро-ревью (6 находок).
Связано с: [architecture.md](../architecture.md) (#1 тонкое ядро) · [ipc.md](ipc.md) · [data-model.md](data-model.md) · [security-privacy.md](security-privacy.md) · домен F (рантайм/дистрибуция) Связано с: [architecture.md](../architecture.md) (#1 тонкое ядро) · [ipc.md](ipc.md) · [data-model.md](data-model.md) · [security-privacy.md](security-privacy.md) · домены C, F
--- ---
@@ -47,15 +47,22 @@ plugin:
handler: /ru/shturman/plugin/fuel_tracker/intents # путь IntentHandler handler: /ru/shturman/plugin/fuel_tracker/intents # путь IntentHandler
``` ```
**Источник истины и согласованность:** `extension_points.tiles` — авторитетный список
конкретных тайлов; `capabilities.ui_tiles: N`**квота** (Perm-Broker enforce-ит
`len(tiles) ≤ ui_tiles`, иначе install отклоняется `InvalidArgument`). Все фразы
`assistant_intents` маршрутизируются в единственный `extension_points.intents.handler`.
## 3. Capability-модель ## 3. Capability-модель
- Таксономия и **гейтинг по каналам** — в [security-privacy.md](security-privacy.md) §34 - Таксономия и **гейтинг по каналам** — в [security-privacy.md](security-privacy.md) §34
(не дублируем). Манифест **декларирует**Perm-Broker **enforce**. (не дублируем). Манифест **декларирует**enforce (статически — прокси+sandbox от App-Host;
рантайм-гранты — Perm-Broker; security-privacy §5).
- `vehicle_read` принимает **только сигналы из каталога** [data-model.md](data-model.md). - `vehicle_read` принимает **только сигналы из каталога** [data-model.md](data-model.md).
- **`network` — host-allowlist** *(резолв открытого вопроса):* `network: { hosts: [...] }` - **`network` — host-allowlist:** `network: { hosts: [...] }` — намерение ограничить egress.
ограничивает egress только этими хостами (net-namespace + DNS/прокси-allowlist). ⚠️ **Строгая гарантия требует forced-proxy/egress-firewall по SNI/Host** (DNS-allowlist
Голый `network: true` (любой хост) — допустимо, но помечается **повышенным риском** обходится прямым IP); иначе allowlist — **best-effort**, строго работает только бинарный
при установке (особенно в связке с `vehicle_read`/`location` см. security-privacy §7). `network` on/off (security-privacy §3/§7). Голый `network: true` + `vehicle_read`/`location`
**повышенный риск** при установке.
## 4. Точки расширения ## 4. Точки расширения
@@ -71,13 +78,29 @@ plugin:
`ru.shturman.IntentHandler1.HandleIntent(intent_id, slots) → result` и `ru.shturman.IntentHandler1.HandleIntent(intent_id, slots) → result` и
регистрируется через `Assistant.RegisterIntents` (ipc §6). регистрируется через `Assistant.RegisterIntents` (ipc §6).
- Латентно-критичные встроенные интенты (громче, домой) ассистент держит сам, без плагинов. - Латентно-критичные встроенные интенты (громче, домой) ассистент держит сам, без плагинов.
- **Контракт отказа/таймаута:** `HandleIntent` ограничен **обязательным dispatch-таймаутом**
(из бюджета латентности d-assistant §10). На таймаут / крэш плагина (`AppHost.AppCrashed`) /
`NotAvailable` — ассистент даёт **деградированный ответ** («не получилось спросить X», #4),
голосовой пайплайн **не виснет** (#11). Долгие интенты — опц. streaming/progress, не блокирующий вызов.
### 4.3 Данные машины (read-only) ### 4.3 Данные машины (read-only)
- `vehicle_read``VehicleData.Subscribe(names, max_hz)` / `GetSignal` (ipc §3). - `vehicle_read``VehicleData.Subscribe(names, desired_max_hz)` / `GetSignal` (ipc §3).
Только чтение, только заявленные сигналы. Только чтение, только заявленные сигналы.
- **Per-vehicle Unavailable:** заявленный сигнал может быть не поддержан конкретной машиной
(`availability`/`NotAvailable`, data-model §3) — `Subscribe` успешен, но `SignalChanged` не
идёт, пока сигнал недоступен; плагин **деградирует** (#4), не падает. На install-ревью (§6)
заявленные `vehicle_read`, которых нет у текущего авто, показываются предупреждением (best-effort).
### 4.4 Настройки ### 4.4 Настройки и хранилище
- Свой namespace в `Settings` + приватное хранилище (`storage``/data/apps/<id>/`). - Свой namespace в `Settings` + приватное хранилище (`storage``/data/apps/<id>/`).
- **Квота:** у `/data/apps/<id>/` дефолтный размерный лимит (+ опц. больший в манифесте),
enforce на записи (ENOSPC плагину, **не** системе) — `/data` журналируемый, от его места
зависит graceful-flush (a-base §3/§9); неограниченный плагин не должен его исчерпать.
Механизм (project-quota / учёт App-Host) — домен A/F.
- **Remove:** при удалении плагина `/data/apps/<id>/` удаляется (опц. экспорт до удаления) —
не оставляем сирот (отдельно от factory-reset, a-base §12).
- **Миграция:** плагин может объявить версию формата хранилища; на мажорный update мигрирует
данные сам (платформа лишь сигналит «есть старые данные»).
## 5. Разрешение коллизии интентов *(резолв открытого вопроса)* ## 5. Разрешение коллизии интентов *(резолв открытого вопроса)*
@@ -97,13 +120,20 @@ plugin:
манифест, helpers (чтение сигналов, регистрация интентов/UI). Другие языки — манифест, helpers (чтение сигналов, регистрация интентов/UI). Другие языки —
через D-Bus (язык-агностично), биндинги по мере нужды экосистемы. через D-Bus (язык-агностично), биндинги по мере нужды экосистемы.
- **Структура:** каталог с `manifest.yaml` + исполняемый бинарь + ассеты. - **Структура:** каталог с `manifest.yaml` + исполняемый бинарь + ассеты.
- **Жизненный цикл:** discover → install (ревью capabilities) → App-Host поднимает в - **Жизненный цикл (сторонние):** discover → install (ревью capabilities) → App-Host
песочнице с прокси → run → update/remove. Дистрибуция/«магазин»/подпись — **домен F**. поднимает в песочнице с прокси → run → update/remove. Дистрибуция/«магазин»/подпись — **домен F**.
- **First-party** апы доставляются в составе **подписанного read-only base-образа**, НЕ проходят
discover/install/ревью (auto-grant); якорь доверия — сам образ, не флажок (security-privacy §5).
## 7. Версионирование и совместимость ## 7. Версионирование и совместимость
- `shturman_api: "N"` в манифесте — мажорная версия API. Аддитивные изменения не - `shturman_api: "N"` — мажорная версия API; **связана с набором D-Bus-мажоров интерфейсов**
ломают; ломающие → новая мажорная, старые плагины продолжают работать на своей. (напр. `"1"``VehicleData1`, `IntentHandler1`, `Shell1`…); связь фиксируется таблицей.
- **Параллельный рантайм:** хост экспортирует на шине **все поддерживаемые мажоры одновременно**
весь срок поддержки `shturman_api` — иначе «старые работают на своей» не подкреплено (ipc §2, аддитивно).
- **Депрекация:** сколько мажоров хост держит одновременно и как анонсируется EOL старого.
- **Несовместимая версия:** установка плагина с неподдерживаемым `shturman_api` **явно падает**
`ru.shturman.Error.Unsupported` (не тихий запуск/деградация), всплывает в install-ревью.
- SDK-крейт — semver. - SDK-крейт — semver.
## 8. Пример: `fuel-tracker` ## 8. Пример: `fuel-tracker`
@@ -132,3 +162,7 @@ plugin:
| Коллизия интентов | слоистая: built-in > специфичность > first-party > диздамбигуация; + явная адресация | 2026-06-16 | | Коллизия интентов | слоистая: built-in > специфичность > first-party > диздамбигуация; + явная адресация | 2026-06-16 |
| Сеть | host-allowlist в манифесте; голый `network: true` — повышенный риск | 2026-06-16 | | Сеть | host-allowlist в манифесте; голый `network: true` — повышенный риск | 2026-06-16 |
| Биндинги | Rust `shturman-sdk` first-class; др. языки через D-Bus | 2026-06-16 | | Биндинги | Rust `shturman-sdk` first-class; др. языки через D-Bus | 2026-06-16 |
| Версии | shturman_api ↔ набор D-Bus-мажоров; параллельный рантайм; неподдерж. → `Unsupported` | 2026-06-16 |
| Интенты | `HandleIntent` с обязательным таймаутом; крэш/таймаут → деградированный ответ, не виснет | 2026-06-16 |
| Манифест-авторитет | `extension_points.tiles` авторитетны; `ui_tiles` — квота (`len ≤ N`) | 2026-06-16 |
| Хранилище | квота на `/data/apps/<id>` (ENOSPC плагину); remove чистит; миграция — плагин | 2026-06-16 |