Files
shturman/docs/contracts/safety.md

166 lines
17 KiB
Markdown
Raw Permalink 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.
# Контракт: безопасность (граница и driver-distraction)
> Сводный документ о **безопасности**: где проходит граница «не safety-critical»,
> как она держится технически, и как минимизируется единственная реальная
> safety-поверхность системы — **отвлечение водителя**. Правило для всех доменов.
Статус: **v1 (черновик на ревью).**
Связано с: [principles.md](../principles.md) (#1/#2/#4/#5/#6) · [security-privacy.md](security-privacy.md) (угрозы/приватность) · домены [C](../domains/c-shell-ux.md) (владелец distraction), [E](../domains/e-vehicle-data.md) (CAN), [B](../domains/b-power-lifecycle.md) (питание/MCU), [J](../domains/j-cameras-video.md) · [hardware.md](hardware.md)
---
## 1. Назначение и рамки claim
- **Что это:** граница безопасности проекта + политика снижения отвлечения. Превращает
заявленные красные линии (#1/#2) в **защищённый аргумент** и до-определяет distraction
(которое в доменах размечено, но числа/список были открыты — C §7).
- **Что это НЕ:** это **не** functional-safety по ISO 26262 / ASIL, **не** заявка на
сертификацию и **не** обещание, что система безопасна как safety-устройство. Мы
сознательно остаёмся **вне** safety-critical (#1) — именно поэтому «safety **НЕ**
заявляем» проходит сквозняком (напр. камера заднего вида — [hardware §4](hardware.md)).
- **Отличие от security-privacy:** там — **злоумышленник** (конфиденциальность/целостность,
модель угроз §1a). Здесь — **физический вред и отказы** (не-адверсариальные): можем ли
навредить вождению или машине и как этого не делаем. Линзы разные, доки дополняют друг друга.
- **Якоря-принципы:** #1 (не safety-critical), #2 (CAN read-only), #6 (driver-distraction).
## 2. Красные линии — свод и энфорсмент
### 2.1 Чего система НИКОГДА не делает
Не управляет и не вмешивается в узлы, влияющие на динамику/защиту: **двигатель, тормоза,
ABS/ESP, рулевое, подушки, трансмиссия** — и **любой** actuator. Нет управляющих интеграций;
в системе нет actuator-путей (#1).
### 2.2 Read-only CAN — точный смысл
Никаких *state-changing* передач: не шлём управляющих/actuator-команд, не пишем в память
ECU, не делаем сброс DTC (Mode 04) и UDS-write. Допустимы стандартные диагностические
**read-запросы** OBD-II — любой read-сервис без *state-changing* (напр. Mode 01/03/07/09/0A) —
протокол физически шлёт кадр-запрос, иначе DTC не прочитать. Пассивный сниффинг (listen-only) не передаёт ничего. (Полная формулировка — #2.)
### 2.3 Как это держится (структурно — со скоупом по транспорту)
- **Нет средства записи в принципе:** на D-Bus и в SDK **не существует** метода/capability
записи или actuator-вызова — нечего вызвать (security-privacy §3, [ipc](ipc.md)). Гарантия
структурная (отсутствие пути), а не рантайм-проверка.
- **Единственный владелец CAN — Vehicle-Data** (E); нативный CAN в пассивном режиме —
listen-only.
- **Граница гарантии по транспорту:** «ноль TX / писать некуда» — **физический** инвариант
только на **нативном CAN в silent-режиме**. На **ELM327** (живой путь для старых не-CAN авто —
простые Lada/ретрофит, E §3) адаптер сам полноценный CAN-узел, поэтому red-line там держится
**software-дисциплиной** (нет write-кода/метода/cap в Vehicle-Data), а не физикой; при
компрометации Vehicle-Data инъекция кадров теоретически возможна — [hardware §4](hardware.md),
[security-privacy §1a](security-privacy.md). Где нужна жёсткая гарантия — адаптер без TX.
- **Условность «безобидности» опроса:** активный TX — ограниченный, **motion-aware**,
fail-safe (снижаем интенсивность/набор PID в движении; backoff/стоп при аномалиях шины) —
[E §5a](../domains/e-vehicle-data.md).
- **Не оставляем ECU в открытой сессии:** на `ShutdownImminent` (B §4) — немедленное гашение
активного OBD-TX и закрытие ISO-TP-сессий — [E §5b](../domains/e-vehicle-data.md).
- **MCU — fail-safe-авторитет:** не подчиняется слепо power-командам SoC; ни одно SoC-сообщение
не может (а) снять питание **на ходу**, (б) держать вечно и разрядить АКБ (B §5/§7).
- **Ревью-гейт фич:** каждая фича проходит проверку «не управляет ли узлом» (#1) — процессное
правило, не код.
## 3. Hazard-анализ (лёгкий)
Не FMEA уровня сертификации — рабочая карта «опасность → стойка → митигация».
| Опасность | Наша стойка | Митигация | Владелец |
|-----------|-------------|-----------|----------|
| **Отвлечение водителя** | главная safety-поверхность | distraction-политика (§4) | C |
| Помеха живой powertrain-шине от активного опроса | read **условен** | motion-aware TX, prefer listen-only, backoff/стоп | E §5a |
| ECU оставлен в открытой диаг-сессии | не допускаем | гашение TX + закрытие ISO-TP на `ShutdownImminent` | E §5b |
| Камера з/в воспринята как **safety-устройство** | **safety НЕ заявляем** | явный дисклеймер + fail-safe «нет сигнала» | J, hw §4 |
| Введение в заблуждение (stale показан как live; неверная трактовка DTC) | честность данных | staleness-флаги, «скорость/данные неизвестны», `unavailable``stale`; объяснения — справочные, не приговор | E, C, D |
| Повреждение ФС при срыве питания | power-safe by design | RO-rootfs+overlay, graceful shutdown, запись только в `/data` (#5) | A, B |
| Ложный shutdown/reset в движении (мис-трактовка cold-crank/просадки рейла) | не допускаем | held-пороги ниже brown-out (НЕ rate-of-change); приоритет crank; ride-through cold-crank до ~6 В | B §3/§4, hw §3 |
| Питание снято не вовремя (на ходу) / разряд АКБ (не заведётся) | MCU не исполняет слепо power-команды SoC | MCU fail-safe-авторитет (не cut на ходу, не держать вечно); battery-cutoff выше operating-brown-out | B §5/§7 |
| Плагин пытается сделать что-то «опасное» | физически не может (нет D-Bus/SDK write-метода) | песочница + нет CAN-write-cap; UI в слотах shell. *(Физ. инвариант шины — лишь на нативном silent-CAN; на ELM327 = software-дисциплина, hw §4)* | F, sec-priv, E |
## 4. Driver-distraction — политика
Консолидация [C §7](../domains/c-shell-ux.md) + до-определение порогов/списка (были открыты).
**Владелец — Shell (C)**; правило едино для всех апов и плагинов.
### 4.1 Модель и уровни
- Состояние публикуется как `DistractionModeChanged(level)` (Shell, [ipc §4](ipc.md)).
- **Уровни (v1):** `parked` (полный UI) и `driving` (ограничения §4.4). Поле `level`
**расширяемо** до промежуточного `low_speed` позже (по UX-тестам) — 🟡.
### 4.2 Источник скорости, арбитраж, fail-safe
- **Источник:** GPS (`ru.shturman.Location`, K) **с v1**; уточняется OBD-скоростью (E) в v2.
C потребляет **занулённую/quality-флагнутую** `Speed` (не сырой Doppler-шум на стоянке).
- **Арбитраж GPS↔OBD (v2):** правило авторитетности и поведение при расхождении/устаревании.
- **Fail-safe:** при неизвестной/устаревшей скорости (тоннель/нет фикса/stale OBD) — гейт
**консервативно в `driving`** (к безопасности) + видимая пометка «скорость неизвестна».
- **Гистерезис/дебаунс:** раздельные пороги on/off — джиттер не мигает режимами.
### 4.3 Пороги *(🟡 — дефолты под подтверждение, финал на реальном HMI)*
- Вход в `driving` — выше **~5 км/ч**; выход в `parked` — ниже **~3 км/ч** (гистерезис).
- Неизвестная/устаревшая скорость → `driving`.
### 4.4 Что блокируется / разрешено в движении *(🟡 — список под подтверждение)*
- **Блокируется:** ввод текста с клавиатуры; видео на экране водителя; длинные списки и
мелкие цели; многошаговые настройки; ручной ввод назначения; всё, что требует долгого взгляда.
- **Разрешено:** голос/PTT (первичный путь); крупные одно-тап тайлы; now-playing-транспорт;
turn-by-turn-ведение; приём/сброс входящего звонка; back/home; навигация по UI **рулём** без касания (C §9).
### 4.5 Glance-бюджет
Для всего разрешённого в движении — design-цель **≤ 2 c одиночный взгляд / ≤ 12 c задача**
(эвристика NHTSA Visual-Manual как **референс дизайна**, не как claim соответствия).
### 4.6 Энфорсмент (центральный — плагины не обходят)
- Shell — **Wayland-хост** UI всех апов/плагинов и маршрутизатор ввода (C §9); ограничения
накладывает **централизованно** по `level`, чужой UI живёт в слотах и не может их обойти.
- SDK **(◻️ задел)** — предполагается отдавать плагину текущий `level` для адаптации UI (не для
обхода); точка доставки (подписка на `DistractionModeChanged` через прокси под `ui_*`, либо
отдельный read-only level-канал) **ещё не специфицирована** в plugin-sdk — см. §8.
## 5. Регуляторный контекст *(без claim соответствия)*
- **EMC / UNECE R10 (e-mark):** ретрофит-головблок — электроника в авто. Соответствие/
установка — ответственность **установщика/пользователя**; проект проектируется «не мешать»,
но **гомологацию не заявляет**. Тепловой/механический конверт — [hardware §1a](hardware.md).
- **Distraction-дизайн** опирается на **NHTSA Visual-Manual Guidelines** и **Euro NCAP** как
**референсы** (§4.5), не как сертификацию.
- **Ответственность ретрофита** на конкретное авто — пользователя; проект даёт **документацию**
(см. «документированный ретрофит», [roadmap](../roadmap.md) v4), не сертификат.
- **152-ФЗ / приватность** — отдельная плоскость: [security-privacy §7](security-privacy.md).
## 6. Поведение при отказах (свод fail-safe)
Единая стойка #4 (**деградируй, не падай**), сведённая по доменам:
| Отказ | Поведение | Домен |
|-------|-----------|-------|
| Неизвестна/устарела скорость | distraction → консервативно `driving` | C §7 |
| Падение CAN-транспорта (bus-off/линк) | `Online=false`; сигналы → `unavailable` (не `stale`); авто-recovery; без краха | E §5b |
| Нет видеосигнала камеры | frame-watchdog → состояние «нет сигнала» (fail-safe), без зависшего кадра | J |
| Срыв навигации (no-route/битые тайлы/GPS-loss) | отказ-пути, без краха | I §12 |
| Срыв питания | power-safe в обе стороны: anti-corruption (RO-rootfs/overlay, graceful) И anti-ложное-срабатывание (held-триггеры не rate-of-change, crank-приоритет, ride-through) | B, A (#5) |
| Недоступна зависимость апа | «нет данных», ап не крэшит | все (#4) |
## 7. Зависимости / связи
- **Принципы:** #1/#2 (граница), #4 (graceful degradation), #5 (power-safe), #6 (distraction).
- **C** — владелец distraction (HMI, уровни, энфорсмент). **E** — энфорсмент read-only CAN +
motion-aware опрос. **B** — power-safe, MCU-авторитет, `ShutdownImminent`. **J/I** — fail-safe.
- **security-privacy** — комплементарна (угрозы/приватность ≠ hazard/вред). **hardware** — §1a
(конверт), §4 (камера-дисклеймер, CAN-периферия).
- **SDK** (◻️ задел) — доставка distraction-`level` плагину пока не специфицирована (§8); **ipc** — сигнал `DistractionModeChanged`.
## 8. Открытые вопросы
- 🟡 **Точные пороги (км/ч) и полный список блокируемого** — финализировать на реальном HMI (v1→v2).
- 🟡 **Промежуточный уровень `low_speed`** (graded vs бинарный) — по UX-тестам.
- ◻️ **Глубина регуляторного анализа** под конкретные рынки (РФ/ЕС) — к релизу/стору.
- ◻️ **Формат «документированного ретрофита»** (roadmap v4) — гайд по установке + разграничение ответственности.
- ◻️ **Доставка distraction-`level` плагину** — точка в plugin-sdk не специфицирована (подписка на `DistractionModeChanged` под `ui_*` vs отдельный read-only level-канал; отразить в security-privacy §3).
## Журнал решений (safety)
| Решение | Выбор | Дата |
|---------|-------|------|
| Рамка claim | non-safety-critical; **НЕ** ISO 26262; «граница + distraction-митигация» | 2026-06-23 |
| Энфорсмент read-only | **структурный** (нет write-метода/cap), а не рантайм-чек; физ.-инвариант «ноль TX» — лишь на нативном silent-CAN, на ELM327 (старые авто) = software-дисциплина (hw §4); VehicleData — единственный владелец CAN | 2026-06-23 |
| Distraction-уровни | бинарный `parked`/`driving`, поле `level` расширяемо до `low_speed` | 2026-06-23 |
| Пороги distraction | ON >~5 км/ч, OFF <~3 км/ч (гистерезис); unknown/stale → `driving` (числа — 🟡) | 2026-06-23 |
| Регуляторика | R10 / NHTSA / Euro NCAP как **референсы**, не claim; гомологация = установщик | 2026-06-23 |