- tech-stack: Rust-first (один прод-рантайм; Python — dev-only), полный стек, крейты - architecture: ассистент Python→Rust для консистентности; boot-порядок (Broker+App-Host до Shell); потолок частоты сигналов ~10–20 Гц - contracts/ipc: реестр D-Bus (сервисы ядра/апов, соглашения, портал-брокеринг) + открытые вопросы из self-review - contracts/data-model: VSS-aligned каталог сигналов, OBD-PID маппинг, DTC-модель; добавлен MIL-статус (PID 0x01) для killer-фичи, состояние машины, расход-estimate Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 KiB
Контракт: IPC (D-Bus)
Backbone связей: реестр D-Bus-сервисов, их интерфейсов и соглашений. Формализует карту связей из architecture.md §5 в конкретные контракты. К нему цепляются data-model, plugin-sdk и все домены.
Статус: v1 (на ревью). Связано с: architecture.md (§4–5) · data-model.md · plugin-sdk.md · security-privacy.md
Область: control plane (D-Bus). Аудио/видео/графика — НЕ здесь (PipeWire/Wayland, см. architecture §4).
1. Шина и топология
- Одна системная шина устройства (Штурман — single-purpose appliance, системная шина и есть его шина) со строгой D-Bus-политикой.
- Ядро-сервисы общаются на ней напрямую.
- Песочные апы/плагины напрямую шину НЕ видят — каждому выдаётся
фильтрующий D-Bus-прокси (паттерн
xdg-dbus-proxy), настроенный App-Host'ом из capabilities манифеста (см. §5). Это реализация портал-модели из решения №5.
🟡 Мелкий выбор на подтверждение: системная шина устройства (рекомендую, проще) vs выделенный экземпляр
dbus-daemonтолько для Штурмана (чище изоляция от хост-сервисов, но лишний компонент). Прокси-фильтрация даёт изоляцию в обоих случаях.
2. Соглашения
| Аспект | Правило |
|---|---|
| Well-known имя | ru.shturman.<Service> (напр. ru.shturman.VehicleData) |
| Путь объекта | /ru/shturman/<Service> |
| Интерфейс | ru.shturman.<Service>N — N = мажорная версия (напр. …VehicleData1) |
| Версионирование | аддитивные изменения внутри версии; ломающие → новый интерфейс …2 |
| Ошибки | ru.shturman.Error.<Name>: PermissionDenied, NotAvailable, ReadOnly, InvalidArgument, Unsupported |
| Действие | метод |
| Изменение состояния | сигнал |
| Текущее состояние | property (+ стандартный PropertiesChanged) |
| Асинхронность | всё async (zbus + tokio); долгие операции не блокируют |
| Стандартные интерфейсы | org.freedesktop.DBus.{Properties,Introspectable,Peer} |
Полные сигнатуры (XML-интроспекция) фиксируются при реализации; здесь — реестр и ключевые члены.
3. Реестр сервисов — ядро (привилегированные)
ru.shturman.VehicleData — данные машины (READ-ONLY)
- Методы (только чтение):
ListSignals() → [name],GetSignal(name) → (value, unit, ts),Subscribe(names, max_hz)/Unsubscribe(names),GetDtcs() → [(code, status, desc)]. - Сигналы:
SignalChanged(name, value, ts)— только подписчикам и только по подписанным именам (не широковещательно «всё всем»),DtcsChanged([...]). - Политика частоты: на шину сигналы идут с потолком (~10–20 Гц) — этого хватает для читаемых датчиков и держит control-plane лёгким. Сырой высокочастотный CAN остаётся внутри VehicleData. Цифровому приборному щитку, если нужна более плавная стрелка, — клиентская интерполяция или выделенный быстрый канал (не D-Bus); см. «Открытые вопросы».
- Properties (горячие, текущее значение):
Speed,Rpm,CoolantTemp,BatteryVoltage,Online. - ⛔ Методов записи нет — ни
SetSignal, ни actuator-команд, ни clear-DTC. Архитектурная гарантия read-only (принцип #2). Типы — data-model.md.
ru.shturman.Power — питание и жизненный цикл
- Методы:
GetPowerState() → state,RequestSleep()(внутр.). - Сигналы:
AccChanged(on),ShutdownImminent(seconds),Sleep(),Wake(). - Properties:
IgnitionState,Uptime,PowerSource.
ru.shturman.Settings — конфигурация и состояние
- Методы:
Get(key) → value,Set(key, value),List(prefix) → [key],Reset(key). - Сигналы:
Changed(key, value). - Namespace на каждый ап изолирован (брокер не даёт читать чужой).
ru.shturman.PermBroker — выдача разрешений (привратник)
- Методы:
CheckCapability(app, cap) → bool,RequestRuntimeGrant(cap) → granted(рантайм-промпт пользователю, напр. «ап X хочет сеть»). - Сигналы:
GrantChanged(app, cap, granted). - Основная фильтрация — на уровне прокси (§5); этот API для рантайм-согласий.
ru.shturman.AppHost — запуск/супервизия апов и плагинов
- Методы:
ListApps() → [(id, status)],StartApp(id),StopApp(id),GetStatus(id) → status. - Сигналы:
AppStarted(id),AppStopped(id),AppCrashed(id, reason). - (Установка/дистрибуция плагинов — домен F, не здесь.)
ru.shturman.Connectivity — сеть (обёртка NM/MM)
- Методы:
GetStatus() → status,ListNetworks() → [...],Connect(id),Disconnect(). - Сигналы:
ConnectivityChanged(online),NetworkChanged(...). - Properties:
Online,Type(wifi/modem),SignalStrength.
4. Реестр сервисов — апы (на SDK)
ru.shturman.Assistant
- Методы:
SendText(query) → reply,StartListening(),StopListening(),RegisterIntents(handler_path, [pattern])(для плагинов с capabilityassistant_intents). - Сигналы:
StateChanged(idle|listening|thinking|speaking),TranscriptUpdated(text),ReplyUpdated(text). - Контекст машины подмешивается ассистентом из
VehicleData(см. architecture §5).
ru.shturman.Shell — UX-host (слот-модель, решение №6)
- Методы:
RegisterTile(decl),RegisterScreen(decl | surface_handle),RequestForeground(slot),ShowOverlay(decl). - Сигналы:
ForegroundChanged(app),NavigatedTo(screen),DistractionModeChanged(level). - Декларативный вклад = данные (рендерит shell); богатый = Wayland-поверхность.
ru.shturman.Media / …Nav / …Phone
- Свои интерфейсы (play/pause/route; navigateTo/cancel; dial/answer/hangup). Детали — в спеках доменов H/I/G; здесь — только факт регистрации на шине.
5. Брокеринг доступа песочных апов (портал-паттерн)
- Манифест плагина декларирует capabilities (
vehicle_read:[speed],network,assistant_intents…). - App-Host поднимает плагин в bubblewrap и даёт ему фильтрующий D-Bus-прокси, сконфигурированный под эти capabilities.
- Прокси пропускает только разрешённые сервисы/интерфейсы/методы/сигналы. Пример:
vehicle_read:[speed]→ виденVehicleData.GetSignal("speed")иSignalChangedпо speed; не виденPower, чужие апы, любые write-методы. - Рантайм-согласия (сеть «сейчас») — через
PermBroker.RequestRuntimeGrant.
Итог: плагин физически не может дотянуться до того, чего нет в манифесте. Детали модели — security-privacy.md.
6. Точки расширения через IPC
- Интенты ассистента: плагин реализует
ru.shturman.IntentHandler1.HandleIntent(intent_id, slots) → resultи регистрируется черезAssistant.RegisterIntents. Латентно-критичные интенты (громче, домой) ассистент обрабатывает локально без LLM. - Вклад в UI: плагин зовёт
Shell.RegisterTile/RegisterScreen(декларативно или поверхностью).
Полные контракты SDK (манифест, биндинги, точки расширения) — plugin-sdk.md.
Открытые вопросы (найдено на self-review → роутинг в нужные доки)
Не теряем; решается в указанных документах.
- Гейтинг data-plane, не только D-Bus. Портал-прокси (§5) фильтрует D-Bus, но доступ к PipeWire (аудио) и Wayland (графика) тоже надо гейтить capability'ями (через bubblewrap-сокеты). → security-privacy.md + plugin-sdk.md.
- Экспорт объектов из песочницы. Чтобы Assistant/Shell звали
IntentHandler/UI плагина, прокси должен разрешать плагину OWN/экспорт своих объектов под ограниченным префиксом. → security-privacy.md. - Приватное хранилище апа. Capability
storageдолжна давать апу приватную writable-директорию в/data(монтирует bubblewrap). → security-privacy.md. - Коллизия интентов. Два плагина регистрируют пересекающиеся фразы — нужна политика разрешения (приоритет / namespace / выбор пользователя). → plugin-sdk.md + домен D.
- Целостность манифеста. Для сторонней дистрибуции — подпись/верификация манифеста (защита от подмены capabilities). → домен F + security-privacy.md.
- Быстрый канал для приборки. Если цифровой щиток требует плавнее, чем потолок шины — спроектировать выделенный канал. → architecture.md §4 + домен E.
Журнал решений (ipc)
| Решение | Выбор | Дата |
|---|---|---|
| Топология шины | системная шина устройства + фильтрующий прокси на ап (🟡 на подтверждение) | 2026-06-16 |
| Изоляция доступа апов | портал-паттерн: per-app dbus-proxy из манифеста | 2026-06-16 |
| Соглашения имён/версий | ru.shturman.*, версия в имени интерфейса |
2026-06-16 |