No description
Find a file
Breadway a21e81476f Align ISO bake and docs with bakery/Tauri product story
Derive BREAD_BINS from iso/bread-lockfile.toml and fail the bake when a
listed binary or breadhelp content is missing. Bake bakery share files
and drop breadcast from the copied installed.json. Add WebKitGTK 4.1 for
Tauri bos-settings, remove rustup, and rewrite README/DESIGN to match the
ISO+skel tree.
2026-08-15 21:40:55 +08:00
.forgejo/workflows CI: fast-forward a stable branch to the latest release tag 2026-07-31 11:14:12 +08:00
assets v0.4.0: branding refresh, breadpaper baked in, bos-settings 0.4.0 2026-06-18 14:50:44 +08:00
dotfiles Align ISO bake and docs with bakery/Tauri product story 2026-08-15 21:40:55 +08:00
iso Align ISO bake and docs with bakery/Tauri product story 2026-08-15 21:40:55 +08:00
packaging Align ISO bake and docs with bakery/Tauri product story 2026-08-15 21:40:55 +08:00
scripts Align ISO bake and docs with bakery/Tauri product story 2026-08-15 21:40:55 +08:00
.gitignore can't be bothered writing a commit message 2026-07-29 21:18:28 +08:00
build-local.sh Align ISO bake and docs with bakery/Tauri product story 2026-08-15 21:40:55 +08:00
DESIGN.md Align ISO bake and docs with bakery/Tauri product story 2026-08-15 21:40:55 +08:00
KEYS.asc Ship yay, wire up LUKS disk encryption, self-signed Secure Boot, release signing 2026-07-04 10:39:44 +08:00
LICENSE Add bakery.toml and packaging/arch to match bread ecosystem 2026-06-13 11:32:40 +08:00
README.md Align ISO bake and docs with bakery/Tauri product story 2026-08-15 21:40:55 +08:00

BOS — Bread Operating System

An Arch-based, Hyprland desktop distribution that ships the bread ecosystem preconfigured. One Calamares install produces a themed, bootable Wayland desktop — no manual Arch bootstrap, no wiring up dotfiles, no per-tool bakery installs.

This file is the product as the tree ships it. DESIGN.md is the original plan, kept as history — several of its sections (in-tree GTK bos-settings, bakery-at-post-install, A/B as if it were current) are not how the ISO works today.

