Files
shturman/docs/specs/v0.2-boot-pipeline.md
kk0t9 9a3b6a8753 docs(v0.2): спека boot-конвейера (Stage 0/1/2 + splash)
Веха v0.2: рефактор плоского shturman.target в фазовый конвейер.
- Stage 0: shturman-splash (Slint software-render → splash.png, до первого кадра);
- Stage 1: критический набор v0.1 → shturman-stage1.target (без изменений тела);
- Stage 2: shturman-stage2-warmup (oneshot-плейсхолдер, после кадра);
- shturman.target → зонтик; общий headless-render хелпер из shell переиспользует splash.
D-Bus-поверхности нет (фазы — systemd). Splash в VM = software-render PNG
(U-Boot framebuffer — HW, шов §10). Тайминг <10c — функц. в VM, вердикт на RK3588.
Приёмка: фазы разделены + splash до кадра + warmup после + регресс v0.1/v0.6 зелёный.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
2026-06-24 19:51:49 +03:00

15 KiB
Raw Permalink Blame History

Спека реализации: v0.2 — Boot-конвейер (Stage 0/1/2 + splash)

Веха v0.2 роадмапа: «splash → таргет фазами»; capabilities A04 (быстрый boot Stage 0/1/2, <10 c), A05 (splash, Stage 0), A15 (systemd-таргеты/оркестрация). Поверх v0.1 (образ + /data + shturman.target). Источники: docs/architecture.md §6 (boot), docs/domains/a-base-system.md §4, docs/roadmap.md §v0. Приёмка роадмапа: «Stage 0/1/2 разделены; splash мгновенно».


1. Цель и первый артефакт

Превратить плоский shturman.target (v0.1: один critical set) в фазовый boot-конвейер из трёх явных стадий, с мгновенным splash до первого кадра Shell и деферредом фоновой нагрузки после интерактива.

Первый артефакт: на boot VM рендерится /run/shturman/splash.png (Stage 0) раньше, чем /run/shturman/frame.png (Stage 1, Shell), а Stage 2 (warmup) стартует после кадра. Все три стадии — отдельные systemd-таргеты, достижимые и упорядоченные; boot-тайминг логируется.

Не цель v0.2: перфоманс-вердикт (<10 c — на RK3588, performance §2; в VM — функционально); красивый визуальный язык splash/Shell (язык — гейт v0.5); реальные Stage-2-сервисы (Vehicle-Data/Assistant/… — v1+).


2. Скоуп и границы

2.1 В скоупе (делаем сейчас)

  • Splash (A05): новый shturman-splash — Slint software-render брендового splash-кадра → PNG (headless, без дисплея/композитора; зеркалит механику shell-кадра v0.1). Стартует максимально рано (Stage 0, минимум зависимостей), до первого кадра Shell.
  • Фазовые таргеты (A15): shturman-stage0/1/2.target + рефактор shturman.target в зонтик. Члены нынешнего critical set переезжают в shturman-stage1.target.
  • Деферред Stage 2: shturman-stage2-warmup.service — oneshot-плейсхолдер (лог+маркер), After первого кадра. Каркас для реальных фоновых сервисов v1+.
  • Boot-тайминг (A04): E2E логирует systemd-analyze + Δ(splash→frame); функционально, не гейт. Жёстко ассертим порядок фаз (splash → frame → warmup) и достижимость трёх таргетов.
  • Общий рендер-хелпер: headless Slint-software-render → PNG выделяется из shturman-shell в переиспользуемый модуль (используют shell + splash). Точное место — план реализации.

2.2 Явно НЕ в скоупе (отложено, с указателем «куда»)

  • U-Boot splash (Stage 0 на железе): framebuffer-картинка загрузчика до ядра — HW (a-base §4, §1). В VM U-Boot'а нет → splash моделируем systemd-сервисом (шов §10).
  • Splash→Shell handoff на реальном дисплее (без чёрного мелькания, передача поверхности композитору) — v0.5 (Shell/композитор smithay). В VM обе стадии — отдельные PNG.
  • Ранний низколатентный путь задней камеры/парктроника в Stage 0 (a-base §1 шов с J/B) — домен J / v1+.
  • A/B boot-select, bootlimit, mark-good, secure/verified boot, security-version rollback (a-base §2, §4) — HW/v4 (нет U-Boot/eFuse в VM).
  • Перф-вердикт <10 cRK3588 (performance §2). В VM — функциональный замер с пометкой «не вердикт».
  • Реальные Stage-2-сервисы (Vehicle-Data, Assistant, Media, Nav, Connectivity) — v1+ (домены E/D/H/I/G).

