# Clawdie Operator USB Testing Guide **Branch:** `xfce-operator-usb` **Target artifact:** `clawdie-quindecim-0.10.0.img` **Current desktop path:** XFCE via SDDM, interactive login as `clawdie` --- ## Overview The current branch ships a **live operator USB**. Testing should answer three questions: 1. Does the built image contain the expected live-session payload? 2. Does it boot to XFCE on representative hardware? 3. Do the operator tools work without `sudo`, using `mdo` where elevation is needed? The most important runtime path is: ```text USB boot -> rc.conf starts dbus + sddm -> /usr/local/etc/rc.d/clawdie_live_gpu runs before sddm -> SDDM greeter; operator logs in as clawdie / quindecim -> clawdie-xfce session launches XFCE ``` The live operator USB uses SDDM with interactive login. Autologin is intentionally not part of the current operator-USB plan. --- ## Level 1: Static Artifact Verification Run this on the FreeBSD build host after `build.sh` finishes. ### What to verify - `/etc/rc.conf` contains: - `hostname="clawdie-live"` - `root_rw_mount="YES"` - `tmpmfs="NO"` - `varmfs="NO"` - `dumpdev_enable="NO"` - `sshd_enable="YES"` - `avahi_daemon_enable="YES"` - `pf_enable="YES"` - `sddm_enable="YES"` - `display_manager="sddm"` - `clawdie_live_gpu_enable="YES"` - `linux_enable="YES"` - `zfs_enable="YES"` - `kld_list="linux linux64 zfs"` - `/etc/fstab` mounts `/dev/ufs/FreeBSD_Install` at `/` with `rw`, not `ro` - `/etc/fstab` adds tmpfs for `/tmp` and `/var/log`, while `/var/tmp` stays on disk - `/etc/fstab` contains no swap entries (no USB write wear, predictable behaviour under memory pressure) - SDDM live config exists, does not configure autologin, and keeps `Numlock=off` for compact laptop keyboards - base `sshd` includes `/etc/ssh/sshd_config.d/*.conf` and the live drop-in disables password and root login - `/etc/nsswitch.conf` resolves hosts with `mdns_minimal` - `/etc/pf.conf` exists and has no `log` rules - `/usr/local/etc/rc.d/clawdie_live_gpu` exists - `/usr/local/etc/rc.d/clawdie_live_wifi` exists - `/usr/local/etc/rc.d/clawdie_live_seed` exists - `/usr/local/etc/rc.d/clawdie_live_power` exists and applies the `power_profile` C-state policy once at boot - `/usr/local/etc/rc.d/clawdie_tailscale_up` exists - `/usr/local/etc/rc.d/clawdie` is absent on baseline live USB builds; `service clawdie` is reserved for deployed disk/server targets - `/usr/local/etc/polkit-1/rules.d/49-clawdie-power.rules` exists - XKB files exist, especially `.../xkb/keycodes/xfree86` - XKB parent directories are traversable and `/var/lib/xkb` is writable for rootless Xorg cache generation - `/tmp` and `/var` are not hidden by stock installer tmpfs overlays - `/home/clawdie/.cache` is a symlink to `/tmp/clawdie/cache` - `networkmgr` is installed without `sudo` - `avahi-app`, `nss_mdns`, and `mousepad` are installed - `wifi-firmware-kmod` and `FreeBSD-fwget` are installed - `webcamd`, `v4l-utils`, `pwcview`, `hw-probe`, and `p5-libwww` are installed - `gpu-firmware-amd-kmod-renoir` and `gpu-firmware-amd-kmod-green-sardine` are installed (Ryzen iGPU coverage) - `webcamd` group exists and `clawdie` is a member - `webcamd_enable="YES"` and `clawdie_live_wifi_enable="YES"` in `/etc/rc.conf` - `clawdie_live_seed_enable="YES"` and `clawdie_live_power_enable="YES"` in `/etc/rc.conf` - `kld_list` includes `cuse`, `hidbus`, `iichid`, `hms`, `hmt`, `hkbd`, `acpi_video`, `acpi_asus`, `acpi_asus_wmi` - `sudo` is not installed in the image - Image partition table has three slices: `s1` EFI 64M, `s2` FreeBSD, `s3` FAT32 64M labeled `CLAWDIESEED` - `CLAWDIESEED` slice mounts cleanly as msdosfs and contains `README.txt` describing the seed contract - `/usr/local/share/wayland-sessions/` contains no `.desktop` files (SDDM must not offer a Wayland session — no working Wayland stack on the live image) - All installed XFCE panel plugins must have satisfied shared-library dependencies (`ldd` on each `.so` must report zero "not found") - `gstreamer1-plugins-good` is installed (provides the GStreamer→OSS bridge required by `xfce4-mixer` to detect sound cards on FreeBSD) - `/usr/local/etc/X11/xorg.conf.d/40-clawdie-noblank.conf` exists and disables Xorg blanking + DPMS at server level (BlankTime/StandbyTime/SuspendTime/OffTime all `"0"`) - `~clawdie/.xprofile` contains `xset -dpms` and starts `clawdie-noblank-guard.sh` as a session-level belt-and-suspenders fallback - `/usr/local/bin/clawdie-noblank-guard.sh` and its XFCE autostart desktop file exist; the guard reapplies no-blank/no-DPMS after xfsettingsd or xfce4-power-manager starts - `xfce4-power-manager.xml` seeds display blanking, DPMS, idle sleep, and lock-on-suspend off for the live user and XDG defaults - CPU power management: - `powerdxx` package is installed (drop-in replacement for base `powerd` with moving-average load sampling) - `powerdxx_enable="YES"` and `powerdxx_flags="-a hiadaptive -b adaptive -n adaptive"` in `/etc/rc.conf` - `powerd_enable="YES"` MUST NOT be present (both daemons share a pidfile; one would fail to start) - `performance_cx_lowest="C3"` and `economy_cx_lowest="C3"` in `/etc/rc.conf` — enables useful idle saving without Cmax/C6-style USB-root resume risk - `hw.usb.no_suspend="1"` in `/boot/loader.conf` — avoids USB autosuspend while the root filesystem is on USB - `/opt/clawdie/npm-global` is recursively owned by `clawdie:clawdie` (build fails loud if not — chown runs at end of `install_live_npm_globals`) - Agent CLI policy on the live image: - `codex` is installed via FreeBSD pkg and the binary is in `/usr/local/bin/codex` - `pi` is installed via the bundled npm tarball and symlinked into `/usr/local/bin/pi` - `gemini` MUST NOT be present on the live image - `claude` MUST NOT be present on the live image (skipped during `install_live_npm_globals`; native deps have no FreeBSD binary, broken CLI is worse UX than no CLI) ### Useful verification commands ```sh sudo mdconfig -a -t vnode -f tmp/output/clawdie-quindecim-0.10.0.img sudo mount -o ro /dev/md0s2a /mnt egrep 'hostname|root_rw_mount|tmpmfs|varmfs|sshd|avahi|powerd|powerdxx|pf_enable|sddm|display_manager|clawdie_live_gpu|clawdie_tailscale_up|linux_enable|zfs_enable|kld_list' /mnt/etc/rc.conf grep -E '^hostname="clawdie-live"' /mnt/etc/rc.conf grep -E '^[[:space:]]*(127\.0\.0\.1|::1)[[:space:]].*clawdie-live' /mnt/etc/hosts grep -E '^tmpmfs="NO"' /mnt/etc/rc.conf grep -E '^varmfs="NO"' /mnt/etc/rc.conf grep -E '^[[:space:]]*/dev/ufs/FreeBSD_Install[[:space:]]+/[[:space:]]+ufs[[:space:]]+.*rw' /mnt/etc/fstab grep -E '^[[:space:]]*tmpfs[[:space:]]+/tmp[[:space:]]+tmpfs' /mnt/etc/fstab grep -E '^[[:space:]]*tmpfs[[:space:]]+/var/log[[:space:]]+tmpfs' /mnt/etc/fstab ! grep -E '^[[:space:]]*[^#].*[[:space:]]swap[[:space:]]' /mnt/etc/fstab grep -E '^dumpdev_enable="NO"' /mnt/etc/rc.conf grep -E '^hosts:.*mdns_minimal.*dns.*mdns' /mnt/etc/nsswitch.conf cat /mnt/usr/local/etc/sddm.conf.d/50-clawdie-live.conf grep -E '^Numlock=off' /mnt/usr/local/etc/sddm.conf.d/50-clawdie-live.conf test ! -e /mnt/home/clawdie/.dmrc if chroot /mnt /usr/sbin/pw usershow sddm >/dev/null 2>&1; then echo sddm-user-ok; else echo sddm-user-missing; fi grep -E '^Include /etc/ssh/sshd_config.d/\\*\\.conf' /mnt/etc/ssh/sshd_config cat /mnt/etc/ssh/sshd_config.d/clawdie-live.conf grep -E '^pf_enable="YES"' /mnt/etc/rc.conf ! grep -E '^pflog_enable="YES"' /mnt/etc/rc.conf ! grep -E '^pflogd_enable="YES"' /mnt/etc/rc.conf test -f /mnt/etc/pf.conf ! grep -q '^[^#].*\' /mnt/etc/pf.conf test -f /mnt/usr/local/etc/rc.d/clawdie_live_gpu ! grep -q '^i915_.*_load="YES"' /mnt/boot/loader.conf grep -q 'vendor="0x1002"' /mnt/usr/local/etc/rc.d/clawdie_live_gpu grep -q 'vendor="0x8086"' /mnt/usr/local/etc/rc.d/clawdie_live_gpu test -f /mnt/usr/local/etc/rc.d/clawdie_live_wifi test -f /mnt/usr/local/etc/rc.d/clawdie_live_seed test -f /mnt/usr/local/etc/rc.d/clawdie_live_power test -f /mnt/usr/local/etc/rc.d/clawdie_tailscale_up test ! -f /mnt/usr/local/etc/rc.d/clawdie test -z "$(ls /mnt/usr/local/share/wayland-sessions/*.desktop 2>/dev/null)" # XFCE panel plugin shared-library diagnostic. If any plugin .so has # unresolved deps, the panel will pop a "could not be loaded" dialog. _panel_missing=0 for _so in /mnt/usr/local/lib/xfce4/panel/plugins/*.so; do _missing=$(ldd "$_so" 2>&1 | grep 'not found' || true) if [ -n "$_missing" ]; then echo "FAIL: $_so"; echo "$_missing"; _panel_missing=1; fi done test "$_panel_missing" -eq 0 pkg -r /mnt info -e gstreamer1-plugins-good grep -q 'name="plugin-11".*value="mixer"' /mnt/usr/local/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml grep -q 'name="plugin-13".*value="clipman"' /mnt/usr/local/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml # X server-level no-blank / no-DPMS. Without this the screen blanks # after 10 min and on some hardware DPMS-wake leaves the session # hung-looking with an I-beam cursor. test -f /mnt/usr/local/etc/X11/xorg.conf.d/40-clawdie-noblank.conf grep -qE 'BlankTime.*"0"' /mnt/usr/local/etc/X11/xorg.conf.d/40-clawdie-noblank.conf grep -qE 'OffTime.*"0"' /mnt/usr/local/etc/X11/xorg.conf.d/40-clawdie-noblank.conf grep -q '^xset -dpms' /mnt/home/clawdie/.xprofile grep -q 'clawdie-noblank-guard.sh' /mnt/home/clawdie/.xprofile test -x /mnt/usr/local/bin/clawdie-noblank-guard.sh test -f /mnt/usr/local/etc/xdg/autostart/clawdie-noblank-guard.desktop test -f /mnt/home/clawdie/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml grep -q 'name="dpms-enabled".*value="false"' /mnt/home/clawdie/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml grep -q 'name="blank-on-ac".*value="0"' /mnt/home/clawdie/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml # CPU power management: powerdxx daemon + deep C-states. pkg -r /mnt info -e powerdxx grep -E '^powerdxx_enable="YES"' /mnt/etc/rc.conf grep -E '^powerdxx_flags=' /mnt/etc/rc.conf ! grep -qE '^powerd_enable="YES"' /mnt/etc/rc.conf grep -E '^performance_cx_lowest="C3"' /mnt/etc/rc.conf grep -E '^economy_cx_lowest="C3"' /mnt/etc/rc.conf grep -E '^hw\.usb\.no_suspend="1"' /mnt/boot/loader.conf # Agent CLI policy: codex via pkg, pi via npm bundle, gemini/claude excluded. pkg -r /mnt info -e codex test -x /mnt/usr/local/bin/codex test -L /mnt/usr/local/bin/pi test ! -e /mnt/usr/local/bin/gemini test ! -e /mnt/usr/local/bin/claude test -z "$(find /mnt/opt/clawdie/npm-global -path '*gemini-cli*' -print -quit)" test -z "$(find /mnt/opt/clawdie/npm-global -path '*claude-code*' -print -quit)" # npm-global tree must be clawdie-owned (was root:wheel before 0f142b7 fix). # Run the ownership checks inside the chroot so the image's passwd/group # database resolves names, not the build host's UID/GID mapping. test "$(chroot /mnt /usr/bin/stat -f '%Su:%Sg' /opt/clawdie/npm-global)" = "clawdie:clawdie" test -z "$(chroot /mnt /usr/bin/find /opt/clawdie/npm-global \( ! -user clawdie -o ! -group clawdie \) -print -quit)" grep -E '^webcamd_enable="YES"' /mnt/etc/rc.conf grep -E '^clawdie_live_wifi_enable="YES"' /mnt/etc/rc.conf grep -E '^clawdie_live_seed_enable="YES"' /mnt/etc/rc.conf grep -E '^clawdie_live_power_enable="YES"' /mnt/etc/rc.conf # Seed partition: verify s3 layout, FAT label, and embedded README.txt. # Run AFTER the s2a mount above; assumes /dev/md0 is the build-host loopback. gpart show /dev/md0 | grep -E '^[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+3[[:space:]]+(!12|fat32lba|fat32)' sudo mkdir -p /mnt-seed sudo mount -t msdosfs -o ro /dev/md0s3 /mnt-seed test -f /mnt-seed/README.txt grep -q 'CLAWDIESEED' /mnt-seed/README.txt sudo umount /mnt-seed && sudo rmdir /mnt-seed grep -E '^kld_list=.*cuse' /mnt/etc/rc.conf grep -E '^kld_list=.*hidbus.*iichid.*hms.*hmt.*hkbd' /mnt/etc/rc.conf grep -E '^kld_list=.*acpi_video.*acpi_asus' /mnt/etc/rc.conf chroot /mnt /usr/sbin/pw groupshow webcamd | grep -q clawdie test -f /mnt/usr/local/etc/xdg/autostart/clawdie-bootstrap.desktop test -f /mnt/usr/local/etc/polkit-1/rules.d/49-clawdie-power.rules ls -ld /mnt/usr/local/etc /mnt/usr/local/etc/xdg /mnt/usr/local/etc/xdg/xfce4 test -x /mnt/usr/local/etc/xdg/xfce4/xinitrc test -x /mnt/usr/local/bin/xinit test -x /mnt/usr/local/bin/startx test -x /mnt/usr/local/bin/clawdie-startx test -x /mnt/usr/local/bin/clawdie-gui test -x /mnt/usr/local/bin/hw-report test -f "/mnt/usr/local/share/applications/Clawdie Hardware Report.desktop" test -f "/mnt/home/clawdie/Desktop/Clawdie Hardware Report.desktop" test -x /mnt/home/clawdie/.xinitrc test -x /mnt/home/clawdie/.config/xfce4/xinitrc pkg -r /mnt info -e xterm pkg -r /mnt info -e mousepad pkg -r /mnt info -e dmidecode pkg -r /mnt info -e pciutils pkg -r /mnt info -e usbutils pkg -r /mnt info -e xfce4-desktop pkg -r /mnt info -e xfdesktop pkg -r /mnt info -e thunar pkg -r /mnt info -e gsettings-desktop-schemas pkg -r /mnt info -e avahi-app pkg -r /mnt info -e nss_mdns pkg -r /mnt info -e wifi-firmware-kmod pkg -r /mnt info -e FreeBSD-fwget pkg -r /mnt info -e webcamd pkg -r /mnt info -e v4l-utils pkg -r /mnt info -e pwcview pkg -r /mnt info -e hw-probe pkg -r /mnt info -e p5-libwww pkg -r /mnt info -e smartmontools pkg -r /mnt info -e lscpu pkg -r /mnt info -e lsblk pkg -r /mnt info -e hwstat pkg -r /mnt info -e usbhid-dump pkg -r /mnt info -e libinput pkg -r /mnt info -e xinput pkg -r /mnt info -e xrandr pkg -r /mnt info -e mesa-demos pkg -r /mnt info -e vulkan-tools pkg -r /mnt info -e gpu-firmware-amd-kmod-renoir pkg -r /mnt info -e gpu-firmware-amd-kmod-green-sardine test -f /mnt/usr/local/share/glib-2.0/schemas/gschemas.compiled test -f /mnt/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache grep -qi png /mnt/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache grep -E '^security.mac.do.rules=gid=0>uid=0,gid=0,\+gid=\*' /mnt/etc/sysctl.conf grep -E '^devfs_system_ruleset="clawdie_live"' /mnt/etc/rc.conf grep -E '^\[clawdie_live=' /mnt/etc/devfs.rules grep -E '^video:.*clawdie' /mnt/etc/group test "$(stat -f '%Su:%Sg' /mnt/opt/clawdie/npm-global)" = "clawdie:clawdie" test -L /mnt/home/clawdie/.cache readlink /mnt/home/clawdie/.cache test -f /mnt/home/clawdie/.local/share/applications/mimeapps.list test -f /mnt/usr/local/share/X11/xkb/keycodes/xfree86 find /mnt/usr/local/share/X11/xkb -type d -maxdepth 1 -exec ls -ld {} + ls -ld /mnt/tmp /mnt/var/log /mnt/var/tmp /mnt/var/lib/xkb /mnt/var/run/user /mnt/var/run/user/* grep -E '"tailscale_auth_key_baked": (true|false)' /mnt/usr/local/share/clawdie-iso/build-manifest.json cat > "$PWD/tmp/xkb-default-test.xkb" <<'EOF' xkb_keymap { xkb_keycodes { include "xfree86+aliases(qwerty)" }; xkb_types { include "complete" }; xkb_compat { include "complete" }; xkb_symbols { include "pc+us+inet(evdev)" }; xkb_geometry { include "pc(pc105)" }; }; EOF /mnt/usr/local/bin/xkbcomp -w 0 -R/mnt/usr/local/share/X11/xkb "$PWD/tmp/xkb-default-test.xkb" "$PWD/tmp/xkb-default-test.xkm" rm -f "$PWD/tmp/xkb-default-test.xkb" "$PWD/tmp/xkb-default-test.xkm" pkg -r /mnt info -e bash pkg -r /mnt info -e zsh pkg -r /mnt info -e ohmyzsh pkg -r /mnt info -e git pkg -r /mnt info -e node24 pkg -r /mnt info -e npm-node24 test -x /mnt/usr/local/bin/bash test -x /mnt/usr/local/bin/zsh grep -qx /usr/local/bin/bash /mnt/etc/shells grep -qx /usr/local/bin/zsh /mnt/etc/shells /usr/sbin/pw -R /mnt usershow clawdie | awk -F: '{print $10}' | grep -qx /usr/local/bin/bash test -f /mnt/etc/profile.d/clawdie.sh test -f /mnt/home/clawdie/.bash_profile test -f /mnt/home/clawdie/.bashrc test -f /mnt/home/clawdie/.zprofile test -f /mnt/home/clawdie/.zshrc grep -q "oh-my-zsh.sh" /mnt/home/clawdie/.zshrc grep -R "/opt/clawdie/npm-global/bin" /mnt/etc/profile.d/clawdie.sh /mnt/home/clawdie/.profile /mnt/home/clawdie/.bash_profile /mnt/home/clawdie/.bashrc /mnt/home/clawdie/.zprofile /mnt/home/clawdie/.zshrc grep -q "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" /mnt/etc/profile.d/clawdie.sh pkg -r /mnt info -e sudo || true pkg -r /mnt info -d networkmgr grep -R "mdo -u root networkmgr" /mnt/usr/local/etc /mnt/usr/local/share/applications 2>/dev/null sudo umount /mnt sudo mdconfig -d -u md0 ``` ### Pass criteria - SDDM live path present - no live autologin configured in SDDM - XFCE global and user xinitrc files are executable - `xinit`/`startx`, `clawdie-startx`, and `clawdie-gui` are present for tty-side graphical rescue testing - `xterm` is present as a minimal Xorg rescue client - `mousepad` is present for the seeded text/plain MIME handler - root filesystem configured read-write in `/etc/fstab` - `/tmp` and `/var/log` are configured as explicit tmpfs mounts while `/var/tmp` remains on disk - default XKB keymap compiles against the image xkeyboard-config tree - XKB cache and temp directories have runtime-safe permissions - stock installer tmpfs overlays for `/tmp` and `/var` are disabled - no swap entries in `/etc/fstab`; `dumpdev_enable="NO"` so the boot path does not scan for swap - base `sshd` is enabled with the restrictive live drop-in and no password/root auth - mDNS is wired through `avahi-app` + `nss_mdns` - PF live baseline is present with no logging rules - `bash`, `zsh`, `ohmyzsh`, and `git` are installed, `/usr/local/bin/bash` and `/usr/local/bin/zsh` are in `/etc/shells`, and `clawdie` uses bash as the login shell - Clawdie shell profiles put `/opt/clawdie/npm-global/bin` on PATH and repair the standard FreeBSD `/usr/local` + `/usr` command paths for SSH, TTY, terminal, and `su - clawdie`; zsh sources packaged oh-my-zsh when present - `.cache` is redirected to `/tmp/clawdie/cache` - GPU pre-SDDM service present - power-action policy present - `networkmgr` does not depend on `sudo` - native Wi-Fi firmware bundle is present - `sudo` is absent from the live rootfs --- ## Level 2: bhyve Verification (on-demand) bhyve is an **on-demand** verification lane, not a per-change gate — it's slow and needs the ML350p, so run it when you want boot/runtime confidence before committing to physical hardware, not on every iteration. The cheap gates that run every change are the static checks (`sh -n`, staging self-tests) and `cargo test`. When you do run it, treat bhyve as authoritative for boot/runtime plumbing and still treat real hardware as the final authority for GPU, panel, input, Wi-Fi, and audio polish. ### ML350p resource plan | Resource | Allocation | | ----------- | ---------------------------------------------------------------------------- | | Host (16G) | ZFS ARC 6G + Poudriere tmpfs 4G + headroom 6G | | bhyve (16G) | FreeBSD ISO test 4G + Linux cross-compile 4G + FreeBSD builder 4G + spare 4G | Planned bhyve roles: - ISO boot verification after each build - Linux target validation - FreeBSD/Poudriere test lane ### Host preflight ```sh ./scripts/preflight-host.sh which bhyve kldstat | grep vmm df -h / ``` Optional PF helper for guest internet: ```sh sudo ./scripts/bhyve-pf-allow.sh ``` ### Run the boot verification ```sh cd /home/clawdie/ai/clawdie-iso sudo ./scripts/bhyve-test.sh ``` ### What to look for - image boots at all - SDDM/XFCE path appears instead of dropping straight to a dead console - no immediate package/rootfs failure - Clawdie/Colibri service staging does not crash the session at first boot bhyve is useful for catching: - broken bootcode - missing live-session payload - obvious SDDM/Xorg startup regressions - obvious service-start regressions after build-time staging changes It is **not** enough for final GPU confidence or laptop-specific UI/device behavior. --- ## Level 3: Hardware USB Validation This is the real acceptance path for the operator USB. ### Before flashing If reusing an old USB stick, inspect it first. Old ZFS labels at the end of the device can survive if a previous image was larger or used a different layout. On Linux: ```sh lsblk -f sudo wipefs -n /dev/sdX sudo fdisk -l /dev/sdX ``` If you see stale labels such as `nomadbsd_zroot`, wipe the whole stick first: ```sh sudo umount /dev/sdX* 2>/dev/null || true sudo sgdisk --zap-all /dev/sdX sudo dd if=/dev/zero of=/dev/sdX bs=16M status=progress conv=fsync ``` ### Flash the image Use [FLASHING.md](FLASHING.md) as the canonical flashing guide for Linux and FreeBSD. For a published compressed image on Linux, the default path is: ```sh curl -fL --continue-at - --retry 5 --retry-delay 5 --progress-bar -O \ https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz curl -fL --retry 5 --retry-delay 5 -O \ https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz.sha256 sha256sum -c clawdie-quindecim-0.10.0.img.xz.sha256 set -o pipefail 2>/dev/null || true xz -dc clawdie-quindecim-0.10.0.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync sync ``` Use the whole USB disk (`/dev/sdX`), not a partition such as `/dev/sdX1`. Then re-check the stick: ```sh sudo wipefs -n /dev/sdX lsblk -f /dev/sdX ``` You should no longer see stale `nomadbsd_zroot`-style labels. ### Expected boot behavior 1. USB boots. 2. `clawdie_live_gpu` detects display hardware and loads a conservative KMS path. 3. SDDM starts. 4. Operator logs in at the SDDM greeter as `clawdie`. 5. XFCE panel and bootstrap launcher appear. 6. NetworkMgr tray applet appears. ### Core runtime checks From the live desktop or a tty: ```sh id clawdie hostname grep -E '^[[:space:]]*(127\.0\.0\.1|::1)[[:space:]].*clawdie-live' /etc/hosts mount | egrep ' on / | on /tmp | on /var ' df -h / /tmp /var/log /var/tmp ~/.cache egrep 'hostname|root_rw_mount|tmpmfs|varmfs|sshd|avahi|powerd|powerdxx|pf_enable|sddm|display_manager|clawdie_live_gpu|clawdie_tailscale_up|devfs_system_ruleset|kld_list|zfs' /etc/rc.conf /etc/rc.conf.local 2>/dev/null sysctl security.mac.do.rules id echo "$XDG_RUNTIME_DIR" ls -ld "$XDG_RUNTIME_DIR" ls -l /usr/local/share/glib-2.0/schemas/gschemas.compiled /usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache ls -ld /dev/dri /dev/dri/* 2>/dev/null || true ls -ld /var/lib/xkb /tmp /var/tmp /usr/local/share/X11/xkb /usr/local/share/X11/xkb/keycodes ls -ld /usr/local/etc /usr/local/etc/xdg /usr/local/etc/xdg/xfce4 ls -l /usr/local/etc/xdg/xfce4/xinitrc /home/clawdie/.xinitrc /home/clawdie/.config/xfce4/xinitrc /usr/local/bin/xinit -version /usr/local/bin/startx --help >/dev/null 2>&1 || true test -x /usr/local/bin/clawdie-startx test -x /usr/local/bin/clawdie-gui xterm -version mousepad --version service dbus onestatus service sshd onestatus service pf onestatus service avahi-daemon onestatus 2>/dev/null || service avahi_daemon onestatus service tailscaled onestatus service sddm onestatus swapinfo # expected: no swap devices listed cat /usr/local/etc/sddm.conf.d/50-clawdie-live.conf cat /etc/ssh/sshd_config.d/clawdie-live.conf grep -E '^hosts:.*mdns_minimal.*dns.*mdns' /etc/nsswitch.conf pfctl -sr cat /var/log/clawdie-live-gpu.log kldstat | egrep 'i915|amdgpu|radeon|vmwgfx|nvidia|linux|zfs' ifconfig sysctl net.wlan.devices 2>/dev/null || true pciconf -lv usbconfig dmesg | grep -Ei 'iwl|rtw|ath|mt76|firmware|wlan|wifi|802\.11' ``` Expected filesystem state: - `/` is mounted read-write from `/dev/ufs/FreeBSD_Install` - `/tmp` and `/var/log` are tmpfs mounts from `/etc/fstab` - `/var/tmp` stays on the root filesystem - `~/.cache` is a symlink to `/tmp/clawdie/cache` - `/var/lib/xkb` exists and is writable for XKB cache generation Then verify operator tools: ```sh echo "$SHELL" command -v bash command -v zsh command -v git command -v node command -v npm command -v pi pi --help tailscale version tmux -V python3 --version bastille --help mdo -u root bastille --help ``` For networking/UI: - confirm the NetworkMgr tray icon appears - confirm Firefox opens - confirm `pcmanfm` opens - confirm `mousepad` opens a plain-text file - confirm panel power actions work for `clawdie` - confirm `mdo -u root tailscale up` is available when you want to join a tailnet - if built with `--ssh-key`, confirm SSH from another machine works with the baked key - if built with `--tailscale-auth-key`, confirm `tailscale status` shows the node joined and `ssh clawdie@clawdie-live` works from the tailnet - if on a multicast-friendly LAN, confirm `clawdie-live.local` resolves from another machine - if a `wlan` device appears, confirm NetworkMgr can see it without any extra `wifibox` layer - if Wi-Fi is missing, collect `ifconfig`, `sysctl net.wlan.devices`, `pciconf -lv`, `usbconfig`, and the Wi-Fi/firmware `dmesg` lines before changing package lists ### GPU expectations The live USB now prefers broad boot success over aggressive proprietary loading and selects KMS drivers by numeric PCI display vendor ID, not broad text matches: - AMD/ATI `0x1002` -> `amdgpu`, then `radeonkms` only if `amdgpu` did not load - Intel `0x8086` -> `i915kms` - VMware `0x15ad` -> `vmwgfx` - NVIDIA `0x10de` -> proprietary modules only if `/boot/modules/nvidia.ko` is actually installed - otherwise -> Xorg fallback path (`scfb` / `vesa`) This means an NVIDIA machine may still boot graphically without using the proprietary NVIDIA stack. ### Reference deploy machine — ASUS ZenBook UX325UA / Ryzen 5700U Linux baseline probe: [linux-hardware.org/?probe=efd5b5b389](https://linux-hardware.org/?probe=efd5b5b389) This is a real deploy target. First-boot check set for this machine (or any AMD Ryzen U-series laptop) once the image lands: ```sh # AMD graphics + firmware cat /var/log/clawdie-live-gpu.log kldstat | grep -E 'amdgpu|drm|i915' dmesg | grep -iE 'amdgpu|firmware|renoir|cezanne|green' sysctl hw.dri.0.busid # Backlight (acpi_video) sysctl hw.acpi.video.lcd0.brightness # Intel Wi-Fi 8265 — clawdie_live_wifi should have created wlan0 service clawdie_live_wifi status sysctl net.wlan.devices # expect iwm0 (or similar) ifconfig -a | grep -A 2 ^wlan0 ifconfig wlan0 list scan | head # Webcam — webcamd should have attached on first USB enumeration service webcamd status ls -l /dev/video* v4l2-ctl --list-devices # Optional interactive: pwcview # close with q # AMD I²C / HID-over-I²C touchpad pciconf -lv | grep -B 1 -A 3 -iE 'i2c|smbus' kldstat | grep -iE 'iic|hms|hmt|elan|hidbus' dmesg | grep -iE 'iichid|hms|hmt|elan|psm' sysctl kern.evdev.input # Hardware baseline bundle for support/custom-ISO analysis. This is local-only. mdo -u root hw-report # Optional public hardware baseline upload — gives a permanent # bsd-hardware.info URL for direct compare against the Linux probe above. mdo -u root hw-report --upload-public-probe # Input/video diagnostic clients. libinput works outside X; xinput/xrandr/glxinfo # assume the desktop session is live on :0. libinput list-devices DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xinput list DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xrandr --verbose | head -80 DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority glxinfo -B # Agent CLI runtime probe. pi is required; gemini/claude should both be absent # from the live image. pi --version command -v gemini || echo "gemini absent as expected (not bundled on the live image)" codex --version command -v claude || echo "claude absent as expected (skipped on FreeBSD live image)" # X power management — must be disabled out of the box. # Expect "timeout: 0", "DPMS is Disabled". Wait 11+ min idle to confirm # screen does NOT blank (10 min was the stock timeout that caused # the hang-looking session on wake). If XFCE tries to re-enable it, # the no-blank guard should force it back off. xset q | grep -E 'timeout|DPMS is' xfconf-query -c xfce4-power-manager -l -v | grep -E 'blank|dpms|inactivity|presentation|lock-screen' || true tail -20 ~/.clawdie-noblank-guard.log # CPU power management runtime probe. service powerdxx status # expect "is running as pid ..." service clawdie_live_power status # expect power_profile applied at boot sysctl hw.acpi.acline # 1 = AC, 0 = battery sysctl hw.acpi.cpu.cx_lowest # expect C3 (matches live USB rc.conf) sysctl dev.cpu.0.freq_levels # available freq steps sysctl dev.cpu.0.freq # after ~1 min idle, should be at a low step # Optional A/B vs default: stop the daemon, observe freq pinning at max # service powerdxx stop && sysctl dev.cpu.0.freq && service powerdxx start # npm-global ownership at runtime — this was the silent regression in # pre-0f142b7 images. Both should be empty. find /opt/clawdie/npm-global \( ! -user clawdie -o ! -group clawdie \) -print stat -f '%Su:%Sg' /opt/clawdie/npm-global # Audio: OSS mixer + xfce4-mixer panel plugin. snd_hda should attach # on most hardware. xfce4-mixer uses GStreamer→OSS; if the volume # icon is missing from the panel, check gstreamer1-plugins-good. cat /dev/sndstat mixer -s | head # expect "Mixer vol is currently set to ..." pkg info -e gstreamer1-plugins-good # Panel plugin visual: xkb should show flag icons (not text "si"), # cpugraph should be ~36px wide, mixer + clipman should be configured, # clock font should be ~14pt Noto Sans. xfconf-query -c xfce4-panel -p /plugins/plugin-10/display-type # expect 0 (flag) xfconf-query -c xfce4-panel -p /plugins/plugin-9/size # expect 36 xfconf-query -c xfce4-panel -p /plugins/plugin-11 # expect mixer xfconf-query -c xfce4-panel -p /plugins/plugin-13 # expect clipman xfconf-query -c xfce4-panel -p /plugins/plugin-12/font # expect "Noto Sans 14" # Clipman runtime gate — catches the "could not be loaded" popup that # prompted the original removal in 2fc4ca1. Empty grep = clipman loaded OK. grep -ri 'could not be loaded' ~/.cache/xfce4-session/*.log 2>/dev/null || echo "clipman: no load failures in session log" # xfce4-mixer runtime gate. The plugin runs inside xfce4-panel (no # separate long-lived process), so `pgrep xfce4-mixer` returns empty # even when the plugin is loaded and working. The question that # actually matters is "does the mixer have an audio backend to # control" — empty /dev/sndstat → the panel icon will be present # but non-functional regardless of whether GStreamer→OSS started. cat /dev/sndstat # expect at least one pcm0 entry mixer -s 2>/dev/null | head # base CLI sanity check xfce4-panel --plugin-list 2>/dev/null | grep -i mixer || true ``` Known FreeBSD limitations on this machine class (not bugs, do not chase): - **AMD ACP3x audio coprocessor (`1022:15e2`)** — no FreeBSD driver. Plain HDA path (`snd_hda`) handles speakers / headphones / mic. AI noise cancellation / beamforming features are absent. - **Realtek RTS522A PCIe card reader (`rtsx_pci` on Linux)** — FreeBSD `rtsx(4)` coverage is patchy for this chip; SD card reader may not work. Not critical for an operator USB. - **HID-over-I²C touchpad** — depends on AMD I²C controller probing successfully on FreeBSD. If `iichid` does not attach, the touchpad falls back to PS/2 — pointer + click work, multitouch gestures do not. This is an upstream FreeBSD support gap, not a Clawdie bug. ### CLAWDIESEED partition — Linux pre-flash workflow The live USB ships with a 64 MiB FAT32 partition labeled `CLAWDIESEED` at slice 3. Mount it from any Linux box (or FreeBSD, or macOS) after flashing — but BEFORE booting the stick — to drop operator overrides. Today the importer (`/usr/local/etc/rc.d/clawdie_live_seed`) honors SSH `authorized_keys` only; `hostname` / Tailscale auth-key / Wi-Fi env files are reserved for future passes. ```sh # After 'dd' of the image to /dev/sdX completes: sudo mount -t vfat /dev/sdX3 /mnt/seed cat /mnt/seed/README.txt # confirm contract cp ~/.ssh/id_ed25519.pub /mnt/seed/authorized_keys sync && sudo umount /mnt/seed # Boot the USB. On the live system: service clawdie_live_seed status cat /var/log/clawdie-live-seed.log # expect "installed authorized_keys..." ls -la ~clawdie/.ssh/ # 0700 dir, 0600 authorized_keys ssh -i ~/.ssh/id_ed25519 clawdie@clawdie-live.local # from another box on LAN ``` The importer runs at every boot and is idempotent — edit the seed, reboot, re-applied. There is no first-boot-only gate; removing a file from the seed and rebooting does NOT remove it from the live system (re-flash to wipe state). --- ## Supported Networking Hardware Some target hardware (Gemini Lake mini-PCs, cheap fanless laptops, kiosk boxes) ships with no internal ethernet and no internal WiFi — empty M.2 slots, USB-only I/O. For those, the live USB still boots and runs the full local stack (`sshd`, Avahi, PF, daemons, mounts), but networking has to come over USB. ### Recommended USB ethernet (preferred path) | Chipset | Driver | Notes | | ------------------------- | --------- | -------------------------------------------------------- | | ASIX AX88179 / AX88179A | `axge(4)` | USB-A or USB-C → 1 GbE. Common in higher-end USB-C hubs. | | Realtek RTL8153 / RTL8156 | `ure(4)` | The most common 1 GbE chip in USB-C dock dongles. | | ASIX AX88772 | `axe(4)` | 100 Mbit only. Older chipset, still works. | All three drivers are in base FreeBSD and **autoload on USB attach** — no `kld_list` change or rc.conf edit needed. Plug in → `ue0` appears in `ifconfig` within ~1 second → DHCP → working. If it doesn't autoload (rare), `mdo -u root kldload if_axge` (or `if_ure` / `if_axe`). USB ethernet is preferred over USB WiFi for development: more reliable, faster, doesn't depend on driver-firmware support, and bypasses the WiFi-chipset-roulette problem below. ### Recommended USB WiFi (when wired isn't possible) | Chipset | Driver | Notes | | ----------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------- | | Atheros AR9271 | `otus(4)` | TP-Link TL-WN722N **v1 only** — v2/v3 silently switched to Realtek. Look for "v1" on the package. | | Ralink RT5370 / RT2870 | `run(4)` | 2.4 GHz only, very stable. | | Realtek RTL8812AU / RTL8821AU | `net/rtl8812au-kmod` port | 802.11ac. Needs the port, not in base. | | Realtek RTL8188EU | `urtwn(4)` | Cheap Realtek option that actually has a FreeBSD driver. | Linksys / D-Link / Netgear-branded dongles **silently switch chipsets between revisions**. There is no way to predict which silicon is in a given box without opening it. Avoid those brands; buy by chipset (searched on `0bda:XXXX` / `148f:XXXX` etc. as vendor:device IDs). ### Recommended internal (PCIe / M.2) | Chipset | Driver | Notes | | ---------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------- | | Intel Wireless 7260 / 8260 / 8265 / 8275 | `iwm(4)` (or `iwlwifi(4)` LinuxKPI) | Wi-Fi 5 (ac). 8265 verified present on Ryzen 5700U laptops; works on FreeBSD via `iwm`. | | Intel AX200 / AX201 / AX210 / AX211 | `iwlwifi(4)` | Wi-Fi 6 / 6E. Best WiFi path on FreeBSD. Most laptops with an M.2 slot can take an AX210. | | Intel I218 / I219 / I225 / I226 | `em(4)` / `igc(4)` | Default ethernet on most Intel-board systems. | | Realtek RTL8111 / RTL8168 PCIe | `re(4)` | Common consumer-motherboard 1 GbE. | ### Known unsupported on FreeBSD | Chipset | Reason | | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Realtek **RTL8723BU** (`0bda:b720`) | No driver in any FreeBSD version through 15. The **Bluetooth half** of this combo dongle does work via `ng_ubt` — verified on hardware. WiFi half: no path forward without out-of-tree Linux ports. | | Realtek RTL8723BS | SDIO variant, same status. | | Realtek RTL8723DU | Same family, same status. | | MediaTek MT7921 / MT7922 | No driver as of early 2026. | | Anything labelled "generic Realtek 802.11n USB" | Vendor swaps chipsets; chipset ID required to predict support. | ### Identifying what's in the box ```sh # USB attached devices usbconfig usbconfig -d ugen?.? dump_device_desc # vendor:device of a specific one # PCIe / internal pciconf -lv | grep -B 1 -A 4 -iE 'wireless|ethernet|network' # What FreeBSD's own probe suggests for installed firmware mdo -u root fwget -n # dry run ``` ### What to do when the chipset is unsupported The live USB image is still useful — all daemons bind to `lo0` too, so `sshd`, Avahi, and the local stack can be validated without network. For end-to-end validation, swap to a supported dongle from the lists above. ### Cross-platform hardware comparison The live USB ships a FreeBSD-native hardware probe set instead of trying to mirror Linux's `hwinfo` package name: - `pciconf` - `usbconfig` - `devinfo` - `kldstat` - `dmidecode` - `lspci` via `pciutils` - `lsusb` via `usbutils` This is enough to compare a FreeBSD boot against a Linux baseline on the same chassis and spot missing drivers or firmware support. **Capture matched reports on both sides:** ```sh # FreeBSD live USB: pciconf -lv > /tmp/fbsd-pci.txt usbconfig > /tmp/fbsd-usb.txt devinfo -rv > /tmp/fbsd-devinfo.txt dmidecode > /tmp/fbsd-dmi.txt kldstat > /tmp/fbsd-kldstat.txt lspci -nn > /tmp/fbsd-lspci.txt lsusb > /tmp/fbsd-lsusb.txt # Linux baseline on the same chassis: lspci -nnk > /tmp/linux-pci.txt lsusb > /tmp/linux-usb.txt sudo dmidecode > /tmp/linux-dmi.txt ``` What the same chassis should show under the FreeBSD live USB once booted there: | Linux shows | FreeBSD equivalent | | ------------------------------------ | ---------------------------------------------------------------------------- | | `wlp1s0` Intel Wireless 8265 / 8275 | `wlan0` after `ifconfig wlan0 create wlandev iwm0`; chip handled by `iwm(4)` | | `ATI Lucienne` (AMD Renoir iGPU) | `vgapci0` in `pciconf`; `amdgpu` in `drm-kmod` | | `Intel Bluetooth wireless interface` | `ng_ubt` netgraph stack | | `tailscale0 Network Interface` | identical name on both platforms | | `/dev/nvme0n1p*` partitions | `nvd0p*` (legacy) or `nvme0ns1*` (newer FreeBSD naming) | **Reading the diff:** - If a device class shows on Linux but is missing from the FreeBSD report, that's a driver gap. Common gaps: USB WiFi dongles whose Linux driver is out-of-tree (RTL8723BU, RTL8821CU, etc.). Internal PCIe / M.2 hardware usually behaves the same. - If a device class shows on both but with different naming, that's expected — see the format-differences note below. **Output-format differences not worth trying to normalize:** - Linux: predictable interface names (`wlp1s0`, `enp2s0`, `wlx`). FreeBSD: driver-based names (`wlan0`, `iwm0`, `re0`, `em0`, `ue0`). - Linux: HID surfaces as `/dev/input/event*`. FreeBSD: through `hmt`, `psm`, `kbdmux` instead. - Linux: `/dev/nvme0n1p*`. FreeBSD: `nvd0p*` / `nvme0ns1*`. Don't try to make the outputs byte-identical — compare _device classes and counts_, not full lines. ### Extended diagnostic toolkit (live by default) The live USB ships the FreeBSD-native probe set plus `pciutils`, `usbutils`, `dmidecode`, and the `hw-report` collector. The collector writes a local bundle under `/home/clawdie/hw-reports` and does not upload unless the operator explicitly asks for a public probe. **Recommended collection command:** ```sh mdo -u root hw-report ``` **Optional public bsd-hardware.info upload:** ```sh mdo -u root hw-report --upload-public-probe ``` **Manifest:** | Package | Version | Purpose | | --------------- | ------- | ------------------------------------------------------------------------------------------------ | | `hw-probe` | 1.6.6_1 | Comprehensive hardware probe report; can submit anonymously to `bsd-hardware.info`. | | `smartmontools` | 7.5_2 | `smartctl` for SMART disk health; `smartd(8)` for monitoring (daemon left disabled on live USB). | | `lscpu` | 1.3.0 | Linux-style CPU summary — convenient when comparing against a Linux baseline. | | `lsblk` | 4.1_1 | Linux-style block-device listing — same. | | `hwstat` | 0.5.1_1 | Hardware statistics (CPU, mem, network, disk counters). | | `usbhid-dump` | 1.4 | Raw HID report descriptor dump. Useful for touchpad/keyboard quirks. | | `xinput` | 1.6.4 | Exact X input device list and per-device properties (trackpad tap/scroll/DWT state). | | `xrandr` | 1.5.3 | RandR output/mode/EDID probe from the running X session. | | `mesa-demos` | 8.5.0 | Provides `glxinfo -B` to confirm real GL renderer vs `llvmpipe`. | Transitive deps of note: `p5-LWP-UserAgent-Cached` (Perl HTTP cache, from `hw-probe`); `freeglut` and `libGLU` from `mesa-demos`. **Useful direct commands:** ```sh # Comprehensive local Clawdie bundle mdo -u root hw-report # Trackpad / mouse / video truth from the running session libinput list-devices DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xinput list DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xrandr --verbose DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority glxinfo -B # Comprehensive snapshot — public upload only when explicitly requested mdo -u root hw-probe -all mdo -u root hw-probe -all -upload # submit to bsd-hardware.info mdo -u root hw-report --upload-public-probe # confirm public Probe URL is reported # SMART disk health /usr/local/sbin/smartctl -a /dev/ada0 # SATA /usr/local/sbin/smartctl -a /dev/da0 # SCSI / USB-attached /usr/local/sbin/smartctl -a /dev/nvme0 # NVMe # Linux-familiar summaries lscpu lsblk # Hardware stats hwstat # HID descriptor of a specific USB device usbhid-dump -d ``` **smartmontools daemon setup — operator opt-in on the installed system, not the live USB:** ```sh cp /usr/local/etc/smartd.conf.sample /usr/local/etc/smartd.conf # edit to taste echo 'smartd_enable="YES"' | mdo -u root tee -a /etc/rc.conf echo 'daily_status_smart_devices=' | mdo -u root tee -a /etc/periodic.conf mdo -u root service smartd start ``` On the live USB `smartd` stays off — interactive `smartctl -a` is the intended use. The daemon setup belongs on the disk-installed system if the operator wants continuous monitoring. **Promotion question — should some of these be baked in?** The ~3 MiB cost is small relative to the image. `smartmontools` and `hw-probe` are the two with the strongest case for becoming default live-USB packages, since both come up regularly during hardware validation. `lscpu` / `lsblk` are convenience aliases for Linux muscle memory. `hwstat` and `usbhid-dump` are niche. Left as on-demand for now; revisit in a future package-list pass. --- ## If Graphical Login Fails Do not rebuild immediately. First capture runtime facts from the booted USB. ### Check service and Xorg state ```sh service dbus onestatus service sddm onestatus tail -100 /var/log/sddm.log tail -100 /var/log/Xorg.0.log cat /var/log/clawdie-live-gpu.log ``` ### Check XKB runtime files ```sh ls -ld /usr/local/share/X11 ls -ld /usr/local/share/X11/xkb ls -ld /usr/local/share/X11/xkb/keycodes ls -ld /var/lib/xkb /tmp /var/tmp ls -l /usr/local/share/X11/xkb/keycodes/xfree86 pkg info -e xkeyboard-config xkbcomp xorg-server xorg-minimal ``` If X is already running, compile the active keymap: ```sh setxkbmap -print | xkbcomp -w 10 -xkm - /tmp/clawdie-xkb-test.xkm echo $? rm -f /tmp/clawdie-xkb-test.xkm ``` If X is not running, compile a default keymap against the installed XKB tree: ```sh cat > /tmp/clawdie-xkb-default-test.xkb <<'EOF' xkb_keymap { xkb_keycodes { include "xfree86+aliases(qwerty)" }; xkb_types { include "complete" }; xkb_compat { include "complete" }; xkb_symbols { include "pc+us+inet(evdev)" }; xkb_geometry { include "pc(pc105)" }; }; EOF xkbcomp -w 10 -R/usr/local/share/X11/xkb /tmp/clawdie-xkb-default-test.xkb /tmp/clawdie-xkb-default-test.xkm echo $? rm -f /tmp/clawdie-xkb-default-test.xkb /tmp/clawdie-xkb-default-test.xkm ``` ### Check the actual running config ```sh egrep 'hostname|root_rw_mount|tmpmfs|varmfs|sshd|avahi|pf_enable|sddm|display_manager|clawdie_live_gpu|clawdie_tailscale_up|kld_list|zfs' /etc/rc.conf /etc/rc.conf.local 2>/dev/null hostname grep -E '^[[:space:]]*(127\.0\.0\.1|::1)[[:space:]].*clawdie-live' /etc/hosts mount | egrep ' on / | on /tmp | on /var ' df -h / /tmp /var/log /var/tmp ~/.cache readlink ~/.cache ``` ### Live Wi-Fi diagnostics If Ethernet works but Wi-Fi does not appear, collect: ```sh ifconfig sysctl net.wlan.devices 2>/dev/null || true pciconf -lv usbconfig kldstat | grep -Ei 'iwl|rtw|ath|mt76|wlan|wifi' dmesg | grep -Ei 'iwl|rtw|ath|mt76|firmware|wlan|wifi|802\.11' ``` Current packaging intent: - native firmware bundle: `wifi-firmware-kmod` - runtime firmware helper: `FreeBSD-fwget` - network UI: existing `NetworkMgr` - not included: `wifibox` ### Manual X session probe If SDDM is dead but a tty works: ```sh su - clawdie startxfce4 ``` If `startxfce4`/`startx` trips over xauth/serverauth setup while Xorg itself starts, use the live rescue launcher. It bypasses `startx` xauth setup and starts a local-only Xorg server for console debugging: ```sh su - clawdie clawdie-gui ``` If this fails, keep the exact error text. The common split is: - Xorg/runtime filesystem issue - SDDM/login issue - GPU module selection issue Avoid package-list changes until the runtime evidence says a package is truly missing from the live rootfs. --- ## Acceptance Checklist Mark the image good only when all of these are true: - [ ] image boots from USB on real hardware - [ ] SDDM greeter appears; logging in as `clawdie` launches Clawdie XFCE - [ ] XFCE panel and desktop appear - [ ] hostname is set to `clawdie-live` - [ ] `/` is read-write, `/tmp` and `/var/log` are tmpfs, and `/var/tmp` stays on disk - [ ] `~/.cache` points at `/tmp/clawdie/cache` - [ ] `/usr/local/etc/xdg/xfce4/xinitrc` and `clawdie` xinitrc fallbacks are executable - [ ] `xinit`/`startx`, `clawdie-startx`, `clawdie-gui`, and `xterm` are present for minimal Xorg rescue/startup checking - [ ] `/var/lib/xkb` exists and XKB keymap compilation succeeds - [ ] `XDG_RUNTIME_DIR` resolves to `/var/run/user/` - [ ] `clawdie_live_gpu` log shows a sensible path or a clear fallback - [ ] SSH policy is pubkey-only and root login is disabled - [ ] PF baseline is active with no default logging stack - [ ] `clawdie-live.local` resolves on a multicast-friendly LAN - [ ] `mdo -u root id` succeeds for `clawdie` - [ ] GSettings schemas and gdk-pixbuf PNG loader cache exist - [ ] `/dev/dri/*` is usable by `clawdie` via the `video` group when DRM is present - [ ] NetworkMgr tray icon appears - [ ] Firefox opens - [ ] `mousepad` opens plain-text files - [ ] `pi --help` works - [ ] `tailscale version` works - [ ] `tmux -V` works - [ ] `python3 --version` reports Python 3.12 - [ ] `bastille --help` works - [ ] `sudo` is absent from the live image - [ ] no stale-label confusion remains on the flashed USB stick --- ## See Also - [README.md](README.md) — current branch overview and quick start - [BUILD.md](BUILD.md) — build flags and artifact output - [REQUIREMENTS.md](REQUIREMENTS.md) — build host, USB, and hardware requirements - [FIRSTBOOT.md](FIRSTBOOT.md) — installed-system firstboot pipeline (philosophy, dependency graph, per-module reference) --- **Last updated:** 16.maj.2026