Repository navigation
Fleet: group per-host previews by what the operator would approve (a pure function) #678
Description
#617's design rule "plan per distro class, approve per preview class" needs one piece that has no daemon dependency: given each host's preview, put the hosts whose previews are the same approval into one group, and show every split.
The input types exist: PreviewEnvelope (crates/sysknife-types/src/lib.rs:573) and the CLI's PreparedPreview { transaction_id, preview } (apps/sysknife-cli/src/client.rs:45). proposed_change carries {action, params} with params redacted, plus the autoremove set and deployment identity where they apply (crates/sysknife-daemon/src/dispatcher.rs:2436-2472).
Scope
group_previews(&[(HostName, PreparedPreview)]) -> Result<Vec<PreviewGroup>, _>in the CLI crate. Two hosts share a group when theirsummary,risk_level,proposed_change, sortedexpected_side_effects, sortedwarnings,reboot_requiredandrollback_availableare equal.- Each group carries its member hosts and one representative preview. Empty input is an error, not an empty list (Fleet plan and execute: design and order of work #617: "fail closed on empty").
- No CLI command yet;
fleet planwill call this once Planning against a remote daemon uses the client's distro, so a Fedora laptop loses the Ubuntu tools for an Ubuntu VM #618 and Show and pin the daemon's audit key, so a client knows which host is on the other end of the socket #619 land.
Traps
- Do not key on
request_hashortransaction_id. Both differ per host by design, and fix(security): key request_hash with an HMAC under the audit key (chain_version 4) #627 (223e86e) maderequest_hashan HMAC under each host's own audit key, so keying on it would put every host in its own group. - Do not key on
current_state: it describes the host, not the change. proposed_changecan differ legitimately (a different autoremove set on one host). That split is correct and must be shown, never merged away.
Tests first
- Two previews identical except
request_hashandtransaction_idform one group. - Two previews with different autoremove sets form two groups.
- Reordered
warningsstill group together. - Empty input is refused.
- Add
request_hashto the key and the first test must go red.
Difficulty
medium: a pure function over existing types, but choosing the key is the whole job.
Getting started
CONTRIBUTING.md has the build and test commands. No CLA and no copyright waiver. The project is MIT; sign off each commit with git commit -s (the required dco check enforces it since #732).
Activity
vladimirrott commentedon Oct 26, 2026
@Georgefifth, if you want this one, it's yours. Your #627 is what makes
request_hashdiffer per host, so you know better than anyone why this grouping must not key on it. It's a pure function overPreviewEnvelopewith no daemon in the loop.Say so here and I'll assign it to you. No pressure either way.
vladimirrott commentedon Oct 26, 2026
Line numbers moved after #626 merged today. I updated the anchors in the body; the code they point at is unchanged:
apps/sysknife-cli/src/client.rs:44→:45crates/sysknife-daemon/src/dispatcher.rs:2356-2392→:2364-2400