Полный чистый `just vm-reset && just e2e` (PRE→reboot→POST) впервые прогнан после
добавления power-safe-блока — вскрыл два латентных шва харнесса (FSM/сервис-код цел):
1. start-limit-hit: блок намеренно рестартит shturman-power N+ раз за <10s →
systemd StartLimitBurst (5/10s) → power в failed, имя ru.shturman.Power теряется,
блок abort не доезжает. Фикс: reset-failed перед намеренными рестартами (как при
реальном reboot); ждать active power, не только settings.
2. machine-id залипал на нижнем rootfs-значении: цикл/power-cut делает
`umount /etc/machine-id`, но `systemctl start shturman.target` НЕ пере-bind-ит —
shturman-machineid это oneshot RemainAfterExit (уже active) → ExecStart не
перезапускается. POST-чек стабильности machine-id (§9.3.4) падал после reboot.
Фикс: `systemctl restart shturman-machineid` после remount (форсит пере-bind).
E2E OK ✅ с нуля (vm-reset → PRE → reboot → POST); регресс v0.1/v0.2 цел.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
- machineid bind (/data/state/machine-id→/etc/machine-id) держит /data busy →
снимаем bind перед umount; remount через systemctl start (не mount /data — нет fstab).
- restart power/settings после install (повторный just run: иначе крутится старый
бинарь, start=no-op) + restart power в начале power-safe-блока (чистый FSM Running).
- §3 oneshot-чек: firstboot/machineid валидны в active|inactive (отработал ИЛИ корректно
пропущен Condition'ом на повторном boot); реальный сбой = failed.
- stage2.target тянет savetime.timer (WantedBy без enable не срабатывал).
Блок power-safe зелёный: N=3 цикла /data цел, abort→ShutdownAborted, power-cut fsck-clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
Прогон cargo fmt (гейт lint): многострочное форматирование match-веток FSM,
PowerMock/PowerService-литералов, integration-вызовов. Без изменений логики.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
P6.4: just splash-frame; lima yaml ставит stage0/1/2.target + tmpfiles
(splash/warmup ловит glob *.service). run.sh: install splash-бинаря, раскладка
новых юнитов+tmpfiles, блок «Stage 0/1/2 разделены» (3 таргета reached, splash.png
до frame.png, stage2.ready после, systemd-analyze лог). Убран restart shell
(ломал бы порядок warmup-после-кадра — фазовый старт рендерит всё по порядку).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
P6.3: shturman.target → зонтик (Wants stage0/1/2). Новые: stage0/1/2.target,
shturman-splash.service (Before=shell, минимум зависимостей → «мгновенно»),
shturman-stage2-warmup.service (After=shell, маркер /run/shturman/stage2.ready),
tmpfiles-shturman.conf (/run/shturman). Члены critical set → stage1.target
(WantedBy+PartOf); у shell убран RuntimeDirectory (каталог теперь от tmpfiles).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
P6.2: статичный брендовый splash-кадр (wordmark «Штурман» на тёмном),
render_splash через shturman-render; bin с --screenshot. Без чтения шины
(стартует до Power/Settings → «мгновенно»). Визуальные токены — каркас (язык v0.5).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
P6.1 общий рендер-хелпер shturman-render (рефактор из shell) →
P6.2 shturman-splash (Stage 0) → P6.3 фазовые systemd-таргеты + splash/warmup +
зонтик → P6.4 justfile/lima/E2E-блок Stage 0/1/2 → P6.5 verify в Lima + acceptance.
TDD-шаги с полным кодом, без плейсхолдеров. Self-review: покрытие спеки полное.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
- БЛОКЕР: shturman.target Wants= сервисов (enable target не каскадит) — иначе start поднимал только /data.
- machine-id bind: создаём /etc/machine-id, если нет, перед mount --bind.
- deny.toml: заметка о хрупкости slint-exceptions к апгрейдам.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
- deny_unknown_fields: опечатка в ключе capability (граница доверия F §3) не проглатывается.
- VEHICLE_SIGNALS → shturman_sdk::vehicle (single source; валидатор берёт оттуда).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
- SettingValue{Str,Int,Bool} в сторе: провод-variant теперь честно поддержан (не string-only).
- битый settings.json → WARN в лог (не молча) + откат к дефолтам.
- отказ записи /data → Error::Failed (не InvalidArgument).
- reset ключа без дефолта → no-op + InvalidArgument (без ложного Changed("")).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
Правила: id не ru.shturman.*, shturman_api поддержан, len(tiles)<=ui_tiles, vehicle_read из каталога.
Фикстуры good + bad-{id-reserved,api,tiles-quota,vehicle-read}; 6 тестов.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
theme::resolve_night (TDD); slint! AppWindow (статус-бар часы+сеть + грид тайлов + тема день/ночь);
main — best-effort чтение Settings/Power через sdk (без шины — дефолты, #4); часы UTC (локаль tz — позже).
deny.toml: GPL-3.0 exceptions для slint-крейтов (вариант A, финал к v4) + BSL-1.0 (error-code).
Slint тянет zbus5/thiserror2 — дубли версий (bans=warn). Реальный screenshot кадра — План 5 E2E.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
Settings round-trip + Changed; Power state + fake-ACC AccChanged — на живой D-Bus.
just test-integration (dbus-run-session). #[ignore] → just ci (unit) не требует шины.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
PowerService (Power1, стаб running) + PowerMock (dev.PowerMock1, разделяет State через Arc<Mutex>).
dev-mocks — default-фича; прод (--no-default-features) mock не регистрирует.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
Store (load_or_seed/get/set/reset/list, durable-write) + SettingsService #[interface] + bin.
v0: строковые значения (variant на проводе), сам сеет дефолты.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
Сервисам нужен bus-bootstrap, а от sdk они не зависят (граница architecture §3).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
connect (system/session по SHTURMAN_BUS); PowerClient/SettingsClient — типизированные обёртки proxy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
just ci зелёный: fmt + clippy(-D warnings) + 6 unit-тестов common + cargo-deny.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
- workspace (resolver 2; members растут по планам)
- rust-toolchain 1.96.0; tracing-journald cfg-gated на Linux (кросс-платформенность)
- shturman-common: модули-скелеты paths/atomic/clock/log
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Спека после adversarial-ревью (17 находок) + позиция Slint (вариант A, финал отложен к v4).
План 1 — воркспейс + governance + shturman-common (TDD).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>