- host_role_mapping now holds at most one row per host_id.
SqliteInventoryRepository::save_role_mapping wraps a DELETE of any
prior rows for the host and the INSERT of the new one in a single
transaction, self-healing pre-existing duplicate rows along the way.
- Before re-prompting for disk and networking, the discovery flow
looks up the current role mapping via the new
InventoryRepository::get_role_mapping(host_id) method. If one
exists, the operator sees a summary (role, install disk, bond
mode + interfaces, blacklist) and picks between "Update" and
"Cancel"; cancelling skips the host entirely and continues the
selection loop without touching the DB. New HostRoleMapping
domain type carries the returned row back to the caller.
- Network interfaces are sorted by name at the hwinfo-to-domain
conversion step (both MDNS and CIDR flows), so f0 always appears
before f1 in every downstream consumer — host summary, bond
multi-select, blacklist multi-select. This also makes the
byte-equality dedup in save() robust against the agent returning
NICs in different sysfs-walk order across reboots.
- PhysicalHost::summary() split into summary_parts_through_storage()
+ append_network_summary(), with a new public summary_short()
variant that omits the NIC list. print_host_header() in the
discovery prompts now uses summary_short() so the "Host: ..."
banner fits on one line; full summaries still render in the node
picker, logs, and Display impl.
- Fix CPU summary rendering when the agent reports an empty model:
single-CPU renders as "6c/6t", multi-CPU as "2x CPU (12c/24t)",
no stray double-space in the pipe-separated summary.
- Regenerate .sqlx offline cache for the new DELETE and SELECT
queries.