PROJECT MAMBO
Change colour theme

Installation and safety

MamboDot is a personal home-directory configuration, not an unattended installer. Its repository command previews one complete link or unlink operation before applying it, refuses conflicts, and never adopts existing home-directory files into the repository. Back up important configuration and review each selected package before linking it.

Requirements

The active configuration references these groups of software:

  • Arch Linux, Hyprland with the Lua hl configuration API, Hypridle, Hyprlock, and Hyprpaper.

  • AGS 3 with GTK4, the Astal Hyprland, battery, network, notification, tray, and WirePlumber libraries, and the astal-notifd executable; its SCSS bundle also requires Sass.

  • NetworkManager, BlueZ with bluetoothctl, Blueman, lm_sensors, nvidia-utils, brightnessctl with systemd-logind support, asusctl, supergfxctl, and Input Remapper for the current hardware controls. Obsidian is optional unless the day planner should open the vault.

  • GNU Stow, Git, Bash, Zsh, Oh My Zsh, zsh-autosuggestions, and zsh-syntax-highlighting.

  • Kitty, Dolphin, FeatherPad, qimgv, Qalculate-Qt, Neovim, Code OSS, Fastfetch, and KDE/Qt desktop utilities.

  • Fcitx5 with Pinyin and Mozc input methods.

  • Bitwarden Desktop Flatpak 2026.2.1 or newer, hyprpolkitagent, Polkit, and Howdy for optional vault unlock through system authentication.

  • Avizo volume/brightness helpers, Playerctl, Cliphist, wl-clipboard, wl-kbptr, Quickshell with HyprQuickFrame, and the screenshot tools used by that shell.

  • A Lua runtime for the vendored MamboColour API and repository checks. MamboColour itself is pinned and copied under vendor/mambocolour/; neither an adjacent provider checkout nor the former mbcolor command is an installation dependency. MamboFont is not an installation dependency.

The repository does not install system packages or enable services. manifest/packages.tsv records the reviewed Arch, foreign/AUR, and Flatpak applications for this workstation; manifest/services.tsv records intended system and user enablement. They are a host profile, not an unattended bootstrap or a minimal dependency list.

The host profile follows the official xdg-desktop-portal-hyprland Arch package. Do not reinstall the retired AUR -git package merely to match an older manifest.

Howdy's AUR python-dlib dependency links native image libraries. After a full system upgrade changes one of those ABIs, verify it before relying on face unlock:

python -c 'import dlib; print(dlib.__version__)'

If the import names a missing shared library, rebuild python-dlib against the upgraded system before testing Howdy again. Do not weaken the Hyprlock or Polkit PAM fallback to work around a broken native module.

Audit machine state

Run the read-only doctor before linking or after a system change:

./script/mambodot.sh doctor

It reports missing packages, packages installed from the wrong source class, disabled services, and bounded managed-dotfile drift. For dotfiles it checks known retired MamboColour links and missing or wrong links only for packages it can infer are currently or partially linked; intentionally unlinked packages and wholly absent packages are not assumed. It ignores extra software and never installs, removes, enables, starts, or stops anything. Review each reported row before changing another machine: entries such as SDDM autologin, SSH, SMB, VPN, NVIDIA, and ASUS laptop services are intentionally specific to this workstation.

After changing the repository layout, rerun ./script/mambodot.sh link <package> for every affected package, then run doctor again. The doctor is read-only and cannot repair links.

The profile excludes thermald, which reports this Ryzen platform as unsupported, and installed -debug split packages that are not runtime requirements. auto-cpufreq was removed after a twenty-day disabled soak confirmed that asusd alone keeps the selected ASUS profile and energy-performance preference stable. This is a single-owner reliability decision, not a controlled battery-life or performance comparison, and no efficiency improvement is claimed. The unsupported thermald package and its enabled but inactive service remain host state pending an explicit privileged cleanup decision. A dangling TLP enablement link also remains inert while TLP is absent; remove it before any TLP installation unless TLP is deliberately chosen to replace asusd. Do not install or enable auto-cpufreq, power-profiles-daemon, or TLP alongside asusd. After a profile change, wait ten seconds and verify every policy still reports the expected preference: power for Quiet, balance_power for Balanced, or performance for Performance. See the ASUS Linux Arch guide before changing ownership.

Review machine-specific values

Before installation, search the checkout for values tied to the maintainer's machine:

