Files
shturman/docs/architecture.md
T
kk0t9 3d13bb5827 docs: tech-stack + контракты ipc/data-model (+ ревью-фиксы)
- 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>
2026-06-20 20:01:36 +03:00

220 lines
16 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.
# Архитектура системы
> Как устроен Штурман: слои, процессы, шина IPC, изоляция — и **карта связей**
> между компонентами. Это верхнеуровневый документ: домены (Tier 2) и контракты
> (Tier 1) ссылаются сюда. Все 6 базовых решений приняты — см. «Журнал решений».
Статус: **v1 (на ревью).**
Связано с: [principles.md](principles.md) · [contracts/](contracts/README.md) · [domains/](domains/README.md) · [dev-environment.md](dev-environment.md)
---
## 1. Главный принцип: тонкое ядро + всё на SDK
Доверенное **ядро минимально** — только инфраструктура, безопасность и данные.
Всё прикладное (shell, ассистент, медиа, навигация, телефон) — отдельные процессы
на **том же SDK**, что и сторонние плагины (first-party получают расширенные
capabilities). Это делает открытый API не лозунгом, а основой: им пользуемся мы
сами.
Ключевое следствие для безопасности: к «опасным» ресурсам (CAN, питание)
прикасается ровно один привилегированный сервис каждый. **Read-only CAN — не
правило, а физический факт:** к шине машины прикасается только Vehicle-Data, и в
нём нет write-кода.
---
## 2. Слои
```
HARDWARE RK3588 · экран · CAN/OBD · GPS · mic-массив · power-path · камеры
LINUX BASE read-only rootfs + overlay · Wayland · systemd · hardware watchdog
TRUSTED CORE Power/Lifecycle · Vehicle-Data (CAN read-only) · Settings/State
(привилегии) Security/Perm-Broker · Plugin/App-Host · Connectivity
│ ──────────────── control plane: D-Bus ────────────────
SDK единый API: D-Bus + Rust SDK (биндинги др. языков — для плагинов) + манифест
FIRST-PARTY Shell/UX-host · Assistant · Media · Nav · Phone ← расш. права
APPS (на SDK)
PLUGINS (3rd) плагин · плагин · … ← узкие права
```
Высокополосные данные (аудио/видео/графика) идут **не** через D-Bus, а через
data-plane — см. §4.
---
## 3. Компоненты и процессная модель
Каждый компонент — **отдельный процесс**. Падение одного не роняет остальные
(изоляция). Раздача привилегий — через Perm-Broker (§7).
### Доверенное ядро (привилегированное, минимум)
| Компонент | Роль | Почему в ядре |
|-----------|------|---------------|
| **Power/Lifecycle** | ACC-детект, graceful shutdown, sleep/wake, watchdog | владеет power-GPIO; критично для защиты от corruption |
| **Vehicle-Data** | читает CAN/OBD, публикует сигналы (VSS-like) на шину | единственный владелец железа CAN → гарантирует read-only |
| **Settings/State** | центральная конфигурация и состояние, пишет в `/data` | общий источник правды; единственный писатель в `/data`-конфиг |
| **Security/Perm-Broker** | выдаёт/режет capabilities по манифесту | привратник всех привилегий |
| **Plugin/App-Host** | запуск, супервизия, песочница апов и плагинов | посредник доступа к шине; владеет sandbox-механизмом |
| **Connectivity** | обёртка ModemManager/NetworkManager, статус сети | управляет сетевым железом |
### First-party апы (отдельные процессы на SDK, расширенные права)
| Ап | Кратко | Особое |
|----|--------|--------|
| **Shell/UX-host** | лаунчер, экраны, тема, driver-distraction | ещё и Wayland-**хост** UI остальных (§8) |
| **Assistant** | wake→STT→LLM→TTS, контекст машины, память о водителе (`.md`) | Rust (ONNX Runtime + биндинги); провайдер-агностик LLM |
| **Media** | аудио, BT A2DP/AVRCP, радио, стриминг | владеет аудио-политикой (с PipeWire) |
| **Nav** | офлайн-карты, роутинг | богатые поверхности (карта) |
| **Phone** | BT HFP, контакты, звонки | аудио через PipeWire |
### Сторонние плагины
Тот же SDK, **узкие** capabilities, запускаются и песочатся App-Host'ом, доступ к
привилегиям — только через Perm-Broker. API расширения — [contracts/plugin-sdk.md](contracts/plugin-sdk.md);
рантайм/дистрибуция/sandbox — домен F (`domains/f-plugin-host.md`).
---
## 4. IPC: control plane vs data plane
Принцип: **D-Bus — для управления и событий, не для медиа-потоков.**
| Plane | Транспорт | Что несёт |
|-------|-----------|-----------|
| **Control** | **D-Bus** | методы, сигналы, свойства: команды, состояние, события, сигналы машины (VSS), интенты ассистента, настройки, выдача capabilities |
| **Audio/video** | **PipeWire** (+ WirePlumber) | микрофон ассистента, TTS-выход, медиа, BT-аудио, маршрутизация на усилитель |
| **Graphics** | **Wayland** | поверхности апов, сводимые shell-композитором (Panfrost/Mesa) |
| **Camera** | **PipeWire / V4L2 (DMABUF)** | видео-источники; самые латентные (задняя камера) — почти прямой путь |
Нюанс: Vehicle-Data перемалывает сырой высокочастотный CAN **внутри себя** и
публикует на шину уже digested-сигналы с потолком частоты (~10–20 Гц) — шина
остаётся лёгкой. Детали — [contracts/ipc.md](contracts/ipc.md).
Камеры спроектированы как **динамический набор 0..N источников** (задняя,
dashcam-фронтальная, surround), расширяемый плагинами — см. задел в
[domains/README.md](domains/README.md).
---
## 5. Карта связей (кто с кем говорит)
| От | К | Plane | Зачем |
|----|---|-------|-------|
| любой ап/плагин | Perm-Broker | D-Bus | проверка capabilities на каждую привилегию |
| App-Host | апы/плагины | процессы | запуск, супервизия, песочница, рестарт |
| Assistant | Vehicle-Data | D-Bus | live-контекст машины в промпт |
| Assistant | Connectivity → сеть | D-Bus/сеть | онлайн RU-LLM (GigaChat/YandexGPT) |
| Assistant, Media, Phone | PipeWire | audio | микрофон, TTS, музыка, BT-аудио |
| Nav, Shell | Vehicle-Data | D-Bus | скорость/положение для карты и виджетов |
| Nav, Media, камеры-виды | Wayland | graphics | богатые поверхности в слот shell |
| Shell | все апы | D-Bus + Wayland | хостинг UI: декларативные вклады + поверхности |
| все апы | Settings/State | D-Bus | чтение/запись настроек |
| Vehicle-Data | CAN/OBD | драйвер | **только чтение** |
| Power/Lifecycle | все | D-Bus сигналы | ACC-on/off, shutdown, sleep |
```mermaid
graph TD
Apps["Апы и плагины (SDK, песочница)"]
Broker["Perm-Broker"]
AppHost["App-Host"]
Vehicle["Vehicle-Data (read-only)"]
Power["Power / Lifecycle"]
Settings["Settings / State"]
Conn["Connectivity"]
PW["PipeWire (audio/video)"]
WL["Wayland (в Shell)"]
CAN[("CAN / OBD")]
Net(("Сеть / RU-LLM"))
Apps -->|"capabilities"| Broker
AppHost -.->|"запуск/супервизия"| Apps
Apps -->|"read сигналы"| Vehicle
Apps -->|"конфиг"| Settings
Apps -->|"аудио"| PW
Apps -->|"поверхности"| WL
Apps -->|"онлайн"| Conn
Conn --> Net
Vehicle ==>|"READ-ONLY"| CAN
Power -.->|"lifecycle"| AppHost
```
---
## 6. Жизненный цикл и загрузка
**Кто кого супервизит:**
- **systemd** — доверенные системные сервисы ядра (+ App-Host и Shell). Рестарт при падении, watchdog.
- **App-Host** — динамические апы и сторонние плагины (жизненный цикл по манифесту, песочница, своя политика рестарта).
**Быстрый boot фазами (цель — < 10 c до интерактива):**
- **Stage 0 (мгновенно):** загрузчик → splash. Низколатентный путь задней камеры/парктроника, если включена задняя.
- **Stage 1 (~35 c):** ядро-минимум (шина + Power + Settings + **Perm-Broker + App-Host**) → **Shell с первым кадром** (home-тайлы кликабельны). Broker/App-Host нужны раньше Shell: Shell — тоже ап и поднимается/цепляется к шине через них.
- **Stage 2 (фоном):** Vehicle-Data, Assistant, Media, Nav прогреваются после того, как UI интерактивен.
**Завершение:** ACC-off → Power/Lifecycle инициирует graceful shutdown (systemd-таргет): апам сигнал «сохранись», Settings флашится в `/data`, размонтирование, снятие питания через supercap/MCU-копилот. Вместе с read-only rootfs это защита от corruption.
**Устойчивость:** hardware watchdog + systemd-watchdog; зависший сервис ядра перезапускается, зависшая система — ребутается watchdog'ом.
---
## 7. Изоляция и разрешения
Песочница — **defense-in-depth** поверх архитектурных гарантий (даже сбежавший
плагин не запишет в CAN — write-пути нет).
- **Механизм:** апы/плагины — в **bubblewrap**-песочнице (namespaces, seccomp, минимальный FS); ядро — **systemd-hardening**. WASM — опциональный тир для лёгких логических плагинов позже.
- **Модель разрешений:** манифест декларирует capabilities (`vehicle_read:[…]`, `assistant_intents`, `ui_tiles`, `network`, `storage`…). **Perm-Broker — единственная дверь** к привилегиям (модель «порталов» как у Flatpak): плагин не трогает ресурсы напрямую, а просит брокера.
- **Грант:** first-party — авто; сторонние — показываем запрашиваемые capabilities при установке, пользователь подтверждает.
Детали модели разрешений и приватности — [contracts/security-privacy.md](contracts/security-privacy.md).
---
## 8. Хостинг UI в shell (гибрид / слоты)
Shell — Wayland-хост; апы/плагины — отдельные песочные процессы. Их UI попадает на
экран двумя путями:
- **Декларативные вклады** (данные/описание, **не код**) для частого/лёгкого:
home-тайлы, настройки, простые экраны плагинов, карточки ассистента. Рендерит
**сам shell** своими Slint-компонентами → единый стиль, безопасность (чужой код
в процесс shell не пускаем).
- **Wayland-поверхности** для богатых апов: нав-карта, медиа, камеры, GPU-тяжёлое.
Ап рисует у себя и отдаёт shell готовую поверхность.
**Модель слотов:** shell задаёт слоты (грид home, полноэкранная зона, оверлей,
статус-бар); ап вкладывает либо декларативный элемент, либо поверхность. Так
консистентность UX (наш дифференциатор) сочетается с мощью и ложится на песочницу.
---
## 9. Что вынесено в другие документы (связи)
- **Интерфейсы шины** (имена сервисов, методы, схемы) → [contracts/ipc.md](contracts/ipc.md).
- **Модель сигналов машины** (VSS-таксономия) → [contracts/data-model.md](contracts/data-model.md).
- **API расширения** (манифест, capability-модель, точки расширения) → [contracts/plugin-sdk.md](contracts/plugin-sdk.md).
- **Разрешения и приватность** (детали брокера, 152-ФЗ) → [contracts/security-privacy.md](contracts/security-privacy.md).
- **Железо и HAL/board-support** (питание, периферия, портирование) → [contracts/hardware.md](contracts/hardware.md).
- **Камеры как 0..N источников, dashcam/surround; парктроники** → [domains/README.md](domains/README.md) (заделы) → домены J/K.
- **Аудио-арбитраж (ducking/приоритеты)** → домены Media/Assistant (политика поверх PipeWire).
- **Ранний путь задней камеры (Stage 0)** → роадмап (объём работ) + домен J.
---
## Журнал решений (architecture)
| # | Решение | Выбор | Дата |
|---|---------|-------|------|
| 1 | Граница ядра | **Тонкое ядро + всё на SDK** | 2026-06-16 |
| 2 | Состав компонентов | Мин. доверенное ядро (6 сервисов) + first-party апы на SDK + плагины; Connectivity в ядре | 2026-06-16 |
| 3 | Control vs data plane | D-Bus (control) + PipeWire (audio/video) + Wayland (graphics) + V4L2/DMABUF (камеры) | 2026-06-16 |
| 4 | Lifecycle/boot | systemd (ядро) ↔ App-Host (апы/плагины); фазовый boot; graceful shutdown по ACC | 2026-06-16 |
| 5 | Песочница | bubblewrap + Perm-Broker (порталы), systemd-hardening ядра; WASM — тир позже | 2026-06-16 |
| 6 | Хостинг UI | Гибрид/слоты: декларативные вклады (shell рендерит) + Wayland-поверхности | 2026-06-16 |