Веха 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>
15 KiB
Спека реализации: 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 c — RK3588 (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_localMinimalSoftwareWindow+set_platformonce +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 ~3–5 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.serviceAfter=shturman-shell.service— стартует после кадра (деферред); пишет маркер/run/shturman/stage2.ready+ лог. Каркас для фоновых сервисов v1+. - Наблюдаемый порядок фаз:
splash.png(mtime) <frame.png(mtime) <stage2.ready(mtime); три таргета достижимы (is-active); warmupAfterкадра (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непустой, верный размер, бренд-фон тёмный (зеркало shellscreenshot.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.