diff --git a/CHANGELOG.md b/CHANGELOG.md index 26c93daa..489dab5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ Releases before `0.2.5` predate the public launch; their notes live in the ## [Unreleased] +### Fixed + +- Align planner action descriptions with the Ubuntu execution fence, including + Ufw and the other tool families moved to shared or Debian-family support. + Guard both directions of the description/fence relationship (#416). + ## [0.15.0] โ€” 2026-09-10 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 83cebc79..acd832f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,9 +242,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" dependencies = [ "aws-lc-sys", "zeroize", @@ -252,14 +252,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -4010,9 +4011,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.39" +version = "0.23.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" dependencies = [ "aws-lc-rs", "once_cell", @@ -4074,9 +4075,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "aws-lc-rs", "ring", diff --git a/README.md b/README.md index a381ad8e..4f187be2 100644 --- a/README.md +++ b/README.md @@ -314,7 +314,7 @@ milestone. | **Every Ubuntu LTS validated** โ€” 22.04, 24.04 and 26.04 all at 79/79, each with a replay twin that reproduces it | โœ… | | Telegram approval interface | ๐Ÿ“‹ roadmap | -**1,852 Rust tests and 72 frontend tests** form the current deterministic +**1,853 Rust tests and 72 frontend tests** form the current deterministic release baseline. ## Configure your LLM diff --git a/crates/sysknife-brain/src/planning_tools/propose_plan.rs b/crates/sysknife-brain/src/planning_tools/propose_plan.rs index 2da06882..d51521e9 100644 --- a/crates/sysknife-brain/src/planning_tools/propose_plan.rs +++ b/crates/sysknife-brain/src/planning_tools/propose_plan.rs @@ -192,11 +192,11 @@ this is runtime status, NOT the saved configuration; on Ubuntu the saved config "disable a swap file, remove it, and drop its /etc/fstab entry โ€” param: file* (must already be a swap file per /proc/swaps or /etc/fstab, and not a symlink); High risk"), // apt pinning (preferences.d) โ€” Ubuntu/Debian only ("GetAptPins", - "show apt pin priorities (apt-cache policy) โ€” param: package (optional); Ubuntu only; read-only"), + "show apt pin priorities (apt-cache policy) โ€” param: package (optional); read-only"), ("SetAptPin", - "pin a package to a version/release via /etc/apt/preferences.d โ€” params: name*, package* (glob), pin* (e.g. 'version 1.24.*' or 'release a=noble-security'), priority* (int -1..1000); Ubuntu only; Medium risk"), + "pin a package to a version/release via /etc/apt/preferences.d โ€” params: name*, package* (glob), pin* (e.g. 'version 1.24.*' or 'release a=noble-security'), priority* (int -1..1000); Medium risk"), ("RemoveAptPin", - "remove a SysKnife-managed apt pin โ€” param: name*; Ubuntu only; Medium risk"), + "remove a SysKnife-managed apt pin โ€” param: name*; Medium risk"), // Scoped sudoers.d ("GetSudoGrants", "list SysKnife-managed sudoers.d drop-ins โ€” no params; read-only"), @@ -294,33 +294,33 @@ this is runtime status, NOT the saved configuration; on Ubuntu the saved config "show SysKnife's own job log โ€” optional params: limit (int), status_filter, action_filter, since_hours (int)"), // โ”€โ”€ Ubuntu / apt โ€” package management โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("AptUpdate", - "refresh apt package index (apt-get update) โ€” no params; Ubuntu only"), + "refresh apt package index (apt-get update) โ€” no params"), ("AptUpgrade", - "upgrade all installed packages via dist-upgrade โ€” no params; Ubuntu only; High risk"), + "upgrade all installed packages via dist-upgrade โ€” no params; High risk"), ("AptInstall", - "install a package โ€” param: package* (string, e.g. nginx); Ubuntu only"), + "install a package โ€” param: package* (string, e.g. nginx)"), ("AptRemove", - "remove a package, keep config files โ€” param: package*; Ubuntu only"), + "remove a package, keep config files โ€” param: package*"), ("AptPurge", - "remove a package AND its config files โ€” param: package*; Ubuntu only"), + "remove a package AND its config files โ€” param: package*"), ("AptAutoremove", - "remove automatically-installed packages no longer needed โ€” no params; Ubuntu only"), + "remove automatically-installed packages no longer needed โ€” no params"), ("AptHold", - "pin a package at its current version (apt-mark hold) โ€” param: package*; Ubuntu only"), + "pin a package at its current version (apt-mark hold) โ€” param: package*"), ("AptUnhold", - "unpin a package to allow upgrades (apt-mark unhold) โ€” param: package*; Ubuntu only"), + "unpin a package to allow upgrades (apt-mark unhold) โ€” param: package*"), ("AptSearch", - "search apt repos for packages โ€” param: term*; Ubuntu only; read-only"), + "search apt repos for packages โ€” param: term*; read-only"), ("AptListInstalled", - "list all installed packages (dpkg -l) โ€” no params; Ubuntu only; read-only"), + "list all installed packages (dpkg -l) โ€” no params; read-only"), ("AptShow", - "show package details (version, deps, description) โ€” param: package*; Ubuntu only; read-only"), + "show package details (version, deps, description) โ€” param: package*; read-only"), ("AptListUpgradable", - "list packages with available upgrades โ€” no params; Ubuntu only; read-only. Use for 'are there pending updates?' or 'what updates are available?'"), + "list packages with available upgrades โ€” no params; read-only. Use for 'are there pending updates?' or 'what updates are available?'"), ("AptHistoryList", - "show recent apt transaction history โ€” no params; Ubuntu only; read-only"), + "show recent apt transaction history โ€” no params; read-only"), ("ConfigureUnattendedUpgrades", - "enable or disable automatic security updates (unattended-upgrades) โ€” param: enabled* (bool); Ubuntu only; High risk"), + "enable or disable automatic security updates (unattended-upgrades) โ€” param: enabled* (bool); High risk"), // โ”€โ”€ Ubuntu / ppa โ€” Launchpad PPAs โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("AddPpa", "add a Launchpad PPA โ€” param: name* in / format (e.g. 'deadsnakes/ppa'); Ubuntu only; requires software-properties-common"), @@ -328,55 +328,55 @@ this is runtime status, NOT the saved configuration; on Ubuntu the saved config "remove a Launchpad PPA โ€” param: name* in / format; Ubuntu only"), // โ”€โ”€ Ubuntu / snap โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("SnapInstall", - "install a snap (auto-holds to prevent auto-refresh) โ€” params: name*; optional: channel (default stable), auto_update (bool, default false); Ubuntu only"), + "install a snap (auto-holds to prevent auto-refresh) โ€” params: name*; optional: channel (default stable), auto_update (bool, default false)"), ("SnapRemove", - "remove a snap โ€” param: name*; Ubuntu only"), + "remove a snap โ€” param: name*"), ("SnapRefresh", - "update a snap or all snaps โ€” param: name (optional, omit for all); Ubuntu only"), + "update a snap or all snaps โ€” param: name (optional, omit for all)"), ("SnapHold", - "pin a snap at its current version (snap refresh --hold) โ€” param: name*; Ubuntu only"), + "pin a snap at its current version (snap refresh --hold) โ€” param: name*"), ("SnapUnhold", - "allow a held snap to auto-refresh again โ€” param: name*; Ubuntu only"), + "allow a held snap to auto-refresh again โ€” param: name*"), ("SnapList", - "list installed snaps โ€” no params; Ubuntu only; read-only"), + "list installed snaps โ€” no params; read-only"), ("SnapInfo", - "show snap details (version, channel, description) โ€” param: name*; Ubuntu only; read-only"), + "show snap details (version, channel, description) โ€” param: name*; read-only"), ("SnapRevert", - "revert a snap to its previous revision โ€” param: name*; Ubuntu only"), + "revert a snap to its previous revision โ€” param: name*"), ("SnapClassicInstall", - "install a snap with classic confinement (full system access) โ€” param: name*; Ubuntu only"), + "install a snap with classic confinement (full system access) โ€” param: name*"), // โ”€โ”€ Ubuntu / ufw โ€” firewall โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("UfwEnable", - "enable the ufw firewall โ€” no params; Ubuntu only; High risk"), + "enable the ufw firewall โ€” no params; High risk"), ("UfwDisable", - "disable the ufw firewall โ€” no params; Ubuntu only; High risk"), + "disable the ufw firewall โ€” no params; High risk"), ("UfwAllow", - "allow inbound traffic on a port or service โ€” param: port_or_service* (e.g. 22, 22/tcp, OpenSSH); Ubuntu only; High risk"), + "allow inbound traffic on a port or service โ€” param: port_or_service* (e.g. 22, 22/tcp, OpenSSH); High risk"), ("UfwDeny", - "deny inbound traffic on a port or service โ€” param: port_or_service*; Ubuntu only; High risk"), + "deny inbound traffic on a port or service โ€” param: port_or_service*; High risk"), ("UfwReset", - "reset ufw to defaults, removing all rules โ€” no params; Ubuntu only; High risk; irreversible"), + "reset ufw to defaults, removing all rules โ€” no params; High risk; irreversible"), ("UfwStatus", "show current ufw status and rules โ€” optional param: numbered (boolean, default false); true runs ufw status numbered and exposes rule_number values for UfwDeleteRule, false keeps verbose status; read-only"), // โ”€โ”€ Ubuntu / distrobox โ€” container environment โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("DistroboxList", - "list distrobox containers โ€” no params; Ubuntu only; read-only"), + "list distrobox containers โ€” no params; read-only"), ("DistroboxCreate", - "create a distrobox container โ€” params: name*, image* (e.g. ubuntu:24.04, fedora:41); Ubuntu only"), + "create a distrobox container โ€” params: name*, image* (e.g. ubuntu:24.04, fedora:41)"), ("DistroboxRemove", - "remove a distrobox container โ€” param: name*; Ubuntu only"), + "remove a distrobox container โ€” param: name*"), // โ”€โ”€ Ubuntu / netplan โ€” server network config โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("NetplanGetConfig", - "read the SAVED network configuration: the netplan YAML in /etc/netplan/ โ€” no params; Ubuntu only; \ + "read the SAVED network configuration: the netplan YAML in /etc/netplan/ โ€” no params; \ read-only; on Ubuntu this is what \"the network config\" means, as opposed to GetNetworkStatus which \ reports live interface state"), ("NetplanApply", - "apply netplan network configuration immediately โ€” no params; Ubuntu only; High risk; can disconnect SSH"), + "apply netplan network configuration immediately โ€” no params; High risk; can disconnect SSH"), // โ”€โ”€ Ubuntu / grub โ€” kernel arguments โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("GrubGetKargs", - "read current GRUB_CMDLINE_LINUX from /etc/default/grub โ€” no params; Ubuntu only; read-only"), + "read current GRUB_CMDLINE_LINUX from /etc/default/grub โ€” no params; read-only"), ("GrubSetKargs", - "modify GRUB kernel arguments and run update-grub โ€” params: append (list), delete (list), bare tokens only (no '='); both lists are screened for boot-security downgrades; Ubuntu only; High risk; requires reboot"), + "modify GRUB kernel arguments and run update-grub โ€” params: append (list), delete (list), bare tokens only (no '='); both lists are screened for boot-security downgrades; High risk; requires reboot"), // โ”€โ”€ Ubuntu / reboot โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("CheckPendingReboot", "check whether a reboot is pending (/var/run/reboot-required) โ€” no params; Ubuntu only; read-only"), @@ -387,32 +387,32 @@ reports live interface state"), "set DNS servers for a network interface โ€” params: interface* (e.g. eth0), servers* (string[]); cross-distro; High risk"), // โ”€โ”€ Ubuntu / AppArmor โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("AppArmorStatus", - "show status of all loaded AppArmor profiles (aa-status) โ€” no params; Ubuntu only; read-only"), + "show status of all loaded AppArmor profiles (aa-status) โ€” no params; read-only"), ("AppArmorEnforce", - "put an AppArmor profile into enforce mode (aa-enforce) โ€” param: profile_path* (e.g. /etc/apparmor.d/usr.bin.firefox); Ubuntu only; High risk"), + "put an AppArmor profile into enforce mode (aa-enforce) โ€” param: profile_path* (e.g. /etc/apparmor.d/usr.bin.firefox); High risk"), ("AppArmorComplain", - "put an AppArmor profile into complain/learning mode (aa-complain) โ€” param: profile_path*; Ubuntu only; High risk (disables MAC enforcement for the profile)"), + "put an AppArmor profile into complain/learning mode (aa-complain) โ€” param: profile_path*; High risk (disables MAC enforcement for the profile)"), // โ”€โ”€ Ubuntu / cloud-init โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("CloudInitStatus", - "show cloud-init provisioning status (cloud-init status --long) โ€” no params; Ubuntu only; read-only"), + "show cloud-init provisioning status (cloud-init status --long) โ€” no params; read-only"), // โ”€โ”€ Ubuntu / Flatpak (Ubuntu-specific routing) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("UbuntuInstallFlatpak", - "install a Flatpak app on Ubuntu โ€” params: username*, app_id*, remote* (e.g. flathub); Ubuntu only; Medium risk"), + "install a Flatpak app โ€” params: username*, app_id*, remote* (e.g. flathub); Medium risk"), ("UbuntuRemoveFlatpak", - "remove a Flatpak app on Ubuntu โ€” params: username*, app_id*; Ubuntu only; Medium risk"), + "remove a Flatpak app โ€” params: username*, app_id*; Medium risk"), ("UbuntuUpdateFlatpak", - "update Flatpak app(s) on Ubuntu โ€” param: username*; optional: app_id (omit for all); Ubuntu only; Medium risk"), + "update Flatpak app(s) โ€” param: username*; optional: app_id (omit for all); Medium risk"), ("UbuntuListFlatpaks", - "list installed Flatpak apps on Ubuntu โ€” param: username*; Ubuntu only; read-only"), + "list installed Flatpak apps โ€” param: username*; read-only"), // โ”€โ”€ Ubuntu / fail2ban โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("Fail2banStatus", - "show fail2ban jail status โ€” optional param: jail (omit for all jails); Ubuntu only; read-only"), + "show fail2ban jail status โ€” optional param: jail (omit for all jails); read-only"), ("Fail2banBanIp", - "ban an IP address in a fail2ban jail โ€” params: jail* (string), ip* (IPv4 or IPv6); Ubuntu only; High risk"), + "ban an IP address in a fail2ban jail โ€” params: jail* (string), ip* (IPv4 or IPv6); High risk"), ("Fail2banUnbanIp", - "unban an IP address from a fail2ban jail โ€” params: jail*, ip*; Ubuntu only; Medium risk"), + "unban an IP address from a fail2ban jail โ€” params: jail*, ip*; Medium risk"), ("ConfigureFail2banJail", - "write a fail2ban jail override (/etc/fail2ban/jail.d/) โ€” params: name*, plus at least one of enabled (bool), maxretry (1-100), bantime/findtime (seconds 0-2592000); Ubuntu only; High risk; needs fail2ban installed"), + "write a fail2ban jail override (/etc/fail2ban/jail.d/) โ€” params: name*, plus at least one of enabled (bool), maxretry (1-100), bantime/findtime (seconds 0-2592000); High risk; needs fail2ban installed"), // โ”€โ”€ auditd file-watch rules (cross-distro) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("GetAuditRules", "list loaded audit rules (auditctl -l) โ€” no params; read-only; needs auditd installed"), @@ -429,14 +429,14 @@ reports live interface state"), "renew due certbot certificates (certbot renew) โ€” no params; Medium risk; needs certbot + network"), // โ”€โ”€ Ubuntu / Tier 3 โ€” netplan extensions โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("NetplanSet", - "set a single netplan key to a value โ€” params: key* (e.g. 'ethernets.eth0.dhcp4'), value*; Ubuntu only; High risk; run NetplanApply to activate"), + "set a single netplan key to a value โ€” params: key* (e.g. 'ethernets.eth0.dhcp4'), value*; High risk; run NetplanApply to activate"), ("NetplanGenerate", - "regenerate netplan backend config without applying โ€” no params; Ubuntu only; Medium risk; dry-run before NetplanApply"), + "regenerate netplan backend config without applying โ€” no params; Medium risk; dry-run before NetplanApply"), // โ”€โ”€ Ubuntu / Tier 3 โ€” ufw extensions โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("UfwDeleteRule", "delete a ufw rule by number โ€” param: rule_number* (positive integer from query_ufw_rules or UfwStatus with numbered=true); never guess a rule number, and refresh after rule changes; High risk"), ("UfwLimit", - "add rate-limiting rule on a port/service (>6 connections/30s blocked) โ€” param: target* (e.g. '22' or 'ssh'); Ubuntu only; High risk; use for SSH brute-force mitigation"), + "add rate-limiting rule on a port/service (>6 connections/30s blocked) โ€” param: target* (e.g. '22' or 'ssh'); High risk; use for SSH brute-force mitigation"), // โ”€โ”€ Ubuntu / Tier 3 โ€” release upgrade โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("UbuntuReleaseUpgrade", "upgrade to the next Ubuntu release (do-release-upgrade) โ€” no params; Ubuntu only; High risk; takes 20โ€“45 min; requires reboot; only for explicit distribution upgrade requests"), @@ -456,7 +456,7 @@ reports live interface state"), "show Canonical Livepatch kernel-patch status โ€” no params; Ubuntu only; read-only; requires canonical-livepatch installed and Ubuntu Pro"), // โ”€โ”€ Ubuntu / Tier 3 โ€” Multipass โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ("MultipassList", - "list Multipass VMs and their state โ€” no params; Ubuntu only; read-only"), + "list Multipass VMs and their state โ€” no params; read-only"), ]; /// Should `action` be offered on the detected distribution? @@ -724,6 +724,25 @@ pub fn parse_proposed_plan(intent: &str, input: &serde_json::Value) -> Result) -> ToolDefinition { let hint = family.map(|family| sysknife_types::DistroHint { id: if family == DISTRO_FAMILY_DEBIAN { diff --git a/docs/action-reference.md b/docs/action-reference.md index 59df9200..90186aa6 100644 --- a/docs/action-reference.md +++ b/docs/action-reference.md @@ -56,10 +56,10 @@ Every row is derived from the live code: the command from each action's `ActionS | `RemoveFlatpakRemote` | `sudo runuser -u testuser -- flatpak remote-delete --user remote` | Medium | All | โ€“ | โ€“ | remove a Flatpak remote โ€” params: username\*, remote\* (name) | | `GetFlatpakAppInfo` | `sudo runuser -u testuser -- flatpak info --user app-id` | Low | All | โ€“ | โ€“ | show metadata for an installed Flatpak โ€” params: username\*, app_id\* | | `UpdateFlatpak` | `sudo runuser -u testuser -- flatpak update --user -y com.example.App` | Medium | All | โ€“ | โ€“ | update Flatpak apps โ€” params: username\* (required); app_id (optional โ€” omit to update all) | -| `UbuntuInstallFlatpak` | `sudo runuser -u testuser -- flatpak install --user -y flathub app-id` | Medium | Ubuntu | โ€“ | โ€“ | install a Flatpak app on Ubuntu โ€” params: username\*, app_id\*, remote\* (e.g. flathub); Ubuntu only; Medium risk | -| `UbuntuRemoveFlatpak` | `sudo runuser -u testuser -- flatpak uninstall --user -y app-id` | Medium | Ubuntu | โ€“ | โ€“ | remove a Flatpak app on Ubuntu โ€” params: username\*, app_id\*; Ubuntu only; Medium risk | -| `UbuntuUpdateFlatpak` | `sudo runuser -u testuser -- flatpak update --user -y com.example.App` | Medium | Ubuntu | โ€“ | โ€“ | update Flatpak app(s) on Ubuntu โ€” param: username\*; optional: app_id (omit for all); Ubuntu only; Medium risk | -| `UbuntuListFlatpaks` | `sudo runuser -u testuser -- flatpak list --user --app --columns=application,name,version,origin` | Low | Ubuntu | โ€“ | โ€“ | list installed Flatpak apps on Ubuntu โ€” param: username\*; Ubuntu only; read-only | +| `UbuntuInstallFlatpak` | `sudo runuser -u testuser -- flatpak install --user -y flathub app-id` | Medium | Ubuntu | โ€“ | โ€“ | install a Flatpak app โ€” params: username\*, app_id\*, remote\* (e.g. flathub); Medium risk | +| `UbuntuRemoveFlatpak` | `sudo runuser -u testuser -- flatpak uninstall --user -y app-id` | Medium | Ubuntu | โ€“ | โ€“ | remove a Flatpak app โ€” params: username\*, app_id\*; Medium risk | +| `UbuntuUpdateFlatpak` | `sudo runuser -u testuser -- flatpak update --user -y com.example.App` | Medium | Ubuntu | โ€“ | โ€“ | update Flatpak app(s) โ€” param: username\*; optional: app_id (omit for all); Medium risk | +| `UbuntuListFlatpaks` | `sudo runuser -u testuser -- flatpak list --user --app --columns=application,name,version,origin` | Low | Ubuntu | โ€“ | โ€“ | list installed Flatpak apps โ€” param: username\*; read-only | ## Toolbox @@ -262,51 +262,51 @@ Every row is derived from the live code: the command from each action's `ActionS | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `AppArmorStatus` | `sudo aa-status` | Low | Ubuntu | โ€“ | โ€“ | show status of all loaded AppArmor profiles (aa-status) โ€” no params; Ubuntu only; read-only | -| `AppArmorEnforce` | `sudo aa-enforce /etc/apparmor.d/usr.bin.firefox` | High | Ubuntu | โ€“ | โ€“ | put an AppArmor profile into enforce mode (aa-enforce) โ€” param: profile_path\* (e.g. /etc/apparmor.d/usr.bin.firefox); Ubuntu only; High risk | -| `AppArmorComplain` | `sudo aa-complain /etc/apparmor.d/usr.bin.firefox` | High | Ubuntu | โ€“ | โ€“ | put an AppArmor profile into complain/learning mode (aa-complain) โ€” param: profile_path\*; Ubuntu only; High risk (disables MAC enforcement for the profile) | +| `AppArmorStatus` | `sudo aa-status` | Low | Ubuntu | โ€“ | โ€“ | show status of all loaded AppArmor profiles (aa-status) โ€” no params; read-only | +| `AppArmorEnforce` | `sudo aa-enforce /etc/apparmor.d/usr.bin.firefox` | High | Ubuntu | โ€“ | โ€“ | put an AppArmor profile into enforce mode (aa-enforce) โ€” param: profile_path\* (e.g. /etc/apparmor.d/usr.bin.firefox); High risk | +| `AppArmorComplain` | `sudo aa-complain /etc/apparmor.d/usr.bin.firefox` | High | Ubuntu | โ€“ | โ€“ | put an AppArmor profile into complain/learning mode (aa-complain) โ€” param: profile_path\*; High risk (disables MAC enforcement for the profile) | ## cloud-init | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `CloudInitStatus` | `cloud-init status --long` | Low | Ubuntu | โ€“ | โ€“ | show cloud-init provisioning status (cloud-init status --long) โ€” no params; Ubuntu only; read-only | +| `CloudInitStatus` | `cloud-init status --long` | Low | Ubuntu | โ€“ | โ€“ | show cloud-init provisioning status (cloud-init status --long) โ€” no params; read-only | ## fail2ban | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `Fail2banStatus` | `sudo fail2ban-client status` | Low | Ubuntu | โ€“ | โ€“ | show fail2ban jail status โ€” optional param: jail (omit for all jails); Ubuntu only; read-only | -| `Fail2banBanIp` | `sudo fail2ban-client set sshd banip 192.0.2.1` | High | Ubuntu | โ€“ | โ€“ | ban an IP address in a fail2ban jail โ€” params: jail\* (string), ip\* (IPv4 or IPv6); Ubuntu only; High risk | -| `Fail2banUnbanIp` | `sudo fail2ban-client set sshd unbanip 192.0.2.1` | Medium | Ubuntu | โ€“ | โ€“ | unban an IP address from a fail2ban jail โ€” params: jail\*, ip\*; Ubuntu only; Medium risk | -| `ConfigureFail2banJail` | `sudo /usr/lib/sysknife/fail2ban-jail-edit --name sshd --maxretry 3` | High | Ubuntu | โ€“ | โ€“ | write a fail2ban jail override (/etc/fail2ban/jail.d/) โ€” params: name\*, plus at least one of enabled (bool), maxretry (1-100), bantime/findtime (seconds 0-2592000); Ubuntu only; High risk; needs fail2ban installed | +| `Fail2banStatus` | `sudo fail2ban-client status` | Low | Ubuntu | โ€“ | โ€“ | show fail2ban jail status โ€” optional param: jail (omit for all jails); read-only | +| `Fail2banBanIp` | `sudo fail2ban-client set sshd banip 192.0.2.1` | High | Ubuntu | โ€“ | โ€“ | ban an IP address in a fail2ban jail โ€” params: jail\* (string), ip\* (IPv4 or IPv6); High risk | +| `Fail2banUnbanIp` | `sudo fail2ban-client set sshd unbanip 192.0.2.1` | Medium | Ubuntu | โ€“ | โ€“ | unban an IP address from a fail2ban jail โ€” params: jail\*, ip\*; Medium risk | +| `ConfigureFail2banJail` | `sudo /usr/lib/sysknife/fail2ban-jail-edit --name sshd --maxretry 3` | High | Ubuntu | โ€“ | โ€“ | write a fail2ban jail override (/etc/fail2ban/jail.d/) โ€” params: name\*, plus at least one of enabled (bool), maxretry (1-100), bantime/findtime (seconds 0-2592000); High risk; needs fail2ban installed | ## apt | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `AptUpdate` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get update` | Low | Ubuntu | โ€“ | โ€“ | refresh apt package index (apt-get update) โ€” no params; Ubuntu only | -| `AptUpgrade` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get dist-upgrade -y` | High | Ubuntu | โ€“ | โ€“ | upgrade all installed packages via dist-upgrade โ€” no params; Ubuntu only; High risk | -| `AptInstall` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get install -y curl` | Medium | Ubuntu | โ€“ | โ€“ | install a package โ€” param: package\* (string, e.g. nginx); Ubuntu only | -| `AptRemove` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get remove -y curl` | Medium | Ubuntu | โ€“ | โ€“ | remove a package, keep config files โ€” param: package\*; Ubuntu only | -| `AptPurge` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get purge -y curl` | Medium | Ubuntu | โ€“ | โ€“ | remove a package AND its config files โ€” param: package\*; Ubuntu only | -| `AptAutoremove` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get autoremove -y` | Medium | Ubuntu | โ€“ | โ€“ | remove automatically-installed packages no longer needed โ€” no params; Ubuntu only | -| `AptHold` | `sudo apt-mark hold curl` | Medium | Ubuntu | โ€“ | โ€“ | pin a package at its current version (apt-mark hold) โ€” param: package\*; Ubuntu only | -| `AptUnhold` | `sudo apt-mark unhold curl` | Medium | Ubuntu | โ€“ | โ€“ | unpin a package to allow upgrades (apt-mark unhold) โ€” param: package\*; Ubuntu only | -| `AptSearch` | `apt-cache search curl` | Low | Ubuntu | โ€“ | โ€“ | search apt repos for packages โ€” param: term\*; Ubuntu only; read-only | -| `AptListInstalled` | `dpkg -l` | Low | Ubuntu | โ€“ | โ€“ | list all installed packages (dpkg -l) โ€” no params; Ubuntu only; read-only | -| `AptShow` | `apt-cache show curl` | Low | Ubuntu | โ€“ | โ€“ | show package details (version, deps, description) โ€” param: package\*; Ubuntu only; read-only | -| `AptListUpgradable` | `bash -c "apt list --upgradable 2>/dev/null"` | Low | Ubuntu | โ€“ | โ€“ | list packages with available upgrades โ€” no params; Ubuntu only; read-only. Use for 'are there pending updates?' or 'what updates are available?' | -| `AptHistoryList` | `bash -c "grep -A 4 '^Start-Date' /var/log/apt/history.log \| tail -n 80"` | Low | Ubuntu | โ€“ | โ€“ | show recent apt transaction history โ€” no params; Ubuntu only; read-only | -| `ConfigureUnattendedUpgrades` | `sudo /usr/lib/sysknife/unattended-upgrades-edit --enable` | High | Ubuntu | โ€“ | โ€“ | enable or disable automatic security updates (unattended-upgrades) โ€” param: enabled\* (bool); Ubuntu only; High risk | +| `AptUpdate` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get update` | Low | Ubuntu | โ€“ | โ€“ | refresh apt package index (apt-get update) โ€” no params | +| `AptUpgrade` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get dist-upgrade -y` | High | Ubuntu | โ€“ | โ€“ | upgrade all installed packages via dist-upgrade โ€” no params; High risk | +| `AptInstall` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get install -y curl` | Medium | Ubuntu | โ€“ | โ€“ | install a package โ€” param: package\* (string, e.g. nginx) | +| `AptRemove` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get remove -y curl` | Medium | Ubuntu | โ€“ | โ€“ | remove a package, keep config files โ€” param: package\* | +| `AptPurge` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get purge -y curl` | Medium | Ubuntu | โ€“ | โ€“ | remove a package AND its config files โ€” param: package\* | +| `AptAutoremove` | `sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a /usr/bin/apt-get autoremove -y` | Medium | Ubuntu | โ€“ | โ€“ | remove automatically-installed packages no longer needed โ€” no params | +| `AptHold` | `sudo apt-mark hold curl` | Medium | Ubuntu | โ€“ | โ€“ | pin a package at its current version (apt-mark hold) โ€” param: package\* | +| `AptUnhold` | `sudo apt-mark unhold curl` | Medium | Ubuntu | โ€“ | โ€“ | unpin a package to allow upgrades (apt-mark unhold) โ€” param: package\* | +| `AptSearch` | `apt-cache search curl` | Low | Ubuntu | โ€“ | โ€“ | search apt repos for packages โ€” param: term\*; read-only | +| `AptListInstalled` | `dpkg -l` | Low | Ubuntu | โ€“ | โ€“ | list all installed packages (dpkg -l) โ€” no params; read-only | +| `AptShow` | `apt-cache show curl` | Low | Ubuntu | โ€“ | โ€“ | show package details (version, deps, description) โ€” param: package\*; read-only | +| `AptListUpgradable` | `bash -c "apt list --upgradable 2>/dev/null"` | Low | Ubuntu | โ€“ | โ€“ | list packages with available upgrades โ€” no params; read-only. Use for 'are there pending updates?' or 'what updates are available?' | +| `AptHistoryList` | `bash -c "grep -A 4 '^Start-Date' /var/log/apt/history.log \| tail -n 80"` | Low | Ubuntu | โ€“ | โ€“ | show recent apt transaction history โ€” no params; read-only | +| `ConfigureUnattendedUpgrades` | `sudo /usr/lib/sysknife/unattended-upgrades-edit --enable` | High | Ubuntu | โ€“ | โ€“ | enable or disable automatic security updates (unattended-upgrades) โ€” param: enabled\* (bool); High risk | ## apt preferences / pinning | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `GetAptPins` | `apt-cache policy` | Low | Ubuntu | โ€“ | โ€“ | show apt pin priorities (apt-cache policy) โ€” param: package (optional); Ubuntu only; read-only | -| `SetAptPin` | `sudo /usr/lib/sysknife/apt-pin-edit --op set --name hold-nginx --package nginx --pin "version 1.24.*" --priority 990` | Medium | Ubuntu | โ€“ | โ€“ | pin a package to a version/release via /etc/apt/preferences.d โ€” params: name\*, package\* (glob), pin\* (e.g. 'version 1.24.\*' or 'release a=noble-security'), priority\* (int -1..1000); Ubuntu only; Medium risk | -| `RemoveAptPin` | `sudo /usr/lib/sysknife/apt-pin-edit --op remove --name hold-nginx` | Medium | Ubuntu | โ€“ | โ€“ | remove a SysKnife-managed apt pin โ€” param: name\*; Ubuntu only; Medium risk | +| `GetAptPins` | `apt-cache policy` | Low | Ubuntu | โ€“ | โ€“ | show apt pin priorities (apt-cache policy) โ€” param: package (optional); read-only | +| `SetAptPin` | `sudo /usr/lib/sysknife/apt-pin-edit --op set --name hold-nginx --package nginx --pin "version 1.24.*" --priority 990` | Medium | Ubuntu | โ€“ | โ€“ | pin a package to a version/release via /etc/apt/preferences.d โ€” params: name\*, package\* (glob), pin\* (e.g. 'version 1.24.\*' or 'release a=noble-security'), priority\* (int -1..1000); Medium risk | +| `RemoveAptPin` | `sudo /usr/lib/sysknife/apt-pin-edit --op remove --name hold-nginx` | Medium | Ubuntu | โ€“ | โ€“ | remove a SysKnife-managed apt pin โ€” param: name\*; Medium risk | ## PPA @@ -319,52 +319,52 @@ Every row is derived from the live code: the command from each action's `ActionS | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `SnapInstall` | `sudo sh -c "snap install --channel=stable firefox && snap refresh --hold firefox"` | Medium | Ubuntu | โ€“ | โ€“ | install a snap (auto-holds to prevent auto-refresh) โ€” params: name\*; optional: channel (default stable), auto_update (bool, default false); Ubuntu only | -| `SnapRemove` | `sudo snap remove firefox` | Medium | Ubuntu | โ€“ | โ€“ | remove a snap โ€” param: name\*; Ubuntu only | -| `SnapRefresh` | `sudo snap refresh firefox` | Medium | Ubuntu | โ€“ | โ€“ | update a snap or all snaps โ€” param: name (optional, omit for all); Ubuntu only | -| `SnapHold` | `sudo snap refresh --hold firefox` | Medium | Ubuntu | โ€“ | โ€“ | pin a snap at its current version (snap refresh --hold) โ€” param: name\*; Ubuntu only | -| `SnapUnhold` | `sudo snap refresh --unhold firefox` | Medium | Ubuntu | โ€“ | โ€“ | allow a held snap to auto-refresh again โ€” param: name\*; Ubuntu only | -| `SnapList` | `snap list` | Low | Ubuntu | โ€“ | โ€“ | list installed snaps โ€” no params; Ubuntu only; read-only | -| `SnapInfo` | `snap info firefox` | Low | Ubuntu | โ€“ | โ€“ | show snap details (version, channel, description) โ€” param: name\*; Ubuntu only; read-only | -| `SnapRevert` | `sudo snap revert firefox` | Medium | Ubuntu | โ€“ | โ€“ | revert a snap to its previous revision โ€” param: name\*; Ubuntu only | -| `SnapClassicInstall` | `sudo snap install --classic code` | Medium | Ubuntu | โ€“ | โ€“ | install a snap with classic confinement (full system access) โ€” param: name\*; Ubuntu only | +| `SnapInstall` | `sudo sh -c "snap install --channel=stable firefox && snap refresh --hold firefox"` | Medium | Ubuntu | โ€“ | โ€“ | install a snap (auto-holds to prevent auto-refresh) โ€” params: name\*; optional: channel (default stable), auto_update (bool, default false) | +| `SnapRemove` | `sudo snap remove firefox` | Medium | Ubuntu | โ€“ | โ€“ | remove a snap โ€” param: name\* | +| `SnapRefresh` | `sudo snap refresh firefox` | Medium | Ubuntu | โ€“ | โ€“ | update a snap or all snaps โ€” param: name (optional, omit for all) | +| `SnapHold` | `sudo snap refresh --hold firefox` | Medium | Ubuntu | โ€“ | โ€“ | pin a snap at its current version (snap refresh --hold) โ€” param: name\* | +| `SnapUnhold` | `sudo snap refresh --unhold firefox` | Medium | Ubuntu | โ€“ | โ€“ | allow a held snap to auto-refresh again โ€” param: name\* | +| `SnapList` | `snap list` | Low | Ubuntu | โ€“ | โ€“ | list installed snaps โ€” no params; read-only | +| `SnapInfo` | `snap info firefox` | Low | Ubuntu | โ€“ | โ€“ | show snap details (version, channel, description) โ€” param: name\*; read-only | +| `SnapRevert` | `sudo snap revert firefox` | Medium | Ubuntu | โ€“ | โ€“ | revert a snap to its previous revision โ€” param: name\* | +| `SnapClassicInstall` | `sudo snap install --classic code` | Medium | Ubuntu | โ€“ | โ€“ | install a snap with classic confinement (full system access) โ€” param: name\* | ## ufw | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `UfwEnable` | `sudo ufw --force enable` | High | Ubuntu | โ€“ | โ€“ | enable the ufw firewall โ€” no params; Ubuntu only; High risk | -| `UfwDisable` | `sudo ufw disable` | High | Ubuntu | โ€“ | โ€“ | disable the ufw firewall โ€” no params; Ubuntu only; High risk | -| `UfwAllow` | `sudo ufw allow 22` | High | Ubuntu | โ€“ | โ€“ | allow inbound traffic on a port or service โ€” param: port_or_service\* (e.g. 22, 22/tcp, OpenSSH); Ubuntu only; High risk | -| `UfwDeny` | `sudo ufw deny 23` | High | Ubuntu | โ€“ | โ€“ | deny inbound traffic on a port or service โ€” param: port_or_service\*; Ubuntu only; High risk | -| `UfwReset` | `sudo ufw --force reset` | High | Ubuntu | โ€“ | โ€“ | reset ufw to defaults, removing all rules โ€” no params; Ubuntu only; High risk; irreversible | +| `UfwEnable` | `sudo ufw --force enable` | High | Ubuntu | โ€“ | โ€“ | enable the ufw firewall โ€” no params; High risk | +| `UfwDisable` | `sudo ufw disable` | High | Ubuntu | โ€“ | โ€“ | disable the ufw firewall โ€” no params; High risk | +| `UfwAllow` | `sudo ufw allow 22` | High | Ubuntu | โ€“ | โ€“ | allow inbound traffic on a port or service โ€” param: port_or_service\* (e.g. 22, 22/tcp, OpenSSH); High risk | +| `UfwDeny` | `sudo ufw deny 23` | High | Ubuntu | โ€“ | โ€“ | deny inbound traffic on a port or service โ€” param: port_or_service\*; High risk | +| `UfwReset` | `sudo ufw --force reset` | High | Ubuntu | โ€“ | โ€“ | reset ufw to defaults, removing all rules โ€” no params; High risk; irreversible | | `UfwStatus` | `sudo ufw status verbose` | Low | Ubuntu | โ€“ | โ€“ | show current ufw status and rules โ€” optional param: numbered (boolean, default false); true runs ufw status numbered and exposes rule_number values for UfwDeleteRule, false keeps verbose status; read-only | | `UfwDeleteRule` | `sudo ufw --force delete 1` | High | Ubuntu | โ€“ | โ€“ | delete a ufw rule by number โ€” param: rule_number\* (positive integer from query_ufw_rules or UfwStatus with numbered=true); never guess a rule number, and refresh after rule changes; High risk | -| `UfwLimit` | `sudo ufw limit 22` | High | Ubuntu | โ€“ | โ€“ | add rate-limiting rule on a port/service (>6 connections/30s blocked) โ€” param: target\* (e.g. '22' or 'ssh'); Ubuntu only; High risk; use for SSH brute-force mitigation | +| `UfwLimit` | `sudo ufw limit 22` | High | Ubuntu | โ€“ | โ€“ | add rate-limiting rule on a port/service (>6 connections/30s blocked) โ€” param: target\* (e.g. '22' or 'ssh'); High risk; use for SSH brute-force mitigation | ## netplan | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `NetplanGetConfig` | `find /etc/netplan -maxdepth 1 -name *.yaml -print -exec cat {} +` | Low | Ubuntu | โ€“ | โ€“ | read the SAVED network configuration: the netplan YAML in /etc/netplan/ โ€” no params; Ubuntu only; read-only; on Ubuntu this is what "the network config" means, as opposed to GetNetworkStatus which reports live interface state | -| `NetplanApply` | `sudo netplan apply` | High | Ubuntu | โ€“ | โ€“ | apply netplan network configuration immediately โ€” no params; Ubuntu only; High risk; can disconnect SSH | -| `NetplanSet` | `sudo netplan set ethernets.eth0.dhcp4=true` | High | Ubuntu | โ€“ | โ€“ | set a single netplan key to a value โ€” params: key\* (e.g. 'ethernets.eth0.dhcp4'), value\*; Ubuntu only; High risk; run NetplanApply to activate | -| `NetplanGenerate` | `sudo netplan generate` | Medium | Ubuntu | โ€“ | โ€“ | regenerate netplan backend config without applying โ€” no params; Ubuntu only; Medium risk; dry-run before NetplanApply | +| `NetplanGetConfig` | `find /etc/netplan -maxdepth 1 -name *.yaml -print -exec cat {} +` | Low | Ubuntu | โ€“ | โ€“ | read the SAVED network configuration: the netplan YAML in /etc/netplan/ โ€” no params; read-only; on Ubuntu this is what "the network config" means, as opposed to GetNetworkStatus which reports live interface state | +| `NetplanApply` | `sudo netplan apply` | High | Ubuntu | โ€“ | โ€“ | apply netplan network configuration immediately โ€” no params; High risk; can disconnect SSH | +| `NetplanSet` | `sudo netplan set ethernets.eth0.dhcp4=true` | High | Ubuntu | โ€“ | โ€“ | set a single netplan key to a value โ€” params: key\* (e.g. 'ethernets.eth0.dhcp4'), value\*; High risk; run NetplanApply to activate | +| `NetplanGenerate` | `sudo netplan generate` | Medium | Ubuntu | โ€“ | โ€“ | regenerate netplan backend config without applying โ€” no params; Medium risk; dry-run before NetplanApply | ## distrobox | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `DistroboxList` | `distrobox list` | Low | Ubuntu | โ€“ | โ€“ | list distrobox containers โ€” no params; Ubuntu only; read-only | -| `DistroboxCreate` | `distrobox create --yes --name dev --image ubuntu:24.04` | Medium | Ubuntu | โ€“ | โ€“ | create a distrobox container โ€” params: name\*, image\* (e.g. ubuntu:24.04, fedora:41); Ubuntu only | -| `DistroboxRemove` | `distrobox rm --force dev` | Medium | Ubuntu | โ€“ | โ€“ | remove a distrobox container โ€” param: name\*; Ubuntu only | +| `DistroboxList` | `distrobox list` | Low | Ubuntu | โ€“ | โ€“ | list distrobox containers โ€” no params; read-only | +| `DistroboxCreate` | `distrobox create --yes --name dev --image ubuntu:24.04` | Medium | Ubuntu | โ€“ | โ€“ | create a distrobox container โ€” params: name\*, image\* (e.g. ubuntu:24.04, fedora:41) | +| `DistroboxRemove` | `distrobox rm --force dev` | Medium | Ubuntu | โ€“ | โ€“ | remove a distrobox container โ€” param: name\* | ## GRUB | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `GrubGetKargs` | `grep -E ^GRUB_CMDLINE_LINUX /etc/default/grub` | Low | Ubuntu | โ€“ | โ€“ | read current GRUB_CMDLINE_LINUX from /etc/default/grub โ€” no params; Ubuntu only; read-only | -| `GrubSetKargs` | `sudo /usr/lib/sysknife/grub-kargs-edit --append quiet --delete splash` | High | Ubuntu | โœ“ | โ€“ | modify GRUB kernel arguments and run update-grub โ€” params: append (list), delete (list), bare tokens only (no '='); both lists are screened for boot-security downgrades; Ubuntu only; High risk; requires reboot | +| `GrubGetKargs` | `grep -E ^GRUB_CMDLINE_LINUX /etc/default/grub` | Low | Ubuntu | โ€“ | โ€“ | read current GRUB_CMDLINE_LINUX from /etc/default/grub โ€” no params; read-only | +| `GrubSetKargs` | `sudo /usr/lib/sysknife/grub-kargs-edit --append quiet --delete splash` | High | Ubuntu | โœ“ | โ€“ | modify GRUB kernel arguments and run update-grub โ€” params: append (list), delete (list), bare tokens only (no '='); both lists are screened for boot-security downgrades; High risk; requires reboot | ## Ubuntu release upgrade @@ -392,7 +392,7 @@ Every row is derived from the live code: the command from each action's `ActionS | Action | Command | Risk | Distro | Rb | Ro | Description | |---|---|---|---|---|---|---| -| `MultipassList` | `multipass list` | Low | Ubuntu | โ€“ | โ€“ | list Multipass VMs and their state โ€” no params; Ubuntu only; read-only | +| `MultipassList` | `multipass list` | Low | Ubuntu | โ€“ | โ€“ | list Multipass VMs and their state โ€” no params; read-only | --- diff --git a/docs/distro-support.md b/docs/distro-support.md index a622c644..0578df7f 100644 --- a/docs/distro-support.md +++ b/docs/distro-support.md @@ -91,7 +91,7 @@ family and the atomic story family are implemented and covered by the workspace suite. What is missing is a way to put the helpers somewhere the daemon's own grants already point. -The deterministic workspace baseline is 1,852 Rust tests plus 72 frontend +The deterministic workspace baseline is 1,853 Rust tests plus 72 frontend tests. Those tests verify action construction, policy, approval, storage, and UI behavior, but they do not replace a real distribution VM run. diff --git a/docs/introduction.md b/docs/introduction.md index 2b0c7c76..25bd9d63 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -141,7 +141,7 @@ flow. ## Status -190 typed actions ยท 1,852 Rust tests + 72 frontend tests ยท MIT +190 typed actions ยท 1,853 Rust tests + 72 frontend tests ยท MIT SysKnife is the reference implementation of the [LACS specification](https://github.com/lacs-project/specification) โ€” a diff --git a/tests/evidence/workspace-tests.json b/tests/evidence/workspace-tests.json index f40c3476..e175f7b4 100644 --- a/tests/evidence/workspace-tests.json +++ b/tests/evidence/workspace-tests.json @@ -4,6 +4,6 @@ "tests": "cargo nextest run --workspace --locked" }, "frontend_tests": 72, - "tests": 1852, + "tests": 1853, "version": 2 }