rg -n 'ProjectMambo/MamboDot|Windows|kohkohnut' dot script system manifest

At minimum, review the scale-1 display policy, wallpaper paths, the Windows boot entry, launch-preset applications, application commands in variables.lua, and any absolute home paths.

Clone into the expected path

The Hyprland modules currently derive resources from this exact checkout location:

git clone https://github.com/ProjectMambo/MamboDot.git "$HOME/ProjectMambo/MamboDot"
cd "$HOME/ProjectMambo/MamboDot"

Using another location requires updating the corresponding path configuration first.

Each direct child of dot/ is a Stow package. Prefer an explicit reviewed list:

./script/mambodot.sh link hypr ags script git kitty zsh

The command validates every name, previews the complete selection, and only applies it when the preview succeeds. It runs GNU Stow with --no-folding, so real parent directories contain leaf symlinks and applications may keep their untracked runtime files beside them. User Stow resource files are ignored, preventing a local .stowrc from silently changing this policy. Rerun the affected package's link command after repository layout changes; doctor reports drift but does not repair it.

Use all only after reviewing every package:

./script/mambodot.sh link all

Linking does not install packages, rebuild caches, reload Hyprland, source shell files, or start services. The hypr package also links the shell's systemd user units. After changing those unit files, run systemctl --user daemon-reload; a fresh login is the normal activation path.

Configuration coverage

Stow only intentional user preferences. Current ownership is deliberately narrower than all of ~/.config:

AreaTrackedDeliberately outside MamboDot
Hyprland and desktop shellHyprland, AGS, systemd user units for the shell lifecycle, scripts, Kitty, Avizo, HyprQuickFrame, and wl-kbptrRuntime sockets, logs, notification bodies, clipboard contents, and generated caches
EditorsNeovim configuration; Code OSS settings and reviewed extension IDs; FeatherPad preferences with recent-file persistence disabledCode chat/session storage, history, logs, machine IDs, authentication, and editor session history
Developer identityGit user identity, default branch, and credential-helper choice.git-credentials, gh/hosts.yml, tokens, SSH keys, and repository-local settings
File manager and desktop integrationDolphin preferences, metadata-field visibility, service-menu choices; KDE appearance and I/O policy; XDG MIME and portal defaultsKDE activities, global shortcuts owned by Hyprland, window/session state, trash state, and KDE Connect keys
InputFcitx5 profile, hotkeys, Pinyin, punctuation, notifications, and conversion preferences; the NordicMouse Sideway Input Remapper presetMozc history/databases, cached layouts, temporary files, learned input data, generated Xmodmap data, empty presets, and Input Remapper daemon state
NotesThe read-only AGS schedule integrationThe Obsidian vault and .obsidian, which remain owned by the Notes project
System and hardwareReviewed files under system/hosts/fa507xv/, including the NetworkManager Wi-Fi policy and narrow Bitwarden/Howdy Polkit policy; ROG Control Center foreground and tray preferencesWi-Fi credentials and connection profiles, generated asusd/supergfxd and ROG Aura/user state, raw sysfs controls, daemon databases, and broad /etc snapshots
Other applicationsFeh themes and visible launcher override; qimgv's colour theme; package presence is recorded in the manifestBitwarden vault/account state; qimgv version/window/cache state; browser/Electron profiles, credentials, cookies, caches, game state, and mixed runtime preference files remain local until a stable leaf file is reviewed

GTK theme selection is already owned by Hyprland's environment and KDE globals. The current GTK CSS files are stale generated Matugen output without tracked source templates, so duplicating them would make the repository less reproducible rather than more complete.

The tracked Git configuration preserves the current credential.helper=store choice but never tracks its payload. Git stores that helper's credentials unencrypted in the mode-600 ~/.git-credentials file; keep that file local, do not commit or sync it, and choose a different helper before using this profile on a machine where plaintext credential storage is inappropriate.

Resolve a conflict

An existing file at a managed path stops the whole selection. To import it deliberately:

  1. Compare the existing file with the tracked version.

  2. Copy only the reviewed content into the matching dot/<package>/ path.

  3. Inspect git diff and keep or discard that repository change deliberately.

  4. Back up or move the original home-directory file.

  5. Run link again.

Do not bypass this process with Stow's --adopt option.

Optional initialization

Code OSS extensions are an explicit, independent action:

./script/code-oss/install_extensions.sh

