docs: завершить Tier 1 (контракты) + ревью-фикс red-line CAN

- 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) <noreply@anthropic.com>
This commit is contained in:
2026-06-20 20:28:52 +03:00
parent 3d13bb5827
commit fb27d8d2fe
5 changed files with 411 additions and 17 deletions
+113
View File
@@ -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 класс, 816 ГБ 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 класс, 816 ГБ | 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 |
+11 -14
View File
@@ -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.<id>.*`).
-**Приватное хранилище апа.** → решено в [security-privacy.md](security-privacy.md) §4
(`storage` → mount `/data/apps/<id>/`).
- **Коллизия интентов.** → решено в [plugin-sdk.md](plugin-sdk.md) §5 (слоистая
политика разрешения); тонкости LLM-роутинга — домен D.
- 🟡 **Целостность манифеста.** Модель доверия — [security-privacy.md](security-privacy.md) §6;
подпись/стор — задел домена F.
- ◻️ **Быстрый канал для приборки.** → [architecture.md](../architecture.md) §4 + домен E (**открыто**).
---
+134
View File
@@ -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) §34
(не дублируем). Манифест **декларирует** → 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/<id>/`).
## 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 |
+142
View File
@@ -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/<id>/` |
> Чего нет в манифесте — физически недоступно: нет сокета, нет имени на шине, нет 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.<id>.*`, чтобы Assistant/Shell могли звать его
`IntentHandler`/UI-объекты. → *закрывает «экспорт объектов».*
- **Приватное хранилище** — `storage` монтирует в песочницу только `/data/apps/<id>/`;
чужие данные и системные пути не видны. → *закрывает «приватное хранилище».*
## 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.<id>.*` | 2026-06-16 |
| Хранилище | `storage` → mount `/data/apps/<id>/` | 2026-06-16 |
| Доверие к манифесту | install-approve + sandbox сейчас; подпись/стор — задел (🟡) | 2026-06-16 |
| Приватность | local-first; в облако только текст; OBD в промпт лишь онлайн + по запросу; телеметрия opt-in | 2026-06-16 |
+11 -3
View File
@@ -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.
---