2.3 Частично в скоупе (каркас сейчас, тело — позже)

  • Stage 2 — только структура (таргет + один warmup-плейсхолдер); приоритеты/oomd-жертвы фона проверяются на реальной нагрузке позже (performance §5).
  • Параллельный быстрый boot (минимальный initramfs, ленивые сервисы, a-base §4) — в VM моделируем systemd-фазами; тюнинг initramfs/ядра — HW.

2.4 Трассируемость ID → статус

ID Веха Статус в v0.2
A04 Быстрый boot Stage 0/1/2 <10 c фазы разделены + тайминг логируется (вердикт — HW)
A05 Splash (Stage 0) splash-сервис рендерит PNG до первого кадра (U-Boot framebuffer — HW)
A15 systemd-таргеты/оркестрация зонтик + 3 фазовых таргета + splash/warmup юниты

3. Красные линии, безопасность, лицензии

  • #1/#2 (нерушимы): boot-оркестрация + read-only splash — нет CAN/actuator/safety-путей. Splash не читает шину (статичный бренд-кадр), Shell-кадр — read-only OBD/состояние (как в v0.1).
  • Лицензии: новых тяжёлых зависимостей нет; splash переиспользует Slint (GPL-3.0 exception в deny.toml, уже заведено) + png (уже в lock). just deny — зелёный.
  • eMMC write-min (A11): splash.png/frame.png/маркеры — в tmpfs /run (volatile), не на flash.

4. Раскладка (новые/изменённые артефакты)

4.1 Бинари/крейты

  • shturman-splash (новый bin, crates/apps/): Slint-компонент splash + --screenshot <path> режим (как shell). Дефолт — интерактив (HW/dev-Mac); --screenshot — headless PNG (VM/E2E). Splash не читает шину (нет зависимости от Power/Settings — стартует до них).
  • Общий рендер-хелпер (выделить из shturman-shell): render_component_to_png(ui, size, path) поверх Slint software-renderer (thread_local MinimalSoftwareWindow + set_platform once + draw_if_needed + png). Используют shturman-shell и shturman-splash. Место (отдельный lib-крейт vs модуль) — план.

4.2 systemd-юниты

Юнит Роль Ключевое
shturman.target зонтик v0 Wants=stage0+stage1+stage2; After=data.mount; WantedBy=multi-user.target
shturman-stage0.target Stage 0 (splash) Wants=shturman-splash.service
shturman-stage1.target Stage 1 (ядро+кадр) Wants=firstboot+machineid+power+settings+shell; Requires/After=data.mount
shturman-stage2.target Stage 2 (фон) Wants=shturman-stage2-warmup.service; After=shturman-stage1.target
shturman-splash.service рендер splash минимум зависимостей; Before=shturman-shell.service; oneshot+RemainAfterExit
shturman-stage2-warmup.service плейсхолдер фона oneshot; After=shturman-shell.service; лог+маркер /run/shturman/stage2.ready

Рефактор: нынешние WantedBy=shturman.target у firstboot/machineid/power/settings/shell → WantedBy=shturman-stage1.target. shturman.target перестаёт прямо тянуть сервисы — тянет три под-таргета.


5. Контракты D-Bus

Новой поверхности нет. Фазы boot — это systemd-оркестрация, не шина. (BootStage-property на Power рассматривалась — YAGNI, отвергнута: фазы наблюдаемы через systemctl/journald; реальный lifecycle-FSM — v0.3, домен B.) Power/Settings-контракты v0.1 — без изменений.


6. Splash — Stage-0 кадр (срез A05)

  • UI (Slint): минимальный брендовый кадр — wordmark «Штурман» по центру на тёмном фоне (нейтральный плейсхолдер; визуальные токены design-system — каркас, полный язык — гейт v0.5). Без статус-бара/тайлов (это Shell, Stage 1). Без чтения шины — статичный (поэтому стартует до Power/Settings → «мгновенно»).
  • Рендер-бэкенды (как Shell §6 v0.1):
    • dev интерактивно: Slint под weston/нативно.
    • VM/E2E: software-renderer → /run/shturman/splash.png (без дисплея); ассерт «splash не пустой».
  • «Мгновенность»: splash-сервис без Requires=data.mount/dbus — стартует на basic.target//run готов, параллельно критическому набору; Before=shturman-shell.service гарантирует splash.png раньше frame.png.
  • Граница: на железе Stage-0-splash — U-Boot framebuffer до systemd (a-base §4); systemd-splash здесь — dev-модель + ранний пост-ядерный splash. Handoff на дисплее (splash→Shell без мелькания) — v0.5.