The extension command accepts no arguments, installs only IDs missing from the reviewed list, and stops if Code OSS cannot list or install extensions.

Colour boundary maintenance

The exact MamboColour source revision is c703092a619b3ee9b05503eaf2a553ae52595d35, recorded in vendor/mambocolour/REVISION. Hyprland loads that vendored Lua API directly and uses stable UI roles. Provider 0.3 eagerly validates both schemes and their paired accent keys and order while loading, exposes zero-based get(index) for direct colour positions, and keeps random_seeded(seed) in the shared u32 domain 0 through 4294967295. Hyprlock and AGS use two committed adapters owned by MamboDot; refresh or verify them separately from deployment:

lua script/sync_mambocolour.lua
lua script/sync_mambocolour.lua --check

The adapter script emits the dark UI roles and 12 deterministic numbered accents. It does not download a provider version or modify the vendored source. To update the dependency, copy the Lua module, all four palettes/mamboorche/*.csv files, and the upstream LICENSE from one reviewed MamboColour commit; update REVISION; run the adapter generator and ./script/test.sh; then inspect the complete diff. The detailed sequence is in the command reference.

Apply host-specific system policy

Files below system/hosts/ are root-owned machine policy, not Stow packages. Inspect and apply them individually. The FA507XV profile records SDDM autologin, Fcitx environment variables, the Hyprlock PAM addition, NetworkManager's Wi-Fi power policy, and the Bitwarden/Howdy system-authentication path:

diff -u /etc/sddm.conf system/hosts/fa507xv/etc/sddm.conf
diff -u /etc/environment system/hosts/fa507xv/etc/environment
diff -u /etc/pam.d/hyprlock system/hosts/fa507xv/etc/pam.d/hyprlock
diff -u /usr/lib/pam.d/polkit-1 system/hosts/fa507xv/etc/pam.d/polkit-1
diff -u /etc/systemd/system/polkit-agent-helper@.service.d/override.conf \
    system/hosts/fa507xv/etc/systemd/system/polkit-agent-helper@.service.d/override.conf
sed -n '1,80p' \
    system/hosts/fa507xv/etc/NetworkManager/conf.d/20-mambodot-wifi-powersave.conf
sed -n '1,80p' \
    system/hosts/fa507xv/usr/share/polkit-1/actions/com.bitwarden.Bitwarden.policy

After reviewing each diff, apply only the intended files:

sudo install --backup=numbered -D -m 0644 \
    system/hosts/fa507xv/etc/sddm.conf /etc/sddm.conf
sudo install --backup=numbered -D -m 0644 \
    system/hosts/fa507xv/etc/environment /etc/environment
sudo install --backup=numbered -D -m 0644 \
    system/hosts/fa507xv/etc/pam.d/hyprlock /etc/pam.d/hyprlock
sudo install --backup=numbered -D -m 0644 \
    system/hosts/fa507xv/etc/NetworkManager/conf.d/20-mambodot-wifi-powersave.conf \
    /etc/NetworkManager/conf.d/20-mambodot-wifi-powersave.conf
sudo install --backup=numbered -D -m 0644 \
    system/hosts/fa507xv/etc/pam.d/polkit-1 /etc/pam.d/polkit-1
sudo install --backup=numbered -D -m 0644 \
    system/hosts/fa507xv/etc/systemd/system/polkit-agent-helper@.service.d/override.conf \
    /etc/systemd/system/polkit-agent-helper@.service.d/override.conf
sudo install --backup=numbered -D -m 0644 \
    system/hosts/fa507xv/usr/share/polkit-1/actions/com.bitwarden.Bitwarden.policy \
    /usr/share/polkit-1/actions/com.bitwarden.Bitwarden.policy
sudo systemctl daemon-reload

The FA507XV profile keeps SDDM autologin and starts Hyprlock immediately. Hyprlock ignores an empty Enter used to wake the display, tries Howdy first, and falls back to the normal password stack. Hyprlock starts PAM only for non-empty submissions: use Space then Enter for a face-only attempt, or enter the password normally to try face recognition before password fallback. Autologin cannot provide a password to GNOME Keyring, so password fallback reuses the password already authenticated by Hyprlock to unlock the keyring. Face authentication cannot unlock that keyring because it supplies no password; after a face-only login, the first secret-using application may still request the keyring password.

Bitwarden's Flatpak requires its official host Polkit action before Unlock with system authentication can work. Use Bitwarden Desktop 2026.2.1 or newer: version 2026.1.0 submitted a Polkit process subject without a UID and failed before PAM or Howdy could open the camera; the upstream fix shipped in 2026.2.1. The tracked action grants only active local users an auth_self challenge. The polkit-1 PAM override tries Howdy first and falls back to the normal password stack, while the systemd drop-in exposes only Video4Linux devices to Polkit's sandboxed helper instead of the former unrestricted device policy. See Bitwarden issue 14263 for the Flatpak failure and fix.

After applying the policy, fully restart Bitwarden, unlock once with the master password or PIN, then enable File → Settings → Security → Unlock with system authentication for each account. Bitwarden generates and stores the account-specific unlock material itself; never copy or track its Flatpak data directory. On later locks in the same Bitwarden process, choose Unlock with system authentication. Linux Bitwarden cannot use system authentication for the first unlock after the application process starts, so Howdy cannot replace that initial master-password or PIN unlock. Password authentication remains available when Howdy fails. See Bitwarden's Linux biometric-unlock instructions.

The browser extension does not authenticate with Howdy independently. Its Unlock with biometrics action uses Bitwarden Desktop's native-messaging bridge, so the desktop process must be running, logged in, and already unlocked once with the master password or PIN after that process started. Enable desktop system authentication first, keep Allow browser integration enabled, then enable Unlock with biometrics in the extension. The bridge supports Firefox-family browsers such as Zen; accepting the extension's native-application permission is required.

The current Bitwarden release protects its in-memory vault key with Linux memfd_secret, which makes /sys/power/disk report [disabled] while Bitwarden runs. Because this workstation's root filesystem and swap file are not encrypted, do not force the mlock or keyctl compatibility backends: either would permit the vault key to enter the unencrypted hibernation image. MamboDot's Hibernate power action closes Bitwarden, waits up to ten seconds for the kernel to restore hibernation, and refuses with a clear error if another holder keeps it disabled; only then does it call systemctl hibernate. Reopen Bitwarden and perform the required first master-password or PIN unlock after resume. A direct systemctl hibernate still fails while Bitwarden is running. See Bitwarden issue 21661 for the upstream behavior.

Each install command leaves a numbered backup beside the target. Restore the appropriate backup from a TTY if login or Hyprlock authentication fails. Changes to SDDM and /etc/environment require a fresh login, preferably a reboot. Package upgrades may provide a .pacnew; compare it with the tracked policy before replacing either file.

The Wi-Fi policy applies NetworkManager's documented numeric value 2 to profiles that retain their default power setting. It was added after the RTL8852BE link showed power saving enabled, locally generated reason-4 reassociations, and gateway latency spikes, without driver crashes or packet loss in the sampled check. This is a reliability preference, not proof that every slowdown came from power saving, and it may use slightly more battery. After installation, apply it without storing any SSID, UUID, or credential in MamboDot:

nmcli general reload conf
nmcli device reapply wlp4s0
iw dev wlp4s0 get power_save

Expect Power save: off. Reconnect once if the live device cannot reapply the setting. Remove the drop-in, reload NetworkManager, and reconnect to restore NetworkManager's default.

Session environment

The active login path is SDDM → the standard Hyprland session → /usr/bin/start-hyprland → Hyprland's Lua startup → one dbus-update-activation-environment --systemd propagation.

OwnerResponsibility
SDDM's standard Hyprland desktop entrySession identity: XDG_CURRENT_DESKTOP, XDG_SESSION_DESKTOP, and XDG_SESSION_TYPE
variables.luaXDG base directories, Qt/GTK preferences, and the user-tool PATH for applications launched by Hyprland
exec.luaPropagate the environment, including PATH, once to D-Bus and the systemd user manager, then start mambodot-shell.target
Tracked /etc/environment host policyFcitx input-method variables
.zshenvApply the same user-tool path prefix to every Zsh, including TTY and SSH shells
.zshrcInteractive shell behavior only; it must not redefine the desktop or input method

UWSM is not installed or required. Do not select the optional Hyprland (uwsm-managed) session unless a later phase deliberately migrates the complete login lifecycle to UWSM.

The shared user-tool prefix is $HOME/.local/bin, $HOME/.npm-global/bin, $HOME/.cargo/bin, and $HOME/.local/share/JetBrains/Toolbox/scripts, followed by the inherited system path with duplicates removed.

A fresh login, preferably a reboot on the autologin host, is the complete way to apply environment changes. hyprctl reload updates future Hyprland-launched applications but cannot replace variables already inherited by the compositor or running services; the startup propagation updates future D-Bus and systemd user activations. After login, verify that every layer agrees and that KDE_SESSION_VERSION is absent:

loginctl show-session "$XDG_SESSION_ID" -p Desktop -p Type
printenv XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP XDG_SESSION_TYPE
systemctl --user show-environment |
    rg '^(PATH|XDG_CURRENT_DESKTOP|XDG_SESSION_DESKTOP|XDG_SESSION_TYPE|KDE_SESSION_VERSION)='

Displays

Hyprland applies one catch-all rule to every current or hot-plugged output: preferred mode, automatic placement, and scale 1. Output removal is handled by the compositor; no listener or external layout daemon is involved. Hyprpaper uses one empty-monitor fallback for every output, and floating-window size steps use the active monitor dimensions rather than a fixed resolution.

Reload Hyprland for layout and geometry changes. Hyprpaper reads its configuration at startup, so restart it or log in again before testing a changed fallback. Then run hyprctl monitors all, connect and disconnect each external display, and confirm placement, wallpaper, and floating-window controls. Review the catch-all rule if hardware needs a different scale, transform, or fixed placement.

AGS shell

The ags Stow package supplies the desktop UI: a per-monitor bar, Apps/Run/Windows/Power/Clipboard launcher, documentation-backed keybind sheet, two sidebars, and notification popups. The hypr package supplies its systemd user lifecycle. After propagating the Wayland environment, Hyprland starts mambodot-shell.target and stops it again during compositor shutdown; the target supervises Astal, AGS, and both Cliphist watchers. These units are deliberately not enabled under the user manager's default target.

Hypridle locks the session and stops AGS before suspend or hibernate, then starts a fresh AGS instance after resume. The service retries clean early exits and limits a frozen stop to three seconds, within logind's sleep-inhibitor window. Astal and Cliphist stay running. Hyprlock remains the secure lock client across sleep; its dynamic clock refreshes every second, so replacing the locker after resume is neither needed nor safe.

Astal is the sole owner of org.freedesktop.Notifications; the former Mako, Waybar, and Rofi packages and their Stow configuration are retired. Restart the supervised AGS service or use a fresh login if the UI needs recovery.

The left panel reads /proc, reviewed sysfs status, sensors, and nvidia-smi only while visible. It queries NVIDIA only when supergfxctl reports the dGPU active, avoiding a periodic wake-up while it sleeps. Firmware thermal profiles provide the safe quick fan control; the Advanced button opens ROG Control Center for deliberate curve editing. AGS never writes raw PWM, CPU-governor, boost, or TDP values, and it confirms every graphics-mode request because that change may require logout or reboot. It never performs that disruptive follow-up itself.

Display-brightness controls explicitly target the FA507XV's nvidia_wmi_ec_backlight device and keep the minimum at 1. The installed brightnessctl delegates writes to the active local session through systemd-logind's SetBrightness API, so root ownership of the raw sysfs attribute is expected; do not add a udev, sudoers, or extra Polkit rule. Keyboard-light levels and panel overdrive use supported asusctl interfaces without sudo. If writes fail, verify that asusd and systemd-logind are running and the session is active, local, and non-remote.

The Power launcher uses the fixed powermenu.sh action interface. AGS confirms every disruptive action; the direct backend is immediate. Restart to Windows is the only path that explicitly invokes pkexec, and reboot proceeds only after grub-reboot succeeds. If reboot fails after the one-shot entry is set, the backend clears that entry before reporting failure.

The eye button in the bar's right status group owns a logind idle inhibitor file descriptor, which Hypridle honors while remaining active. A warm button background means AGS still owns that descriptor, not merely that an earlier application request returned a cookie. The inhibitor defaults to on at every AGS start, including resume, and retries failed acquisition; click it off to close the descriptor and restore automatic idle locking. That choice lasts only until AGS restarts. Explicit lock, suspend, and hibernate actions still lock the session.

The launcher exposes every visible desktop application and the complete newest-first Cliphist database through a virtualized scrolling list. The text and image watchers raise Cliphist's retention ceiling from its 750-item default to 5,000 entries; the limit is applied by newly started watchers, not by AGS. Clipboard bodies remain in Cliphist's untracked cache database and can contain credentials or other sensitive material, so do not commit, sync, or back up that database without reviewing the privacy impact.

The right panel reads only today's Periodic/ note under MAMBO_NOTES_DIR or $HOME/ProjectMambo/notes. It uses the vault's unpadded ISO-week filename and still accepts legacy padded names, parses only ## Schedule rows shaped as - HH:mm - HH:mm event, and never creates, edits, or indexes vault files. Its notification history is process-local and intentionally does not persist bodies to disk.

systemctl --user stop mambodot-shell.target
./script/mambodot.sh unlink hypr kitty zsh
./script/mambodot.sh unlink all
systemctl --user daemon-reload

Stop the shell target before unlinking hypr, which owns its unit files. Unlinking previews the complete selection before removing managed links. It does not remove application-created runtime files, uninstall packages, or revert settings outside those links.

Verify

bash -n script/mambodot.sh script/test.sh script/code-oss/install_extensions.sh dot/script/.local/bin/powermenu.sh
shellcheck script/mambodot.sh script/test.sh script/code-oss/install_extensions.sh dot/script/.local/bin/powermenu.sh
./script/test.sh
./script/mambodot.sh doctor
find dot/hypr/.config/hypr -name '*.lua' -print0 | xargs -0 -n1 luac -p
Hyprland --verify-config --config "$PWD/dot/hypr/.config/hypr/hyprland.lua"
diff -u system/hosts/fa507xv/etc/sddm.conf /etc/sddm.conf
diff -u system/hosts/fa507xv/etc/environment /etc/environment
diff -u system/hosts/fa507xv/etc/pam.d/hyprlock /etc/pam.d/hyprlock
diff -u system/hosts/fa507xv/etc/pam.d/polkit-1 /etc/pam.d/polkit-1
diff -u system/hosts/fa507xv/etc/systemd/system/polkit-agent-helper@.service.d/override.conf \
    /etc/systemd/system/polkit-agent-helper@.service.d/override.conf
diff -u system/hosts/fa507xv/usr/share/polkit-1/actions/com.bitwarden.Bitwarden.policy \
    /usr/share/polkit-1/actions/com.bitwarden.Bitwarden.policy
diff -u system/hosts/fa507xv/etc/NetworkManager/conf.d/20-mambodot-wifi-powersave.conf \
    /etc/NetworkManager/conf.d/20-mambodot-wifi-powersave.conf
git diff --check
git status --short

The regression suite tests safe linking and unlinking, including the reviewed desktop packages, conflict handling, hostile Stow resource files, sorted machine manifests and doctor drift, the exact vendored MamboColour revision, both semantic adapters, stable UI roles and deterministic accents, strict Code OSS extension synchronization, the shared user-tool path, an AGS production bundle, all seven fixed power-action mappings and both restart-to-Windows failure paths, process-owned default idle inhibition, battery-alert state transitions, the persistent full-charge action, the FA507XV Wi-Fi and Bitwarden/Howdy host policies, the pre-sleep/post-resume AGS lifecycle, Hyprlock clock refresh, monitor-added workspace initialization, background-workspace attention state, multi-output launcher backdrop and mode-shortcut contracts, hardware telemetry parsers, AGS request grammar, the keybind, schedule, and binary-safe clipboard parser self-checks, systemd shell-unit ownership, monitor-relative sizing, the catch-all display and wallpaper rules, the focused Zoom annotation-toolbar rule, and key Lua helpers. The Hyprland command validates the complete configuration without changing the live session. Physically connect an external display and confirm it opens its first workspace while the original output retains focus and pointer position; then trigger an external browser sign-in, confirm the destination workspace stays highlighted, and visit it to clear the state. In Zoom, open the annotation or highlighter tools and hover their toolbars; confirm the auxiliary toolbar floats above the tiled meeting without reflowing it or losing clicks. Also test display removal, workspace hover/focus restoration, the keybind sheet, both AGS sidebars, all launcher modes, low-battery and rapid-AC warnings, idle inhibition in systemd-inhibit --list, notification popups/actions/do-not-disturb/history, text and image clipboard restoration, Howdy-backed Bitwarden unlock with password fallback, input methods, screenshots, media controls, and power actions individually before relying on them. A real hibernate remains deliberate manual validation: after resume, confirm the lock shows current time, the bar and ags request respond without a refresh, and exactly one AGS instance is active. Logout, sleep, restart, Windows boot selection, and shutdown are not triggered by the suite.