From fb27d8d2fec3c8c1a16d38db562b798838f98235 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 20 Jun 2026 20:28:52 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=B7=D0=B0=D0=B2=D0=B5=D1=80=D1=88?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20Tier=201=20(=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=BA=D1=82=D1=8B)=20+=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E-?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20red-line=20CAN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- docs/contracts/hardware.md | 113 +++++++++++++++++++++++ docs/contracts/ipc.md | 25 +++-- docs/contracts/plugin-sdk.md | 134 +++++++++++++++++++++++++++ docs/contracts/security-privacy.md | 142 +++++++++++++++++++++++++++++ docs/principles.md | 14 ++- 5 files changed, 411 insertions(+), 17 deletions(-) create mode 100644 docs/contracts/hardware.md create mode 100644 docs/contracts/plugin-sdk.md create mode 100644 docs/contracts/security-privacy.md diff --git a/docs/contracts/hardware.md b/docs/contracts/hardware.md new file mode 100644 index 0000000..537e837 --- /dev/null +++ b/docs/contracts/hardware.md @@ -0,0 +1,113 @@ +# Контракт: железо и board-support + +> Целевой таргет, топология питания, периферия — и **HAL/BSP** для портирования под +> другое железо/авто (то самое «API для автопроизводителей/автолюбителей» из vision). + +Статус: **v1 (на ревью).** +Связано с: [architecture.md](../architecture.md) · [dev-environment.md](../dev-environment.md) · [data-model.md](data-model.md) (§7 DBC) · [security-privacy.md](security-privacy.md) (якорь доверия) · домены A/B/E/J/K + +--- + +## 1. Целевой SoC + +**RK3588 / RK3588S класс, 8–16 ГБ RAM.** Почему: приличная mainline-Linux-поддержка, +Panfrost GPU, мощности хватает на плавный UI и **локальную мелкую LLM**; это же класс +реальных автоголов. + +## 2. Хранилище + +- **eMMC** — rootfs, **read-only**. +- **Раздел `/data`** (SD/eMMC) — read-write, **журналируемый**. +- Прямое следствие power-safe (принцип #5): запись только в `/data`. + +## 3. Питание (критично) — power-safe by design + +- **Управляемый power-path:** питание устройства коммутируется по зажиганию. +- **Детект ACC/зажигания** — через GPIO (12 В → level-shift). +- **Автомобильная защита входа:** широкодиапазонный DC-DC + защита от **load-dump, + транзиентов и переплюсовки** (бортовые 12 В грязные — скачки до 40+ В). +- **Hold-up энергия** для graceful shutdown при резком пропадании 12 В. +- **Secure boot** (verified boot RK3588) — **якорь доверия first-party** (из + [security-privacy.md](security-privacy.md): first-party = вшит в подписанный образ). + Подпись OTA — домен A. + +🟡 **Выбор hold-up механизма:** +- **(рек.) MCU-копилот** — маленький always-on МК: мониторит зажигание, сигналит SoC + «выключайся» по ACC-off, держит watchdog, управляет power-sequencing и sleep/wake. + + конденсатор/supercap на пару секунд для флаша и размонтирования. +- **(проще)** только supercap — буфер энергии без логики (детект ACC — на SoC-GPIO). + +Рекомендую MCU-копилот: он же закрывает watchdog и пробуждение. (Прошивка МК — домен B.) + +## 4. Периферия + +| Узел | Старт | Прод / позже | +|------|-------|--------------| +| **Дисплей** | HDMI + USB-тачскрин | MIPI-DSI / LVDS панель | +| **CAN/OBD** | ELM327 (USB/BT) | нативный CAN-трансивер → **SocketCAN** | +| **GPS** | USB/UART, NMEA | — | +| **Связь** | USB-модем (ModemManager) / Wi-Fi | — | +| **Аудио** | I2S codec + усилитель | — | +| **Микрофон** | USB **mic-массив** (wake-word, шумоподавление) | — | +| **Камеры** | задняя (CVBS capture-чип + драйвер, фаза 2) | dashcam / surround (задел, домен J) | +| **Мультируль** | кнопки руля: чтение с CAN **или** ADC (резистивная лесенка) | — | + +**Два пути чтения и точный смысл «read-only»:** +- **Пассивный сниффинг (listen-only):** CAN-контроллер в silent-режиме — физически + не передаёт и не шлёт ACK; читаем broadcast-кадры машины (нужен DBC). Ноль TX. +- **OBD-II поллинг:** чтобы прочитать DTC и PID, протокол **требует отправить + кадр-запрос** (Mode 01/03/07/09). Это НЕ listen-only — мы передаём, но **только + стандартные диагностические read-запросы**. + +**Red-line (принцип #2):** запрещены **управляющие/actuator-команды, запись в ECU, +сброс DTC (Mode 04), UDS-write** — любые *state-changing* передачи. Безобидные +read-запросы OBD-II разрешены (без них не прочитать ошибки). Чистый listen-only — +только для пассивного пути. + +## 5. HAL / board-support (портирование) + +**HAL абстрагирует железо-специфичное**, чтобы платформа переносилась на другие +платы/авто: + +- Power/зажигание (карта GPIO + протокол MCU-копилота). +- CAN (контроллер + listen-only). +- Дисплей (тип панели + тач), аудио (codec/усилитель/маршрутизация). +- GPS-источник, захват камер, карта ввода мультируля. + +**BSP (board-support package)** = device tree (overlay) + конфиг HAL + **per-vehicle +DBC/маппинг сигналов** (см. [data-model.md](data-model.md) §7). + +**Порт = новый BSP.** Это и есть «API под конкретное железо/авто» из vision: +автопроизводитель/энтузиаст поставляет BSP, ядро не трогается. + +## 6. Первый таргет vs портируемость + +- **Один reference-таргет доводим end-to-end** (vision: не «любое железо из коробки»). + Портируемость — силами других через BSP/HAL. +- 🟡 **Выбор конкретной платы — отложен** (решение по доступности/цене). Кандидаты: + Radxa Rock 5B / 5B+, Orange Pi 5 / 5 Plus, Khadas Edge2 — критерии: mainline-поддержка, + доступность (в т.ч. в РФ), цена, IO (CAN-способные пины). + +--- + +## Открытые вопросы (→ роутинг) + +- 🟡 **Выбор reference-платы** — procurement-решение (доступность/цена в РФ). → отдельно. +- ◻️ **Прошивка MCU-копилота** (детект ACC, sequencing, watchdog, протокол к SoC). → домен B. +- ◻️ **Ранний путь задней камеры** (Stage 0 boot) — аппаратная сторона. → домен J + B. +- 🟡 **Подписанные OTA** (вторая половина цепочки доверия; secure boot закрыт здесь). → домен A. +- ◻️ **Тепловой режим:** RK3588 в горячем салоне/закрытом корпусе — радиатор, throttling. → домен A. +- ◻️ **Износ eMMC/SD** при записи (логи/трипы/телеметрия) — минимизация записи, особенно на SD. → домен A/B. + +--- + +## Журнал решений (hardware) + +| Решение | Выбор | Дата | +|---------|-------|------| +| SoC | RK3588/RK3588S класс, 8–16 ГБ | 2026-06-16 | +| Хранилище | eMMC RO rootfs + журналируемый `/data` | 2026-06-16 | +| Hold-up питания | MCU-копилот + cap (🟡); supercap-only — проще | 2026-06-16 | +| CAN | пассивный listen-only + OBD read-запросы (без state-changing TX); ELM327 на старте | 2026-06-16 | +| Доверие | secure boot анкорит first-party; подпись OTA — домен A | 2026-06-16 | +| Портируемость | HAL + BSP; один reference-таргет first-party | 2026-06-16 | diff --git a/docs/contracts/ipc.md b/docs/contracts/ipc.md index 7dc0cb2..16cb951 100644 --- a/docs/contracts/ipc.md +++ b/docs/contracts/ipc.md @@ -120,20 +120,17 @@ Не теряем; решается в указанных документах. -- **Гейтинг data-plane, не только D-Bus.** Портал-прокси (§5) фильтрует D-Bus, но - доступ к **PipeWire (аудио)** и **Wayland (графика)** тоже надо гейтить - capability'ями (через bubblewrap-сокеты). → [security-privacy.md](security-privacy.md) + [plugin-sdk.md](plugin-sdk.md). -- **Экспорт объектов из песочницы.** Чтобы Assistant/Shell звали `IntentHandler`/UI - плагина, прокси должен разрешать плагину **OWN/экспорт** своих объектов под - ограниченным префиксом. → [security-privacy.md](security-privacy.md). -- **Приватное хранилище апа.** Capability `storage` должна давать апу приватную - writable-директорию в `/data` (монтирует bubblewrap). → [security-privacy.md](security-privacy.md). -- **Коллизия интентов.** Два плагина регистрируют пересекающиеся фразы — нужна - политика разрешения (приоритет / namespace / выбор пользователя). → [plugin-sdk.md](plugin-sdk.md) + домен D. -- **Целостность манифеста.** Для сторонней дистрибуции — подпись/верификация - манифеста (защита от подмены capabilities). → домен F + [security-privacy.md](security-privacy.md). -- **Быстрый канал для приборки.** Если цифровой щиток требует плавнее, чем потолок - шины — спроектировать выделенный канал. → [architecture.md](../architecture.md) §4 + домен E. +- ✅ **Гейтинг data-plane, не только D-Bus.** → решено в [security-privacy.md](security-privacy.md) §4 + (PipeWire/Wayland гейтятся capability'ями через bubblewrap-сокеты). API-часть — в plugin-sdk. +- ✅ **Экспорт объектов из песочницы.** → решено в [security-privacy.md](security-privacy.md) §4 + (плагин OWN под префиксом `ru.shturman.plugin..*`). +- ✅ **Приватное хранилище апа.** → решено в [security-privacy.md](security-privacy.md) §4 + (`storage` → mount `/data/apps//`). +- ✅ **Коллизия интентов.** → решено в [plugin-sdk.md](plugin-sdk.md) §5 (слоистая + политика разрешения); тонкости LLM-роутинга — домен D. +- 🟡 **Целостность манифеста.** Модель доверия — [security-privacy.md](security-privacy.md) §6; + подпись/стор — задел домена F. +- ◻️ **Быстрый канал для приборки.** → [architecture.md](../architecture.md) §4 + домен E (**открыто**). --- diff --git a/docs/contracts/plugin-sdk.md b/docs/contracts/plugin-sdk.md new file mode 100644 index 0000000..1a46f1d --- /dev/null +++ b/docs/contracts/plugin-sdk.md @@ -0,0 +1,134 @@ +# Контракт: Plugin / Extension SDK + +> **Главный API платформы.** Как расширять Штурман, не трогая ядро. Синтез +> [ipc.md](ipc.md) + [data-model.md](data-model.md) + [security-privacy.md](security-privacy.md). +> Приоритет №1: даже наши first-party апы строятся на этом SDK. + +Статус: **v1 (на ревью).** +Связано с: [architecture.md](../architecture.md) (#1 тонкое ядро) · [ipc.md](ipc.md) · [data-model.md](data-model.md) · [security-privacy.md](security-privacy.md) · домен F (рантайм/дистрибуция) + +--- + +## 1. Принцип + +- Плагин = **отдельный процесс**, говорит по D-Bus через **фильтрующий прокси**, в + **bubblewrap-песочнице**. Видит только заявленное в манифесте. +- Тот же SDK — у first-party апов (с расширенными capabilities). Если для фичи + «нужно лезть в ядро» — это баг API, чиним API (принцип #9). + +## 2. Манифест (полная схема) + +Формат — **YAML**. Единая модель: всё, что нужно плагину, — это **capabilities** +(объединили `capabilities`+`permissions` из исходной спеки в один список). + +```yaml +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](security-privacy.md) §3–4 + (не дублируем). Манифест **декларирует** → Perm-Broker **enforce**. +- `vehicle_read` принимает **только сигналы из каталога** [data-model.md](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_read` → `VehicleData.Subscribe(names, max_hz)` / `GetSignal` (ipc §3). + Только чтение, только заявленные сигналы. + +### 4.4 Настройки +- Свой namespace в `Settings` + приватное хранилище (`storage` → `/data/apps//`). + +## 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 | diff --git a/docs/contracts/security-privacy.md b/docs/contracts/security-privacy.md new file mode 100644 index 0000000..845b3d6 --- /dev/null +++ b/docs/contracts/security-privacy.md @@ -0,0 +1,142 @@ +# Контракт: безопасность и приватность + +> Модель изоляции, разрешений и приватности (152-ФЗ). Здесь **решаются открытые +> вопросы**, направленные из [ipc.md](ipc.md): гейтинг data-plane, экспорт объектов +> из песочницы, приватное хранилище, целостность манифеста. + +Статус: **v1 (на ревью).** +Связано с: [architecture.md](../architecture.md) (§5,§7) · [ipc.md](ipc.md) · [plugin-sdk.md](plugin-sdk.md) · [principles.md](../principles.md) (#1,#2,#7) · домен F + +--- + +## 1. Слои защиты (defense-in-depth) + +| Слой | Что гарантирует | +|------|-----------------| +| **Архитектурный** | write-пути к CAN нет в системе → красные линии держатся даже при полном компромиссе (принципы #1, #2) | +| **Песочница** | bubblewrap (апы/плагины) + systemd-hardening (ядро) — ограничивает syscalls/FS/сеть | +| **Брокер/портал** | доступ к ресурсам только через capability-гейтинг (D-Bus-прокси + сокеты) | +| **Грант пользователя** | сторонние capabilities подтверждает пользователь | + +> Ключевой инвариант: **сбежавший из песочницы плагин всё равно не запишет в CAN** — +> писать некуда. Песочница защищает данные и приватность, не красные линии. + +## 2. Песочница + +- **Апы/плагины — bubblewrap:** mount/pid/net/user namespaces, **seccomp**-фильтр + syscalls, минимальный FS-вид, `no-new-privileges`. Плагин видит только: свой код, + разрешённые сокеты, своё приватное хранилище. +- **Ядро — systemd-hardening:** `ProtectSystem`, `RestrictAddressFamilies`, + `SystemCallFilter`, и т.п. на доверенных юнитах. +- WASM-тир для лёгких логических плагинов — задел (см. architecture §7). + +## 3. Модель capabilities + +Манифест декларирует, что апу/плагину нужно. Каждая capability открывает ровно один +ресурс и гейтится на своём канале: + +| capability | что открывает | канал / механизм гейтинга | +|------------|---------------|----------------------------| +| `vehicle_read:[signals]` | чтение указанных сигналов | D-Bus-прокси: `VehicleData`, фильтр по списку | +| `assistant_intents:[…]` | регистрация интентов | D-Bus: `Assistant.RegisterIntents` + OWN `IntentHandler` | +| `ui_tiles` / `ui_screens` | вклад в UI | D-Bus: `Shell.Register*` (+ Wayland-сокет, если поверхность) | +| `audio_out` | воспроизведение | **PipeWire-сокет** (пропускается в песочницу) | +| `audio_in` (микрофон) | запись с микрофона — **высокочувствительно** | PipeWire-сокет + **runtime-грант + видимый индикатор**; сторонним — ограниченно | +| `network` | доступ в сеть (опц. **host-allowlist** в манифесте) | net-namespace + **runtime-грант** | +| `location` | GPS/положение | D-Bus (location) + **runtime-грант** | +| `gpu` (render) | GPU-ускорение (UI/ML) | bubblewrap пропускает `/dev/dri` | +| `storage` | приватное хранилище | bubblewrap **mount** `/data/apps//` | + +> Чего нет в манифесте — физически недоступно: нет сокета, нет имени на шине, нет mount. + +## 4. Гейтинг по каналам (закрывает routed-вопросы из ipc) + +- **D-Bus** — фильтрующий per-app прокси из манифеста (детали — [ipc.md](ipc.md) §5). +- **PipeWire (аудио)** — bubblewrap пропускает pipewire-сокет только при `audio_*`. + → *закрывает «гейтинг data-plane».* +- **Wayland (графика/UI)** — wayland-сокет пропускается только при `ui_*` с поверхностью. + → *закрывает «гейтинг data-plane».* +- **Экспорт объектов из песочницы** — прокси разрешает плагину **OWN** имена строго + под префиксом `ru.shturman.plugin..*`, чтобы Assistant/Shell могли звать его + `IntentHandler`/UI-объекты. → *закрывает «экспорт объектов».* +- **Приватное хранилище** — `storage` монтирует в песочницу только `/data/apps//`; + чужие данные и системные пути не видны. → *закрывает «приватное хранилище».* + +## 5. Жизненный цикл разрешения + +``` +declare (манифест) → install: пользователь видит запрошенные capabilities и +подтверждает → enforce (прокси + sandbox конфигурятся под манифест) → +runtime-грант для чувствительных (network / audio_in / location) — отдельный +промпт в момент использования +``` + +- **First-party** апы — авто-грант. *Что делает их first-party:* они **часть + подписанного read-only base-образа** (вшиты, не устанавливаются пользователем) — + это и есть якорь доверия, а не флажок в манифесте. +- **Сторонние** — устанавливаются в `/data`, **всегда** в песочнице и под + capability-гейтингом; install-time ревью + runtime-промпты на чувствительное. + +## 6. Доверие и дистрибуция (целостность манифеста) + +🟡 **Выбор на подтверждение:** +- **(рек., сейчас)** install-time approve + песочница: пользователь видит + capabilities и соглашается; защита — sandbox. Просто, достаточно для раннего этапа. +- **(задел)** **подпись манифеста** + keyring издателей — против подмены capabilities + при сторонней дистрибуции. → домен F (экосистема/«магазин»). +- **(опц.)** курируемый стор с ревью. + +Рекомендую: сейчас — approve+sandbox; подпись/стор — когда включаем community-маховик. +→ *закрывает «целостность манифеста» (с явным заделом).* + +## 7. Приватность / 152-ФЗ + +**Принцип:** local-first; наружу — минимум и осознанно. + +| Данные | Где обрабатываются | Уходит в облако? | +|--------|--------------------|------------------| +| Голос (аудио) | локально (STT/TTS) | **никогда** | +| Текст запроса | локально → онлайн-LLM при необходимости | только текст, только в онлайн-режиме | +| Данные машины (OBD/DTC) | локально | **в промпт онлайн-LLM** — только когда пользователь спросил и активен онлайн-режим; в офлайне не уходит вовсе | +| Память о водителе (`.md`) | локально | нет (без явного согласия) | +| Телеметрия | локально | **opt-in**, по умолчанию выключена | + +- Онлайн-LLM — только **RU-провайдеры** (GigaChat/YandexGPT), данные в РФ (152-ФЗ). +- **Прозрачность:** в онлайн-режиме контекст машины уходит провайдеру в составе + промпта — это явно сообщается; офлайн-фолбэк держит всё на устройстве. + +**Микрофон:** wake-word слушает постоянно, но **локально**; в обработку идёт только +после слова-активатора; включённый микрофон показывается **видимым индикатором**. + +**Охват гарантий и рисковые комбинации.** Таблица выше описывает поведение +first-party (ассистент). Сторонний плагин с `network` **+** чувствительными данными +(`vehicle_read`/`location`) теоретически может слить их куда угодно — это **рисковая +комбинация**: требует заметного предупреждения при установке, по возможности — +host-allowlist сети. Системная приватность держится на **capability-контроле**, а не +только на политике ассистента. + +--- + +## Открытые вопросы (найдено на self-review → роутинг) + +- ◻️ **Отзыв и управление грантами.** Пользователь должен видеть и **отзывать** + выданные capabilities по каждому апу. → Settings/Shell + домен C. +- 🟡 **Цепочка доверия к base-образу.** Secure boot (якорь) — в [hardware.md](hardware.md) §3; + осталась вторая половина — **подписанные OTA**. → домен A. +- ✅ **Host-scoping сети.** → решено в [plugin-sdk.md](plugin-sdk.md) §3 (host-allowlist + в манифесте; голый `network: true` — повышенный риск). +- ◻️ **Локальный audit-log** чувствительного доступа (микрофон, сеть, гранты) — + локально, не телеметрия. → этот контракт + Settings. + +--- + +## Журнал решений (security-privacy) + +| Решение | Выбор | Дата | +|---------|-------|------| +| Изоляция | bubblewrap (апы) + systemd-hardening (ядро); WASM — задел | 2026-06-16 | +| Гейтинг ресурсов | per-capability на своём канале (D-Bus / PipeWire / Wayland / FS) | 2026-06-16 | +| Экспорт из песочницы | OWN под префиксом `ru.shturman.plugin..*` | 2026-06-16 | +| Хранилище | `storage` → mount `/data/apps//` | 2026-06-16 | +| Доверие к манифесту | install-approve + sandbox сейчас; подпись/стор — задел (🟡) | 2026-06-16 | +| Приватность | local-first; в облако только текст; OBD в промпт лишь онлайн + по запросу; телеметрия opt-in | 2026-06-16 | diff --git a/docs/principles.md b/docs/principles.md index 5d0a18e..b8a16cb 100644 --- a/docs/principles.md +++ b/docs/principles.md @@ -16,9 +16,17 @@ - **Почему:** безопасность людей, юридическая ответственность, сертификационная яма функциональной безопасности. - **Как держим:** нет интеграций с управляющими ECU; в системе нет actuator-путей; каждая фича проходит ревью «не управляет ли узлом». -### 2. CAN только на чтение -- **Почему:** тот же риск + юридическая чистота. Это то, что делает проект подъёмным для малой команды. -- **Как держим:** в Vehicle-Data нет write-кода; он единственный владелец CAN; на шине D-Bus нет метода записи в CAN; в SDK нет capability вида `can_write` — её просто не существует. +### 2. CAN — только чтение (без управляющих команд) +- **Почему:** безопасность + юридическая чистота. Это то, что делает проект подъёмным для малой команды. +- **Точный смысл «чтения»:** мы НИКОГДА не шлём управляющих/actuator-команд, не пишем + в память ECU, не делаем сброс DTC (Mode 04) и UDS-write — никаких *state-changing* + передач. При этом стандартные диагностические **read-запросы** OBD-II (Mode 01/03/07/09) + допустимы и необходимы: протокол физически отправляет кадр-запрос, иначе DTC не + прочитать. Пассивный сниффинг (listen-only) не передаёт ничего. +- **Как держим:** в Vehicle-Data нет кода управляющих/write-команд; он единственный + владелец CAN; на D-Bus и в SDK нет метода/capability записи или actuator-вызова — + их не существует; нативный CAN в пассивном режиме — listen-only. См. + [contracts/hardware.md](contracts/hardware.md) §4. ---