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

8.6 KiB
Raw Blame History

Контракт: Plugin / Extension SDK

Главный API платформы. Как расширять Штурман, не трогая ядро. Синтез ipc.md + data-model.md + security-privacy.md. Приоритет №1: даже наши first-party апы строятся на этом SDK.

Статус: v1 (на ревью). Связано с: architecture.md (#1 тонкое ядро) · ipc.md · data-model.md · security-privacy.md · домен F (рантайм/дистрибуция)


1. Принцип

  • Плагин = отдельный процесс, говорит по D-Bus через фильтрующий прокси, в bubblewrap-песочнице. Видит только заявленное в манифесте.
  • Тот же SDK — у first-party апов (с расширенными capabilities). Если для фичи «нужно лезть в ядро» — это баг API, чиним API (принцип #9).

2. Манифест (полная схема)

Формат — YAML. Единая модель: всё, что нужно плагину, — это capabilities (объединили capabilities+permissions из исходной спеки в один список).

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 §3–4 (не дублируем). Манифест декларирует → Perm-Broker enforce.
  • vehicle_read принимает только сигналы из каталога 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_readVehicleData.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