Files
shturman/docs/contracts/plugin-sdk.md
T
kk0t9 fb27d8d2fe docs: завершить Tier 1 (контракты) + ревью-фикс red-line CAN
- security-privacy: изоляция, capabilities, гейтинг по каналам, приватность/152-ФЗ;
  first-party = вшит в подписанный образ; рисковые комбинации (vehicle_read+network)
- plugin-sdk: манифест, точки расширения, коллизия интентов, host-allowlist
- hardware: RK3588, power-safe, периферия, HAL/BSP портирование
- ВАЖНО: уточнён red-line CAN (принцип #2 + hardware §4): «чтение» = без
  управляющих/actuator/write-передач; диагностические OBD read-запросы допустимы
  (иначе не прочитать DTC); listen-only — только пассивный сниффинг
- + автозащита питания, тепло, износ eMMC; кросс-доковые аннотации

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:28:52 +03:00

135 lines
8.6 KiB
Markdown
Raw 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.
# Контракт: Plugin / Extension SDK
> **Главный API платформы.** Как расширять Штурман, не трогая ядро. Синтез
> [ipc.md](ipc.md) + [data-model.md](data-model.md) + [security-privacy.md](security-privacy.md).
> Приоритет №1: даже наши first-party апы строятся на этом SDK.
Статус: **v1 (на ревью).**
Связано с: [architecture.md](../architecture.md) (#1 тонкое ядро) · [ipc.md](ipc.md) · [data-model.md](data-model.md) · [security-privacy.md](security-privacy.md) · домен F (рантайм/дистрибуция)
---
## 1. Принцип
- Плагин = **отдельный процесс**, говорит по D-Bus через **фильтрующий прокси**, в
**bubblewrap-песочнице**. Видит только заявленное в манифесте.
- Тот же SDK — у first-party апов (с расширенными capabilities). Если для фичи
«нужно лезть в ядро» — это баг API, чиним API (принцип #9).
## 2. Манифест (полная схема)
Формат — **YAML**. Единая модель: всё, что нужно плагину, — это **capabilities**
(объединили `capabilities`+`permissions` из исходной спеки в один список).
```yaml
plugin:
id: ru.shturman.plugin.fuel-tracker # reverse-DNS, уникальный
name: "Учёт расхода"
version: 0.1.0 # semver
description: "Пробег и средний расход"
author: "Имя / организация"
shturman_api: "1" # мажорная версия API (совместимость)
capabilities:
vehicle_read: [speed, maf, fuel_level, fuel_rate] # только из каталога data-model
assistant_intents:
- "сколько я проехал"
- "средний расход"
ui_tiles: 1
storage: true
# network: { hosts: ["api.example.ru"] } # опц.: host-allowlist (см. §3)
extension_points:
tiles:
- id: consumption
title: "Расход"
intents:
handler: /ru/shturman/plugin/fuel_tracker/intents # путь IntentHandler
```
## 3. Capability-модель
- Таксономия и **гейтинг по каналам** — в [security-privacy.md](security-privacy.md) §34
(не дублируем). Манифест **декларирует** → Perm-Broker **enforce**.
- `vehicle_read` принимает **только сигналы из каталога** [data-model.md](data-model.md).
- **`network` — host-allowlist** *(резолв открытого вопроса):* `network: { hosts: [...] }`
ограничивает egress только этими хостами (net-namespace + DNS/прокси-allowlist).
Голый `network: true` (любой хост) — допустимо, но помечается **повышенным риском**
при установке (особенно в связке с `vehicle_read`/`location` — см. security-privacy §7).
## 4. Точки расширения
### 4.1 UI — тайлы и экраны (слот-модель, решение №6)
- `Shell.RegisterTile(decl)`**декларативный** элемент (рендерит shell в едином стиле).
- `Shell.RegisterScreen(decl | surface)` — декларативный экран **или** Wayland-поверхность (богатый ап рисует сам).
- Декларативный словарь (констрейнт): `icon`, `title`, `value`, `state`, привязки к
данным, `action`. Сложнее этого → поверхность. *(🟡 глубину декларативного DSL
уточним при домене C/Shell.)*
### 4.2 Интенты ассистента
- Манифест: `assistant_intents: [фразы]`. Плагин реализует
`ru.shturman.IntentHandler1.HandleIntent(intent_id, slots) → result` и
регистрируется через `Assistant.RegisterIntents` (ipc §6).
- Латентно-критичные встроенные интенты (громче, домой) ассистент держит сам, без плагинов.
### 4.3 Данные машины (read-only)
- `vehicle_read``VehicleData.Subscribe(names, max_hz)` / `GetSignal` (ipc §3).
Только чтение, только заявленные сигналы.
### 4.4 Настройки
- Свой namespace в `Settings` + приватное хранилище (`storage``/data/apps/<id>/`).
## 5. Разрешение коллизии интентов *(резолв открытого вопроса)*
Когда два плагина регистрируют пересекающиеся фразы — слоистая политика:
1. **Встроенные латентно-критичные** интенты — всегда выигрывают, минуя плагины.
2. **Специфичность:** более точное/длинное совпадение бьёт более общее.
3. **Тай-брейк:** first-party > сторонний.
4. **Всё ещё неоднозначно → диздамбигуация:** ассистент уточняет у пользователя
(«кого спросить — X или Y?») либо LLM-роутер выбирает по контексту.
5. **Явная адресация:** «спроси у *учёта расхода*, сколько я проехал» — направляет в конкретный плагин.
6. **На регистрации** пересечения детектируются и подсвечиваются (автору/при установке).
## 6. Биндинги и структура плагина
- **Rust SDK-крейт `shturman-sdk`** — first-class: типобезопасные обёртки над D-Bus,
манифест, helpers (чтение сигналов, регистрация интентов/UI). Другие языки —
через D-Bus (язык-агностично), биндинги по мере нужды экосистемы.
- **Структура:** каталог с `manifest.yaml` + исполняемый бинарь + ассеты.
- **Жизненный цикл:** discover → install (ревью capabilities) → App-Host поднимает в
песочнице с прокси → run → update/remove. Дистрибуция/«магазин»/подпись — **домен F**.
## 7. Версионирование и совместимость
- `shturman_api: "N"` в манифесте — мажорная версия API. Аддитивные изменения не
ломают; ломающие → новая мажорная, старые плагины продолжают работать на своей.
- SDK-крейт — semver.
## 8. Пример: `fuel-tracker`
Манифест выше. Что делает: подписывается на `speed/maf/fuel_level/fuel_rate`,
считает пробег и средний расход (свой trip-стейт в `storage`), показывает тайл
«Расход», отвечает на интенты «сколько я проехал»/«средний расход». Никакой сети,
никакой записи — типичный безопасный плагин.
---
## Открытые вопросы (найдено на self-review → роутинг)
- 🟡 **Глубина декларативного UI-DSL** (что именно можно выразить тайлом/экраном без
поверхности). → домен C (Shell).
- ◻️ **Дистрибуция, «магазин», подпись** плагинов. → домен F.
---
## Журнал решений (plugin-sdk)
| Решение | Выбор | Дата |
|---------|-------|------|
| Манифест | YAML; единый список capabilities (объединили с permissions) | 2026-06-16 |
| Точки расширения | UI (тайлы/экраны, слот-модель) · интенты · vehicle_read · settings | 2026-06-16 |
| Коллизия интентов | слоистая: built-in > специфичность > first-party > диздамбигуация; + явная адресация | 2026-06-16 |
| Сеть | host-allowlist в манифесте; голый `network: true` — повышенный риск | 2026-06-16 |
| Биндинги | Rust `shturman-sdk` first-class; др. языки через D-Bus | 2026-06-16 |