clawdie-iso/TESTING.md

49 KiB

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:

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

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 '^[^#].*\<log\>' /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

./scripts/preflight-host.sh
which bhyve
kldstat | grep vmm
df -h /

Optional PF helper for guest internet:

sudo ./scripts/bhyve-pf-allow.sh

Run the boot verification

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:

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:

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 as the canonical flashing guide for Linux and FreeBSD. For a published compressed image on Linux, the default path is:

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:

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:

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:

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

This is a real deploy target. First-boot check set for this machine (or any AMD Ryzen U-series laptop) once the image lands:

# 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.

# 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.

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.

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).

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

# 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:

# 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<mac>). 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:

mdo -u root hw-report

Optional public bsd-hardware.info upload:

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:

# 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 <ugen>

smartmontools daemon setup — operator opt-in on the installed system, not the live USB:

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

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

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:

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:

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

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:

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:

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:

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/<uid>
  • 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 — current branch overview and quick start
  • BUILD.md — build flags and artifact output
  • REQUIREMENTS.md — build host, USB, and hardware requirements
  • FIRSTBOOT.md — installed-system firstboot pipeline (philosophy, dependency graph, per-module reference)

Last updated: 16.maj.2026