From e471bfe83ee02680d17e7a7043b5f3e8186d40f8 Mon Sep 17 00:00:00 2001 From: Breadway Date: Tue, 16 Jun 2026 15:51:47 +0800 Subject: [PATCH] docs+test: ecosystem matrix, keybinds, limitations, recovery, smoke test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README: add a bread-ecosystem feature matrix, keyboard-shortcut reference, a Known Limitations section (NVIDIA/Mesa, VM GPU accel, Secure Boot, btrfs assumption), and a Recovery guide (snapshot rollback + GRUB/EFI repair from the live ISO). scripts/smoke-test.sh: read-only post-install validator — btrfs subvolumes, snapper config, enabled services, bread bins on PATH, bos-settings, default dotfiles, and the GRUB EFI artifacts. Exits non-zero on any failure. Co-Authored-By: Claude Opus 4.8 --- README.md | 80 +++++++++++++++++++++++++++++++++++++++++++ scripts/smoke-test.sh | 68 ++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100755 scripts/smoke-test.sh diff --git a/README.md b/README.md index a70fef3..930804c 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,86 @@ cargo build --release -p bos-settings cargo test -p bos-settings # includes config round-trip tests ``` +## The bread ecosystem at a glance + +| Tool | Role | Launch | +|------|------|--------| +| `bread` / `breadd` | Reactive automation daemon — normalises hardware/compositor signals into events dispatched to Lua modules | runs at login | +| `breadbar` | Top status bar (workspaces, clock, stats, tray) **and** the notification daemon | runs at login | +| `breadbox` | Application launcher | `SUPER+Space` | +| `breadpad` | Notes & reminders (AI-classified, optional CalDAV sync) | `SUPER+U` | +| `breadman` | Package-manager UI | `SUPER+M` | +| `breadcrumbs` | Wi-Fi profile state machine (location-aware) | CLI / BOS Settings | +| `bakery` | CLI package manager for the ecosystem | `bakery` | +| `bos-settings` | Unified GTK4 control panel for all of the above + snapshots + updates | `SUPER+,` | + +## Keyboard shortcuts + +`SUPER` is the Windows/Cmd key. Press **`SUPER+/`** at any time for this +cheatsheet in-session; first boot shows a short welcome (once). + +| Keys | Action | +|------|--------| +| `SUPER+Return` | Terminal (kitty) | +| `SUPER+Space` | App launcher (breadbox) | +| `SUPER+E` / `SUPER+B` | Files (nautilus) / Browser (zen) | +| `SUPER+U` / `SUPER+M` | breadpad / breadman | +| `SUPER+,` / `SUPER+/` | BOS Settings / keybind cheatsheet | +| `SUPER+L` / `SUPER+N` | Lock / log out | +| `SUPER+Backspace` | Close window | +| `SUPER+F` / `SUPER+V` / `SUPER+T` | Fullscreen / float / toggle split | +| `SUPER+Shift+V` | Clipboard history | +| `SUPER+Tab` | Last window | +| `SUPER+Shift+S/C/P` | Screenshot region→file / region→clipboard / screen→file | +| `SUPER+arrows` | Move focus | +| `SUPER+Shift+h/j/k/l` | Move window | +| `SUPER+Shift+arrows` | Resize window | +| `SUPER+1..0` | Switch to workspace 1–10 | +| `SUPER+Shift+1..0` | Move window to workspace | +| `SUPER+[ / ]` | Previous / next workspace | +| `SUPER+left/right-drag` | Move / resize window with the mouse | + +## Known limitations + +- **GPUs**: ships the generic Mesa stack — AMD and Intel work out of the box. + The **NVIDIA proprietary driver is not included**; NVIDIA users must install + `nvidia`/`nvidia-utils` and set the usual Hyprland env vars after install. +- **Virtual machines**: Hyprland needs GPU acceleration to be smooth. Use + `virtio-vga-gl` + `-display gtk,gl=on` (virgl); plain software rendering is + noticeably laggy. +- **Wayland-first**: X11-only apps run through XWayland; a few may misbehave. +- **Secure Boot**: not configured. Boot with Secure Boot disabled, or enroll + your own keys. The installer writes both an NVRAM entry and the removable + `EFI/BOOT/BOOTX64.EFI` fallback. +- **Snapshots assume btrfs**: the snapper/grub-btrfs tooling expects the default + btrfs subvolume layout the installer creates. + +## Recovery + +**An update broke something (system still boots):** open BOS Settings → +Snapshots and roll back, or pick a pre-update snapshot from the **GRUB +“snapshots” submenu** at boot, then run `snapper rollback` from the booted +snapshot. + +**The system won't boot (broken GRUB / lost EFI entry):** + +1. Boot the BOS ISO and open a terminal (`SUPER+Return`). +2. Mount the installed root and EFI, then chroot: + ```sh + mount -o subvol=@ /dev/sdXN /mnt + mount /dev/sdXP /mnt/boot/efi # the EFI partition + arch-chroot /mnt + ``` +3. Reinstall the bootloader (the same sequence the installer uses): + ```sh + grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=BOS --recheck + grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck + grub-mkconfig -o /boot/grub/grub.cfg + ``` + +**Firmware shows “no boot device”:** select `EFI/BOOT/BOOTX64.EFI` from the +firmware boot menu — the installer always writes that removable fallback. + ## Boot architecture notes archiso keeps the kernel and initramfs outside the squashfs, so the installer diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh new file mode 100755 index 0000000..a551253 --- /dev/null +++ b/scripts/smoke-test.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# BOS post-install smoke test. +# +# Run this INSIDE a freshly installed BOS (as the main user) to assert the +# install's core invariants. It is read-only and safe to run any time. +# +# ./smoke-test.sh +# +# Exit status is non-zero if any check fails, so it can gate CI / manual QA. +set -uo pipefail + +pass=0 fail=0 +ok() { printf ' \033[32mPASS\033[0m %s\n' "$1"; pass=$((pass+1)); } +bad() { printf ' \033[31mFAIL\033[0m %s\n' "$1"; fail=$((fail+1)); } +note() { printf ' \033[33m----\033[0m %s\n' "$1"; } + +check() { if eval "$2" >/dev/null 2>&1; then ok "$1"; else bad "$1"; fi; } + +echo "== btrfs subvolume layout ==" +if command -v btrfs >/dev/null; then + # `btrfs subvolume list` needs root; try unprivileged, fall back to non- + # interactive sudo (no hang if creds aren't cached). + paths="$(btrfs subvolume list / 2>/dev/null || sudo -n btrfs subvolume list / 2>/dev/null)" + paths="$(awk '{print $NF}' <<<"$paths")" + if [ -z "$paths" ]; then + note "couldn't list subvolumes (need root) — skipping" + else + for sv in @ @home @snapshots @log @cache; do + if grep -qx "$sv" <<<"$paths"; then ok "subvolume $sv present"; else bad "subvolume $sv missing"; fi + done + fi +else + note "btrfs not installed (not a btrfs root?) — skipping subvolume checks" +fi + +echo "== snapshot tooling ==" +check "snapper root config exists" "[ -f /etc/snapper/configs/root ]" +check "snap-pac hook present" "pacman -Qq snap-pac" +check "grub-btrfs present" "pacman -Qq grub-btrfs" + +echo "== enabled system services ==" +for unit in NetworkManager.service greetd.service bluetooth.service tlp.service \ + cups.socket avahi-daemon.service ufw.service systemd-timesyncd.service; do + check "$unit enabled" "systemctl is-enabled $unit" +done +check "graphical.target is default" "[ \"\$(systemctl get-default)\" = graphical.target ]" + +echo "== bread ecosystem on PATH ==" +for bin in bakery bread breadd breadbar breadbox breadbox-sync breadcrumbs breadpad breadman; do + check "$bin found" "command -v $bin" +done + +echo "== bos-settings ==" +check "bos-settings installed" "command -v bos-settings" + +echo "== default dotfiles ==" +check "hyprland.lua present" "[ -f \"\$HOME/.config/hypr/hyprland.lua\" ]" +check "mimeapps.list present" "[ -f \"\$HOME/.config/mimeapps.list\" ]" +check "kitty config present" "[ -f \"\$HOME/.config/kitty/kitty.conf\" ]" + +echo "== bootloader (EFI) ==" +check "GRUB EFI binary present" \ + "[ -f /boot/efi/EFI/BOS/grubx64.efi ] || [ -f /boot/efi/EFI/BOOT/BOOTX64.EFI ]" +check "grub.cfg present" "[ -f /boot/grub/grub.cfg ]" + +echo +printf 'Result: \033[32m%d passed\033[0m, \033[31m%d failed\033[0m\n' "$pass" "$fail" +[ "$fail" -eq 0 ]