7. Boot-конвейер фазами (A04/A15)

Модель (architecture §6, a-base §4): Stage 0 мгновенно · Stage 1 ~35 c · Stage 2 фоном.

  • Stage 0: shturman-splash.service → splash.png. Минимум зависимостей, до первого кадра.
  • Stage 1 (нынешний critical set v0.1): data.mount → firstboot → machineid → dbus → power+settings → shell (первый кадр frame.png). Ordering — в самих юнитах (как в v0.1), членство — shturman-stage1.target.
  • Stage 2: shturman-stage2-warmup.service After=shturman-shell.service — стартует после кадра (деферред); пишет маркер /run/shturman/stage2.ready + лог. Каркас для фоновых сервисов v1+.
  • Наблюдаемый порядок фаз: splash.png (mtime) < frame.png (mtime) < stage2.ready (mtime); три таргета достижимы (is-active); warmup After кадра (journald-время старта > времени рендера кадра).
  • Тайминг (A04, функц.): E2E логирует systemd-analyze time + Δ(boot→splash) + Δ(boot→frame); порог <10 c не гейтит (вердикт — RK3588). Дисциплина: монотонные часы для замеров (a-base §4 / common-helper).

8. Dev-харнесс (расширение v0.6)

  • justfile: splash-frame [path] — инспекция splash-кадра (как shell-frame). run/e2e — без новых целей (фазы поднимаются тем же shturman.target).
  • tests/e2e/run.sh: добавить блок «Stage 0/1/2»:
    • три таргета is-active/reached;
    • splash.png существует, валидный PNG, mtime < frame.png;
    • stage2.ready существует, mtime > frame.png (warmup после кадра);
    • лог systemd-analyze + Δ-тайминги (не гейт).
  • lima/shturman.yaml: разложить новые юниты (stage0/1/2.target, splash, warmup) + бинарь splash в run.sh. Splash-зависимостей (пакетов) нет — Slint build-deps уже есть (v0.6).

9. План тестирования и приёмка

9.1 Unit

  • shturman-splash: render → PNG непустой, верный размер, бренд-фон тёмный (зеркало shell screenshot.rs).
  • Общий рендер-хелпер: один тест на оба компонента (или по тесту на крейт).

9.2 E2E (Lima, расширение run.sh)

  • Фазы разделены: shturman-stage0/1/2.target достижимы; splash.png до frame.png; stage2.ready после.
  • Splash: PNG валиден/непустой.
  • Регресс v0.1/v0.6 не сломан: все прежние проверки (mount/firstboot/per-unit/шина/fake-ACC/кадр/бюджеты/ персист+reboot) — зелёные на рефакторенных таргетах.
  • Тайминг: залогирован (функц.).

9.3 Критерии приёмки (acceptance)

  • shturman.target = зонтик; shturman-stage0/1/2.target достижимы и разделены (per-target active).
  • Splash-кадр рендерится (splash.png непустой) раньше первого кадра Shell (frame.png).
  • Stage 2 (warmup) стартует после первого кадра (деферред наблюдаем).
  • Boot-тайминг логируется (Δ splash/frame, systemd-analyze); <10 c — пометка «вердикт на RK3588».
  • Вся приёмка v0.1/v0.6 (§9.4 foundation) — зелёная на новой фазовой раскладке (нет регресса).
  • just ci зелёный; красные линии целы (нет CAN/actuator).

10. Двунаправленные швы (синхронизировать при реализации)

  • a-base §4 / architecture §6: уточнить, что в dev-VM Stage-0-splash — systemd-сервис (software-render PNG), а U-Boot framebuffer-splash — HW; пометить как VM↔HW-границу (как уже сделано для overlay/A-B в v0.6).
  • roadmap §v0.2: по прохождении — отметить веху ; «splash мгновенно» в VM = splash.png до frame.png.
  • CLAUDE.md: обновить статус (v0.2 готово → следующее v0.3/v0.5).
  • v0.1-v0.6 spec §13: добавить шов «shturman.target → зонтик; критический набор → stage1.target».
  • Если всплывёт: handoff splash→Shell и ранний путь камеры — указатели на v0.5 / домен J.

11. Дальше по ритму

v0.2 (эта спека) → writing-plans (план реализации: рендер-хелпер → splash → таргеты-рефактор → warmup → E2E-блок) → TDD → реализация → verify в Lima → коммит. Не писать код до утверждённой спеки. Далее по роадмапу: v0.3 power-safe и v0.5 shell — параллельно поверх v0.2.