77d9a5a0ee
Новый домен H (медиа/аудио). Ядро — сквозной арбитр аудио (политика фокуса/ducking поверх PipeWire, role-based), плюс медиаплеер (локальное/BT A2DP/AVRCP/радио/стриминг). Многоагентный adversarial-ревью: 24 находки, 20 подтверждено (default-refute), все применены. Ключевое из ревью: - symphonia НЕ декодирует Opus → отдельный audiopus (libopus, BSD). - AEC: module-echo-cancel (≠ filter-chain) в audio-plane, не в ассистенте — резолв D §147. - media.role (арбитраж) vs media.category (Playback/Capture) разведены. - Кнопки громкости мультируля — uinput→Wayland-input (C/K), не интенты ассистента. - Crash-safe по двум осям (source: жизнь ноды + проактивный cork по NameOwnerChanged/watchdog; sink: пересчёт при возврате output). - intra-role media-фокус (один media-продюсер), гистерезис фокуса (анти-pumping), duck = относит. аттенюатор. - boot аудио-плоскости на Stage 1; отказ-пути плеера (битый файл/обрыв A2DP/ENOSPC/underrun); resume без авто-старта. Кросс-док: D §147 AEC→✅; tech-stack (symphonia/audiopus/module-echo-cancel); hardware §4 (amp-mute-GPIO + FM-тюнер + откр. вопросы); B §4 (amp-mute перед cut); architecture §9 (аудио-арбитр → H); domains/README (строка H). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
87 lines
5.6 KiB
Markdown
87 lines
5.6 KiB
Markdown
# Технический стек
|
||
|
||
> Канонический список технологий Штурмана с обоснованием — источник правды по
|
||
> «на чём пишем». Архитектурные *решения* — в [architecture.md](architecture.md);
|
||
> здесь — конкретные технологии и крейты.
|
||
|
||
Статус: **v1 (на ревью).**
|
||
Связано с: [architecture.md](architecture.md) · [principles.md](principles.md) (#11 отзывчивость, #12 лицензии) · [dev-environment.md](dev-environment.md)
|
||
|
||
---
|
||
|
||
## Язык: Rust-first, один прод-рантайм
|
||
|
||
**Всё, что мы шипим, — на Rust.** Core, SDK, shell и весь прикладной слой,
|
||
включая ассистента.
|
||
|
||
- **Почему:** один тулчейн, минимальный footprint (важно на RK3588 и 16 ГБ-dev),
|
||
единый sandbox-профиль, безопасность памяти, перформанс (принцип #11 — отзывчивость).
|
||
- **ML без Python в проде:** STT/TTS/VAD — через **ONNX Runtime** (крейт `ort`) и
|
||
нативные биндинги (Vosk, llama.cpp); облачные LLM — обычный HTTP. PyTorch в прод
|
||
не тащим.
|
||
- **Python — только в dev:** прототипы, Vehicle Simulator, скрипты, CI-утилиты.
|
||
- **Escape-hatch:** если у конкретной ML-возможности нет вменяемого Rust-пути —
|
||
она шипится **изолированным Python-sidecar процессом** (архитектура позволяет:
|
||
всё и так отдельные процессы на D-Bus + sandbox). Это исключение, не правило.
|
||
- **SDK язык-агностичен для плагинов:** транспорт — D-Bus, поэтому сторонний
|
||
плагин можно писать на любом языке. Биндинги: **Rust — first-class**, другие
|
||
(Python…) — по мере нужды экосистемы.
|
||
|
||
---
|
||
|
||
## Полный стек
|
||
|
||
| Слой / концерн | Выбор | Примечание |
|
||
|----------------|-------|------------|
|
||
| **Языки (прод)** | **Rust** | единственный шипимый рантайм |
|
||
| **Языки (dev)** | Python | прототипы, Vehicle Simulator, скрипты — не в проде |
|
||
| **UI** | **Slint** | декларативный, GPU-ускоренный, Rust-native |
|
||
| **Графика** | **Wayland** — shell = кастомный композитор на `smithay` (Rust) · Panfrost/Mesa | `cage` не годится (single-app) — только ранний bring-up |
|
||
| **Аудио/видео plane** | **PipeWire** + WirePlumber (+ `module-echo-cancel` — AEC) | микрофон, TTS, медиа, BT-аудио; политика ducking — домен H |
|
||
| **IPC (control plane)** | **D-Bus** | низкополосное управление и события |
|
||
| **Песочница** | **bubblewrap** + systemd-hardening | апы/плагины; WASM-тир — позже |
|
||
| **OS base** | Armbian/Debian (RK3588), ядро ближе к mainline | read-only rootfs + overlay |
|
||
| **Init / lifecycle** | **systemd** | ядро; апы/плагины — App-Host |
|
||
| **CAN/OBD (read-only)** | **SocketCAN** (`socketcan`) + **ISO-TP** (`can-isotp`/`CAN_ISOTP`) для нативного OBD | ELM327 (мульти-протокол, прячет ISO-TP) на старте; `python-OBD` — в симуляторе |
|
||
| **Wake-word** | **openWakeWord** | RU-фраза «Штурман»; Porcupine отвергнут (проприетарный, #12) |
|
||
| **VAD** | Silero VAD | через ONNX Runtime |
|
||
| **STT** | Vosk · Silero | офлайн, RU; через биндинги / `ort` |
|
||
| **TTS** | Silero | офлайн, RU |
|
||
| **LLM онлайн** | GigaChat · YandexGPT | HTTP, provider-agnostic, 152-ФЗ |
|
||
| **LLM офлайн** | llama.cpp / Ollama | квантованная мелкая модель |
|
||
| **Карты (v4)** | MapLibre + Valhalla/OSRM | офлайн |
|
||
| **Dev VM** | Lima (vz-backend) | ARM64, нативная виртуализация |
|
||
| **CI** | GitHub Actions, ARM64-Linux | совпадает с таргетом |
|
||
| **Сборка / оркестрация** | Cargo (workspace) + `justfile` | |
|
||
| **Лицензия / гигиена** | **MIT** · `cargo-deny` | без AGPL-заразы (принцип #12) |
|
||
|
||
---
|
||
|
||
## Ключевые крейты (Rust)
|
||
|
||
| Концерн | Крейт |
|
||
|---------|-------|
|
||
| D-Bus | `zbus` |
|
||
| UI | `slint` |
|
||
| Async-рантайм | `tokio` |
|
||
| SocketCAN | `socketcan` |
|
||
| ONNX-инференс (STT/TTS/VAD) | `ort` (ONNX Runtime) |
|
||
| Локальная LLM | биндинги `llama.cpp` |
|
||
| STT (Vosk) | `vosk` |
|
||
| HTTP (облачные LLM) | `reqwest` |
|
||
| Сериализация | `serde` |
|
||
| Логи/трейсинг | `tracing` |
|
||
| Аудио-декод (медиа) | `symphonia` (MP3/AAC/FLAC/Vorbis/WAV/ALAC) + `audiopus` (Opus) |
|
||
|
||
> Список крейтов уточняется при проектировании доменов; здесь — опорные.
|
||
|
||
---
|
||
|
||
## Журнал решений (stack)
|
||
|
||
| Решение | Выбор | Дата |
|
||
|---------|-------|------|
|
||
| Язык прод-рантайма | **Rust-first, один рантайм** (Python — dev-only; sidecar как escape-hatch) | 2026-06-16 |
|
||
| ML в проде | ONNX Runtime (`ort`) + нативные биндинги, без PyTorch | 2026-06-16 |
|
||
| SDK для плагинов | язык-агностичен (D-Bus); Rust — first-class | 2026-06-16 |
|