Files
shturman/docs/architecture.md
T
kk0t9 fb4e585152 docs(domain G): v2 — связь/телефон (Connectivity+Phone), после adversarial-ревью (15 находок) + кросс-док
Новый домен G: Connectivity-core (WiFi/LTE/tethering + BT-адаптер/паринг) +
Phone-ап (HFP-звонки/контакты). Многоагентный adversarial-ревью: 24 находки,
15 подтверждено (default-refute; tech-измерение — 0, техника устояла), все применены.

Ключевое из ревью:
- BT-шов резолвнут двунаправленно: владелец BlueZ — Connectivity-core (G §3 ↔ H §6/§15 ).
- Граница голоса: только HFP спаренного телефона; встроенный модем — data-only (VoLTE/eCall вне скоупа).
- SIM PIN/PUK-флоу (sim_locked/no_sim) + captive-portal детект (portal/limited, не ложный online) — модем v1.
- Connectivity поднимается на Stage 2 (синхр. с architecture §6).
- Мультипаринг: ровно один active-телефон для HFP/PBAP (Dial/CallStateChanged однозначны).
- SCO-loss mid-call → CallState=audio_lost + снятие роли phone_call → H раскорчивает медиа (не залипает).
- Входящий-оверлей не перекрывает реверс-вид (z-order overlay-слота → C); tethering-петля AP+tether запрещена.
- PBAP-синк фоновый; отказ-пути паринга/no_service симметрично J/H.

Кросс-док: H §6/§15 (BlueZ ) + якоря D §147/§148→§10; architecture §3 (Connectivity+BT)
/§6 (Stage 2); ipc §3 (Type+tether, State enum, CallState=audio_lost); security-privacy §7
(контакты/журнал/SMS local-first); hardware §4 (Bluetooth); tech-stack (NM/MM/BlueZ);
C §11 (z-order overlay).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 19:08:52 +03:00

225 lines
17 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-кода. *(Точнее: «физический» инвариант — для нативного CAN в silent-режиме;
на старте через ELM327 read-only держится software-дисциплиной, т.к. ELM327 — полноценный
CAN-узел. См. [contracts/hardware.md](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 **+ BlueZ-адаптер/паринг**, статус сети | управляет сетевым и BT-железом (общий радиоресурс) |
### 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 | 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 |
```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, **Connectivity** прогреваются после того, как 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](contracts/security-privacy.md) §5.
- **Грант:** first-party — авто; сторонние — показываем запрашиваемые capabilities при установке, пользователь подтверждает.
Детали модели разрешений и приватности — [contracts/security-privacy.md](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](domains/c-shell-ux.md) §4.
**Модель слотов:** 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/приоритеты)** → домен **H** (Media — design-owner политики) + D (Assistant); enforcement в WirePlumber. См. [domains/h-media-audio.md](domains/h-media-audio.md) §3.
- **Ранний путь задней камеры (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 |