What you get

  • Compositor: Hyprland with a native-Lua config (hyprland.lua), curated keybinds, snappy animations, blur, and pywal-driven colours on a black base.
  • bread ecosystem, baked into /etc/skel from bakery-managed binaries (no network needed at install time): the bread/breadd automation daemon plus bread-emit / bread-module-host, breadbar (status bar + notifications), breadbox (launcher), breadclip (clipboard history), breadcrumbs (Wi-Fi profiles), breadpad/breadman (notes), breadpaper (wallpaper + theme), breadsearch (system search), breadmon (monitor layout TUI), breadshot (screenshots), bread-theme (the shared palette engine), breadhelp (onboarding + cheatsheet), bos-settings (control panel), and the bakery package manager. Most of those apps are zero-config on first boot; breadcrumbs networks are user-filled after install. See below.
  • breadlock (lock screen + greeter) is the one bread* app that ships as pacman, not bakery — it needs a root-owned PAM service.
  • bos-settings: a Tauri 2 + Svelte control panel (standalone bakery product, not a member of this repo). Configures every bread* app non-destructively, plus snapshots, bakery/pacman updates, and day-to-day machine administration.
  • Login: greetd + breadgreet (under cage) → Hyprland session.
  • Boot splash: Plymouth bos theme (logo + spinner, black background).
  • Theming: global dark across GTK3 (Adwaita-dark), GTK4/libadwaita (color-scheme: prefer-dark), and Qt (qt5ct/qt6ct Fusion dark); Papirus-Dark icons; Bibata cursor.
  • Apps: kitty, nautilus (+ gvfs), Zen browser, VLC, loupe, gnome-text-editor, gnome-calculator, file-roller, with file associations wired in mimeapps.list. yay ships for AUR access beyond bakery + [breadway].
  • Hardware: pipewire audio, NetworkManager, BlueZ + blueman, CUPS printing with avahi mDNS discovery, TLP power management, fwupd firmware updates.
  • Resilience: btrfs + snapper + snap-pac + grub-btrfs snapshots on every pacman transaction; zram swap; ufw firewall (deny-incoming, mDNS allowed).
  • Security: full-disk encryption (LUKS, via Calamares' built-in support — cryptsetup + the matching mkinitcpio/GRUB wiring ship so an encrypted install actually boots) and self-signed Secure Boot (via sbctl, enrolled automatically at install time when the firmware is in Setup Mode).

What ships vs what does not

Channel What
Bakery, baked into skel bakery, bread / breadd / bread-emit / bread-module-host, breadbar, breadbox / breadbox-sync, breadcrumbs, breadpad / breadman, breadpaper, bread-theme, breadmon, breadsearch / breadmill, breadclip / breadclipd, breadshot, bos-settings, breadhelp (+ breadhelp content under ~/.local/share/breadhelp/)
pacman (packages.x86_64) breadlock, plus the rest of the distro (Hyprland, Calamares, Zen, …)
Not shipped breadcast, breadarr

The baked name list is iso/bread-lockfile.toml. build-local.sh fails if any listed binary is missing on the builder.

Repo layout

This is an ISO + Calamares + skel repo. There is no Cargo workspace and no bos-settings/ member — bos-settings and breadhelp live in their own repos and arrive via bakery.

bos/
├── iso/                           # archiso profile
│   ├── bread-lockfile.toml        # bakery bins that MUST be baked
│   ├── profiledef.sh
│   ├── packages.x86_64            # live + installed pacman set
│   └── airootfs/                  # files overlaid onto the image
│       └── etc/
│           ├── skel/              # live user defaults (hypr, kitty, gtk, …)
│           └── calamares/         # installer config + post-install.sh
├── packaging/                     # in-house PKGBUILDs for AUR-only deps
│   ├── calamares/
│   ├── bibata/
│   ├── powerlevel10k/
│   └── yay-bin/
├── dotfiles/                      # STALE — not the live skel; see its README
├── scripts/smoke-test.sh
├── .forgejo/workflows/            # CI: AUR republish + tagged ISO release
├── build-local.sh                 # native ISO build for this machine
├── README.md
└── DESIGN.md                      # historical plan

Live binds are iso/airootfs/etc/skel/.config/hypr/binds.json (Super+Lloginctl lock-session, breadshot on Super+Shift+S/C/P, Super+U breadpad). Do not treat dotfiles/hypr/keybinds.conf as current.

Branches and remotes

Single-trunk: work on main via short-lived feature/* / fix/* branches. stable is a marker branch CI fast-forwards to the latest non-RC release tag — do not land work there by hand.

Dual remotes:

  • origin — Forgejo (ssh://git@100.66.238.26:2222/Breadway/bos.git), authoritative
  • github — GitHub (https://github.com/Breadway/bos.git) mirror

Push origin (and github when mirroring). Do not treat origin as GitHub.

Building the ISO

build-local.sh builds the image natively (no container) and bakes this machine's bakery-installed bread binaries + breadhelp content into /etc/skel:

sudo ./build-local.sh              # release-quality (xz squashfs)
sudo FAST_BUILD=1 ./build-local.sh # fast dev iteration (zstd squashfs)

The ISO lands in out/bos-<date>-x86_64.iso. The script pins SOURCE_DATE_EPOCH (reproducible UUIDs), rewrites the [breadway] repo URL to the Tailscale-reachable Forgejo registry for the build, and exits non-zero if any lockfile binary (or breadhelp content) is missing.

CI should populate the builder from the stable bakery index; local builds still snapshot the builder. The lockfile is names only.

Why some packages are in-house

calamares, zen-browser-bin, bibata-cursor-theme, and yay-bin are AUR-only. BOS keeps a PKGBUILD for each under packaging/ and republishes the built package to the [breadway] repo via a Forgejo Actions workflow (built on the hestia self-hosted runner, published with a scoped registry token). [breadway] is not where bakery/breadbar/bos-settings live.

Verifying a release

Every tagged release ISO on the Forgejo releases page ships alongside a SHA256SUMS file and a detached signature SHA256SUMS.asc, signed by a dedicated release-signing key (not reused from anything else):

5620 3B86 A110 695A E7F3  1093 4AF3 323D 678E B5E2

The public half is committed at KEYS.asc. To verify a download:

gpg --import KEYS.asc
gpg --verify SHA256SUMS.asc SHA256SUMS
sha256sum -c SHA256SUMS

Testing in a VM

A reusable, GPU-accelerated launcher lives at ~/bos-vm/run.sh:

~/bos-vm/run.sh install   # boot the ISO installer (target disk attached)
~/bos-vm/run.sh           # boot the installed system from the disk

It uses KVM + -cpu host, 8 GiB / 8 vCPU, and virtio-vga-gl with -display gtk,gl=on (virgl) — 3D acceleration is essential for a smooth Hyprland session in QEMU. The disk lives on NVMe (not the tmpfs /tmp) to avoid memory pressure.

Post-install, scripts/smoke-test.sh (run as the installed user) checks subvolumes, services, bakery bins, and breadhelp content under ~/.local/share/breadhelp/content.

bos-settings

Standalone bakery product: Tauri 2 + Svelte, not GTK4, and not built from this repo. Install/update with bakery; the ISO just bakes whatever binary the builder has.

It aims for GNOME-Settings-style parity: live system state and control, so day-to-day administration doesn't require a terminal. Bread-ecosystem configs are edited non-destructively (comments and unmodeled keys stay). Panels with a daemon (bread, breadbox, breadcrumbs, breadsearch, breadclip) also get live systemd status + Start/Stop/Restart/Logs.

Panel What it does
About System info (OS/kernel/CPU/GPU/memory/disk/uptime) + hostname
Network Wi-Fi scan/connect, Ethernet status, radio toggle
Wi-Fi Profiles (breadcrumbs) breadcrumbs.toml — settings, saved networks, profiles
Firewall ufw rules: enable/disable, add/remove, view active rules
Sound PipeWire output/input device + volume via pactl
Power Battery status/health, brightness, charge limits (hardware-dependent), TLP profile (read-only)
Date & Time Timezone, NTP sync toggle
Display (Hyprland) Connected monitors + open hyprland.lua in editor
Users Add/remove accounts, change passwords
Wallpaper (breadpaper) Set wallpaper, drives the pywal-derived accent palette
Bar (breadbar) breadbar/style.css override, live-reloads on save
Launcher (breadbox) breadbox/config.toml — launcher contexts
Clipboard (breadclip) breadclipd service control + "open history"
Notes (breadpad) breadpad/breadpad.toml — settings, model + ollama, reminders, calendar
File Search (breadsearch) breadsearch/config.toml — index/search/model + breadmill service
Daemon (bread) breadd.toml — daemon, lua, modules, adapters, events, notifications
Packages bakery installed list + updates, pacman system update
AUR Search via yay; installing opens a terminal (AUR build scripts need review)
Firmware fwupd device list + updates
Snapshots snapper list / boot-into (grub-btrfs) / delete

Source and build live in the bos-settings repo, not here.

The bread ecosystem

Everything below is a separate bakery-distributed project with its own repo and release cadence, baked into /etc/skel at ISO build time so a fresh install has them all with no network round-trip. Some ship more than one binary from a single package — that's noted where it applies. Most have a corresponding bos-settings panel; this table is about using the app directly.

Desktop shell

Tool Role Launch
bread / breadd Reactive automation daemon — normalises hardware/compositor/power/network signals into events dispatched to Lua modules (~/.config/bread/). bread-emit is the fire-and-forget helper hooks/CLIs use; bread-module-host is the sandboxed out-of-process module runtime breadd spawns. runs at login (breadd.service)
breadbar Top status bar: workspaces, clock, system stats, tray, and the notification daemon — one process, not two runs at login
breadbox Application launcher (fuzzy search, per-context results via breadbox-sync) SUPER+Space
breadlock Idle lock screen. Also provides breadgreet, the login greeter hosted under cage via greetd — same project, two binaries, one visual identity from login to lock. pacman, not bakery. SUPER+L (via loginctl lock-session, picked up by hypridle); breadgreet runs automatically at boot
bread-theme The shared palette engine every bread app renders through: fixed dark base colors, with only the accent slots following the current wallpaper's pywal palette. bread-theme generate regenerates the stylesheet; hyprland.lua calls it automatically on wallpaper change. invoked automatically, rarely run by hand

Productivity

Tool Role Launch
breadpad Quick-capture scratchpad/notes popup with AI classification and optional CalDAV calendar sync SUPER+U
breadman The fuller notes manager view (browse/organize) — ships from the same breadpad package as a second binary SUPER+M
breadclip Clipboard history. breadclipd is the background daemon that actually records history; breadclip is the GTK4 popup that browses it SUPER+V / SUPER+Shift+V
breadsearch Semantic system-wide search (indexes files/notes, embeds locally — CPU/ROCm/CUDA backend configurable). breadmill is its indexing daemon. via breadbox, or BOS Settings → File Search
breadhelp Onboarding + in-session help/cheatsheet. Content lives at ~/.local/share/breadhelp/content (bakery content.tar.gz, baked into skel). SUPER+/

System

Tool Role Launch
breadcrumbs Location-aware Wi-Fi profile state machine, with optional Tailscale integration — switches network behavior based on which saved network you're on CLI, or BOS Settings → Wi-Fi Profiles
breadpaper Wallpaper manager — sets the wallpaper via awww, generates the pywal accent palette from it, and reloads every bread-theme app BOS Settings → Wallpaper
breadmon TUI monitor layout manager (resolution/position/scaling) — the interactive counterpart to BOS Settings' read-only Display panel breadmon in a terminal
breadshot Screenshot utility wrapping grim/slurp/wl-copy with Hyprland-aware geometry (multi-monitor-safe region select) breadshot, or SUPER+Shift+S/C/P

Tooling

Tool Role Launch
bakery CLI package manager for the whole ecosystem — install/update/list, tracks installed binaries + versions independently of pacman bakery
bos-settings Unified Tauri 2 + Svelte control panel: live system state + control (network, power, firewall, users, packages, firmware, AUR, snapshots) plus non-destructive config editing for every app above 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 Notes (breadpad) / notes manager (breadman)
SUPER+, / SUPER+/ BOS Settings / keybind cheatsheet
SUPER+L / SUPER+N Lock / log out
SUPER+Backspace Close window
SUPER+F Fullscreen
SUPER+I Toggle floating
SUPER+P Toggle pseudotile
SUPER+R Resize mode
SUPER+T Toggle split direction
SUPER+V / SUPER+Shift+V Clipboard history (breadclip)
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 110
SUPER+Shift+1..0 Move window to workspace
SUPER+[ / ] Previous / next workspace
SUPER+Shift+[ / ] Move window to previous / next workspace
SUPER+scroll Cycle workspaces
SUPER+left/right-drag Move / resize window with the mouse
Volume / brightness / play-pause / next / prev Media keys — work even on the lock screen
Calculator key Opens gnome-calculator

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: self-signed only, via sbctl — BOS can't ship a Microsoft-signed shim (that needs going through Microsoft's own paid UEFI CA process). Post-install enrolls BOS's own keys automatically, but only when the firmware is already in Setup Mode (no vendor keys installed yet); otherwise it's skipped and you can run sudo sbctl enroll-keys --microsoft && sudo sbctl sign-all -g yourself later (after clearing your firmware's existing keys, if any). The installer writes both an NVRAM entry and the removable EFI/BOOT/BOOTX64.EFI fallback either way.
  • Disk encryption: full-disk LUKS is available on the installer's "Erase disk" page (Calamares' own checkbox) and on manually-created partitions — BOS ships the matching cryptsetup/mkinitcpio/GRUB wiring so an encrypted install actually boots (LUKS1, since GRUB doesn't support LUKS2 + Argon2id).
  • 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 pick a snapshot to boot, or choose one from the GRUB “snapshots” submenu (grub-btrfs) at boot, then reboot into it.

Do not run snapper rollback as the default recovery step. BOS GRUB pins rootflags=subvol=@, so a snapper-swapped default subvolume is not what the installed grub.cfg will boot next. Use the grub-btrfs entry so the kernel command line matches the snapshot you want.

A/B root swapping (SteamOS-style) is a future idea in DESIGN.md — it is not shipped.

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:
    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):
    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 stages them explicitly: a shellprocess@kernel step copies the kernel + ucode into the target /boot and writes a stock mkinitcpio preset before the native initcpio module builds the initramfs. GRUB is not installed by Calamares' bootloader/grubcfg modules (they leave the ESP empty in this layout) — post-install.sh runs grub-install (NVRAM and --removable) + grub-mkconfig instead, which is the sequence verified to boot.