C-shell v2: - GPS-скорость для distraction — домен K (ru.shturman.Location), не E (E это OBD, v2); E — уточнение OBD-скорости в v2 + быстрый статус машины - механизм поверхности: Wayland slot-протокол ru.shturman.shell_slot + slot-token, не «handle по D-Bus» - fail-safe distraction при потере/устаревании скорости (консервативный дефолт, гистерезис, арбитраж GPS/OBD) - контракт статус-бара: network «unknown» до Connectivity; часы — до синка времени Кросс-док: - architecture §1 (ELM327-оговорка к «физическому» read-only), §5 (положение/GPS из Location/K, не Vehicle-Data), §7 (Perm-Broker = грантодатель, статика — прокси+sandbox), §8 (surface через Wayland slot-протокол) - ipc Shell.RegisterScreen → slot_token - dev-environment: cage → smithay/weston в журнале и списке пакетов Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
16 KiB
Архитектура системы
Как устроен Штурман: слои, процессы, шина IPC, изоляция — и карта связей между компонентами. Это верхнеуровневый документ: домены (Tier 2) и контракты (Tier 1) ссылаются сюда. Все 6 базовых решений приняты — см. «Журнал решений».
Статус: v1 (на ревью). Связано с: principles.md · contracts/ · domains/ · dev-environment.md
1. Главный принцип: тонкое ядро + всё на SDK
Доверенное ядро минимально — только инфраструктура, безопасность и данные. Всё прикладное (shell, ассистент, медиа, навигация, телефон) — отдельные процессы на том же SDK, что и сторонние плагины (first-party получают расширенные capabilities). Это делает открытый API не лозунгом, а основой: им пользуемся мы сами.
Ключевое следствие для безопасности: к «опасным» ресурсам (CAN, питание) прикасается ровно один привилегированный сервис каждый. Read-only CAN — не правило, а физический факт: к шине машины прикасается только Vehicle-Data, и в нём нет write-кода. (Точнее: «физический» инвариант — для нативного CAN в silent-режиме; на старте через ELM327 read-only держится software-дисциплиной, т.к. ELM327 — полноценный CAN-узел. См. contracts/hardware.md §4.)
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;
рантайм/дистрибуция/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.
Камеры спроектированы как динамический набор 0..N источников (задняя, dashcam-фронтальная, surround), расширяемый плагинами — см. задел в 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 | Location (домен K) | D-Bus | GPS-положение/скорость (карта, distraction v1) |
| Shell | Vehicle-Data | D-Bus | OBD-скорость (v2) + быстрый статус машины |
| 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 |
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 (~3–5 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 — единый грантодатель/портал (политика и рантайм-согласия), но статическую фильтрацию делает per-app D-Bus-прокси + bubblewrap (настраивает App-Host из манифеста) — не «брокер в каждом вызове». Детали — contracts/security-privacy.md §5. - Грант: first-party — авто; сторонние — показываем запрашиваемые capabilities при установке, пользователь подтверждает.
Детали модели разрешений и приватности — contracts/security-privacy.md.
8. Хостинг UI в shell (гибрид / слоты)
Shell — Wayland-хост; апы/плагины — отдельные песочные процессы. Их UI попадает на экран двумя путями:
- Декларативные вклады (данные/описание, не код) для частого/лёгкого: home-тайлы, настройки, простые экраны плагинов, карточки ассистента. Рендерит сам shell своими Slint-компонентами → единый стиль, безопасность (чужой код в процесс shell не пускаем).
- Wayland-поверхности для богатых апов: нав-карта, медиа, камеры, GPU-тяжёлое.
Ап рисует у себя и подключается клиентом к Wayland-сокету Shell; привязка surface→слот —
через приватный slot-протокол (
ru.shturman.shell_slot) + slot-token отShell.RegisterScreen(не «handle по D-Bus»). Детали — domains/c-shell-ux.md §4.
Модель слотов: shell задаёт слоты (грид home, полноэкранная зона, оверлей, статус-бар); ап вкладывает либо декларативный элемент, либо поверхность. Так консистентность UX (наш дифференциатор) сочетается с мощью и ложится на песочницу.
9. Что вынесено в другие документы (связи)
- Интерфейсы шины (имена сервисов, методы, схемы) → contracts/ipc.md.
- Модель сигналов машины (VSS-таксономия) → contracts/data-model.md.
- API расширения (манифест, capability-модель, точки расширения) → contracts/plugin-sdk.md.
- Разрешения и приватность (детали брокера, 152-ФЗ) → contracts/security-privacy.md.
- Железо и HAL/board-support (питание, периферия, портирование) → contracts/hardware.md.
- Камеры как 0..N источников, dashcam/surround; парктроники → 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 |