Decouple the ISO identity from zot and cut the first numbered milestone. Versioning schema (decided 2026-06-15): - ISO_VERSION is now an explicit product version (build.cfg: 0.10.0); the "auto"/zot-tracking path is removed and a build with no version fails fast. The image no longer borrows zot's number — component versions are provenance. - build-manifest.json: "iso_version_tracks":"zot" -> "version_scheme":"product", and add colibri_commit/colibri_dirty (the image stages adjacent colibri binaries; record which commit produced them — the main reproducibility gap). Docs/version consistency (from docs to flashing/testing/skill): - CHANGELOG: new [0.10.0] "Operator Image" milestone (stable XFCE + colibri service fixes + self-rebuild lane); reword the version model and repo table. - README/BUILD/FLASHING/TESTING/iso-publish: artifact examples 0.2.29 -> 0.10.0; version-scheme prose updated to product-version, not zot-tracking. Stacked on the live-rebuild branch (PR #56); merge after it. Checks: sh -n build.sh OK; prettier clean on all changed docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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:
- Does the built image contain the expected live-session payload?
- Does it boot to XFCE on representative hardware?
- Do the operator tools work without
sudo, usingmdowhere 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.confcontains: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/fstabmounts/dev/ufs/FreeBSD_Installat/withrw, notro/etc/fstabadds tmpfs for/tmpand/var/log, while/var/tmpstays on disk/etc/fstabcontains no swap entries (no USB write wear, predictable behaviour under memory pressure)- SDDM live config exists, does not configure autologin, and keeps
Numlock=offfor compact laptop keyboards - base
sshdincludes/etc/ssh/sshd_config.d/*.confand the live drop-in disables password and root login /etc/nsswitch.confresolves hosts withmdns_minimal/etc/pf.confexists and has nologrules/usr/local/etc/rc.d/clawdie_live_gpuexists/usr/local/etc/rc.d/clawdie_live_wifiexists/usr/local/etc/rc.d/clawdie_live_seedexists/usr/local/etc/rc.d/clawdie_live_powerexists and applies thepower_profileC-state policy once at boot/usr/local/etc/rc.d/clawdie_tailscale_upexists/usr/local/etc/rc.d/clawdieis absent on baseline live USB builds;service clawdieis reserved for deployed disk/server targets/usr/local/etc/polkit-1/rules.d/49-clawdie-power.rulesexists- XKB files exist, especially
.../xkb/keycodes/xfree86 - XKB parent directories are traversable and
/var/lib/xkbis writable for rootless Xorg cache generation /tmpand/varare not hidden by stock installer tmpfs overlays/home/clawdie/.cacheis a symlink to/tmp/clawdie/cachenetworkmgris installed withoutsudoavahi-app,nss_mdns, andmousepadare installedwifi-firmware-kmodandFreeBSD-fwgetare installedwebcamd,v4l-utils,pwcview,hw-probe, andp5-libwwware installedgpu-firmware-amd-kmod-renoirandgpu-firmware-amd-kmod-green-sardineare installed (Ryzen iGPU coverage)webcamdgroup exists andclawdieis a memberwebcamd_enable="YES"andclawdie_live_wifi_enable="YES"in/etc/rc.confclawdie_live_seed_enable="YES"andclawdie_live_power_enable="YES"in/etc/rc.confkld_listincludescuse,hidbus,iichid,hms,hmt,hkbd,acpi_video,acpi_asus,acpi_asus_wmisudois not installed in the image- Image partition table has three slices:
s1EFI 64M,s2FreeBSD,s3FAT32 64M labeledCLAWDIESEED CLAWDIESEEDslice mounts cleanly as msdosfs and containsREADME.txtdescribing the seed contract/usr/local/share/wayland-sessions/contains no.desktopfiles (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 (
lddon each.somust report zero "not found") gstreamer1-plugins-goodis installed (provides the GStreamer→OSS bridge required byxfce4-mixerto detect sound cards on FreeBSD)/usr/local/etc/X11/xorg.conf.d/40-clawdie-noblank.confexists and disables Xorg blanking + DPMS at server level (BlankTime/StandbyTime/SuspendTime/OffTime all"0")~clawdie/.xprofilecontainsxset -dpmsand startsclawdie-noblank-guard.shas a session-level belt-and-suspenders fallback/usr/local/bin/clawdie-noblank-guard.shand its XFCE autostart desktop file exist; the guard reapplies no-blank/no-DPMS after xfsettingsd or xfce4-power-manager startsxfce4-power-manager.xmlseeds display blanking, DPMS, idle sleep, and lock-on-suspend off for the live user and XDG defaults- CPU power management:
powerdxxpackage is installed (drop-in replacement for basepowerdwith moving-average load sampling)powerdxx_enable="YES"andpowerdxx_flags="-a hiadaptive -b adaptive -n adaptive"in/etc/rc.confpowerd_enable="YES"MUST NOT be present (both daemons share a pidfile; one would fail to start)performance_cx_lowest="C3"andeconomy_cx_lowest="C3"in/etc/rc.conf— enables useful idle saving without Cmax/C6-style USB-root resume riskhw.usb.no_suspend="1"in/boot/loader.conf— avoids USB autosuspend while the root filesystem is on USB
/opt/clawdie/npm-globalis recursively owned byclawdie:clawdie(build fails loud if not — chown runs at end ofinstall_live_npm_globals)- Agent CLI policy on the live image:
codexis installed via FreeBSD pkg and the binary is in/usr/local/bin/codexpiis installed via the bundled npm tarball and symlinked into/usr/local/bin/pigeminiMUST NOT be present on the live imageclaudeMUST NOT be present on the live image (skipped duringinstall_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, andclawdie-guiare present for tty-side graphical rescue testingxtermis present as a minimal Xorg rescue clientmousepadis present for the seeded text/plain MIME handler- root filesystem configured read-write in
/etc/fstab /tmpand/var/logare configured as explicit tmpfs mounts while/var/tmpremains 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
/tmpand/varare disabled - no swap entries in
/etc/fstab;dumpdev_enable="NO"so the boot path does not scan for swap - base
sshdis 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, andgitare installed,/usr/local/bin/bashand/usr/local/bin/zshare in/etc/shells, andclawdieuses bash as the login shell- Clawdie shell profiles put
/opt/clawdie/npm-global/binon PATH and repair the standard FreeBSD/usr/local+/usrcommand paths for SSH, TTY, terminal, andsu - clawdie; zsh sources packaged oh-my-zsh when present .cacheis redirected to/tmp/clawdie/cache- GPU pre-SDDM service present
- power-action policy present
networkmgrdoes not depend onsudo- native Wi-Fi firmware bundle is present
sudois absent from the live rootfs
Level 2: bhyve Verification Gate
Use bhyve as the standard pre-hardware gate when the ML350p lane is available. This is no longer just an opportunistic startup check; it is the default middle-stage verification between static artifact checks and physical hardware.
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
- USB boots.
clawdie_live_gpudetects display hardware and loads a conservative KMS path.- SDDM starts.
- Operator logs in at the SDDM greeter as
clawdie. - XFCE panel and bootstrap launcher appear.
- 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/tmpand/var/logare tmpfs mounts from/etc/fstab/var/tmpstays on the root filesystem~/.cacheis a symlink to/tmp/clawdie/cache/var/lib/xkbexists 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 -c "import PIL; print(PIL.__version__)"
bastille --help
mdo -u root bastille --help
For networking/UI:
- confirm the NetworkMgr tray icon appears
- confirm Firefox opens
- confirm
pcmanfmopens - confirm
mousepadopens a plain-text file - confirm panel power actions work for
clawdie - confirm
mdo -u root tailscale upis 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, confirmtailscale statusshows the node joined andssh clawdie@clawdie-liveworks from the tailnet - if on a multicast-friendly LAN, confirm
clawdie-live.localresolves from another machine - if a
wlandevice appears, confirm NetworkMgr can see it without any extrawifiboxlayer - if Wi-Fi is missing, collect
ifconfig,sysctl net.wlan.devices,pciconf -lv,usbconfig, and the Wi-Fi/firmwaredmesglines 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, thenradeonkmsonly ifamdgpudid not load - Intel
0x8086->i915kms - VMware
0x15ad->vmwgfx - NVIDIA
0x10de-> proprietary modules only if/boot/modules/nvidia.kois 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_pcion Linux) — FreeBSDrtsx(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
iichiddoes 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.
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
# 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:
pciconfusbconfigdevinfokldstatdmidecodelspciviapciutilslsusbviausbutils
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: throughhmt,psm,kbdmuxinstead. - 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
clawdielaunches Clawdie XFCE - XFCE panel and desktop appear
- hostname is set to
clawdie-live /is read-write,/tmpand/var/logare tmpfs, and/var/tmpstays on disk~/.cachepoints at/tmp/clawdie/cache/usr/local/etc/xdg/xfce4/xinitrcandclawdiexinitrc fallbacks are executablexinit/startx,clawdie-startx,clawdie-gui, andxtermare present for minimal Xorg rescue/startup checking/var/lib/xkbexists and XKB keymap compilation succeedsXDG_RUNTIME_DIRresolves to/var/run/user/<uid>clawdie_live_gpulog 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.localresolves on a multicast-friendly LANmdo -u root idsucceeds forclawdie- GSettings schemas and gdk-pixbuf PNG loader cache exist
/dev/dri/*is usable byclawdievia thevideogroup when DRM is present- NetworkMgr tray icon appears
- Firefox opens
mousepadopens plain-text filespi --helpworkstailscale versionworkstmux -Vworkspython3 -c "import PIL; print(PIL.__version__)"worksbastille --helpworkssudois 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