dwarves L1 — service/systemd via skidbladnir (reuse, never hand-roll)
dwarves-server is a skidbladnir-managed systemd service. dwarves declares a ServiceSpec and drives a Lifecycle — it does not hand-roll unit files or systemctl calls (Law #1: one crate owns service/systemd; nornir & holger already use it). Behind the server feature, so nornir's path-dep + lean embedders pay nothing.
The seam (crates/dwarves/src/service.rs)
service_spec(exec, port, scope) -> skidbladnir::service::ServiceSpec— a Fat (state-holding) forge server,HealthProbe::Tcp(port), restart-on-failure,DWARVES_SERVER_ADDRin env;scopepicks root system vs per-user.lifecycle(exec, port, scope) -> Lifecycle— the verbs (install/enable/start/stop/ status/health), all delegated to skidbladnir's D-Bus controller (no subprocess).unit_text(...)— the pure systemd render (no root/bus) → unit-tested.
Wired into dwarves-server
dwarves-server --unit prints the rendered unit; --install/--start/--stop/--status drive the Lifecycle for the current binary (--system = root scope, else per-user). These act and exit before the gRPC server boots.
Coverage
service::tests::{renders_a_dwarves_server_systemd_unit, unit_name_is_dwarves_server_service}(pure).- dwarves-gui robot scenario
robot_pipeline_funnel_panes_matrixdrives the Pipeline | Funnel panes over the remote seam (state_json/update_json) in code and emits anornir-testmatrixcell (dwarves-gui/pipeline_funnel_panes_drivable). Visiblewatch-on-DISPLAY:0 (egui_kittest) is the flagged follow-up.
Follow-ups
- Full
dwarves service {install,start,…}CLI subcommand (verbs exist via the module). - Extract the shared
nornir-serviceserver+client scaffold into edda (the tonic server is still a mirror-not-invent stopgap); then dwarves consumes it.