# Clawdie ISO

**XFCE-based FreeBSD operator USB image.**

A persistent operator USB with XFCE as the live-image baseline:

- bootable USB image
- stable XFCE desktop for the live operator environment
- browser available immediately
- Colibri's agent harness staged with the control plane (under the colibri
  umbrella; staged by default — `FEATURE_COLIBRI=NO` is an internal build-time
  escape hatch, e.g. for a build host without a colibri checkout, not a
  user-facing option)
- `pi` retained as a spawnable agent backend (bundled npm global)
- Tailscale available immediately
- Colibri control-plane daemon staged and enabled as the live-USB rc.d service
  (`service colibri_daemon`)
- `service clawdie` reserved as the deployed-system service name for disk/server
  installs; the live USB stays on the lighter Colibri control-plane path

**Current validation target:** bootable dev image with `BUILD_CHANNEL=dev` and
bundled Clawdie-AI from `main`. Public release images should use
`BUILD_CHANNEL=release` and a pinned Clawdie-AI tag.

---

## What You Get

Boot a USB and land in an operator environment:

- FreeBSD 15.x base system
- XFCE desktop via SDDM interactive login
- pre-SDDM live GPU detection for Intel, AMD/ATI, VMware, and NVIDIA auto-detection with a universal driver lane
- Firefox browser on the live image
- Tailscale on the live image
- broad native Wi-Fi firmware bundle on the live image
- Bundled npm globals on the live image, including `pi`
- `bash` as the default operator shell, with `zsh` + packaged oh-my-zsh also available on the USB
- Offline package repository bundled on the USB image, including `blender`
  for the parametric-design / CAD/CAM / CNC fabrication roadmap (installed
  on the disk-deploy path, not on the live USB during early hardware
  validation — see `BUILD.md` "Packages Deferred to Disk Install")
- Clawdie-AI tarball with offline `node_modules`
- Static bootstrap page launched from the desktop
- desktop power actions allowed for `wheel` users, including `clawdie`

Provider keys, Telegram, browser sign-in, and disk deployment are intentionally
deferred on this branch.

### Runtime service split

```text
Live operator USB
  SDDM/XFCE desktop
    └── colibri_daemon      # lightweight control plane, enabled on USB
          ├── colibri CLI / colibri-tui
          ├── colibri-mcp       # MCP bridge for editor/assistant clients
          └── agent harness     # Colibri's bundled agent (staged with the
                                # daemon); pi available as a spawnable backend

Deployed disk/server system
  service clawdie           # target operator service name
    └── persistent Clawdie host duties: health, inventory, watchdog,
        credentials, and Colibri-backed agent orchestration
```

Use Colibri names when talking about the live USB control plane. Use Clawdie
service names when talking about the installed/deployed host.

---

## Desktop Strategy

XFCE is the live USB baseline because it is stable, lightweight, and well tested
on FreeBSD. That is a build-time choice for the operator USB, not a permanent
policy for every installed system.

Later disk deployment should grow a desktop profile step. The live USB can stay
XFCE-based while the install-to-disk flow lets the operator choose a target
profile such as:

- XFCE — default, conservative desktop
- KDE Plasma — optional fuller desktop, pulled during deployment
- Headless — no local desktop for server-style installs

The live USB should therefore avoid names and docs that make Xorg or XFCE look
like the whole product contract.

### `clawdie-gui` instead of `clawdie-startx`

The user-facing rescue command should be `clawdie-gui`, not `clawdie-startx`.
`startx` describes one X11 implementation detail; `gui` describes the operator's
intent: start or recover the graphical Clawdie operator session.

Today `clawdie-gui` can still launch the same XFCE/Xorg rescue path. In the
future it can dispatch to the right graphical profile without changing operator
instructions. Existing internal scripts may keep calling the lower-level XFCE
session wrapper, but docs should teach `clawdie-gui` as the stable command.

---

## Pre-Install Requirements

Build host:

- FreeBSD 15.x
- `pkg`, `curl`, Node/npm, `sudo`
- root or `sudo` for image assembly (`mdconfig`, mount, bootcode)
- 150 GB free build space recommended
- 64 GB USB key minimum
- 128 GB USB key recommended

Optional but recommended:

- Tailscale account and auth key (`tskey-auth-...`)

Tailscale is **recommended**, not mandatory. If no auth key is supplied, the ISO
still builds and the live USB still boots normally. You can either bake
`--tailscale-auth-key` for one-shot first-boot join or run `mdo -u root tailscale up`
later from the live session.

---

## Quick Start: Build Image

```sh
git clone https://code.smilepowered.org/clawdie/clawdie-iso.git
cd Clawdie-ISO

# Full build: fetch FreeBSD, packages, Clawdie-AI, then assemble image.
sudo ./build.sh
```

Useful alternatives:

```sh
# Fetch/cache only. Does not assemble an image.
./build.sh --fetch-only

# Reuse cached packages and image inputs.
# Safe for pinned tags/commits. For moving refs, build.sh caches by resolved commit.
sudo ./build.sh --skip-fetch

# Fetch packages but reuse the cached FreeBSD memstick image.
sudo ./build.sh --skip-memstick-fetch

# Dev/test image: set live user clawdie password to quindecim.
sudo ./build.sh --live-default-password

# Validation build from current Clawdie-AI main.
sudo ./build.sh --clawdie-ref main

# Release build from a pinned Clawdie-AI tag.
BUILD_CHANNEL=release sudo ./build.sh --clawdie-version 0.10.0
```

The build prints provenance similar to:

```text
ISO     : <iso-version>-dev
FreeBSD : 15.x-RELEASE amd64
Clawdie : main
Clawdie commit: <sha>
```

It also writes `build-manifest.json` into the image and onto the installed
system under `/usr/local/share/clawdie-iso/`.

### Why `quindecim`

Artifact names use a short Latin codename for the FreeBSD major line they were
built on. For FreeBSD `15`, that codename is `quindecim`, so:

```text
clawdie-quindecim-0.11.0.img
```

means:

- `clawdie` — project name
- `quindecim` — Latin for `15`, matching the FreeBSD 15 build line
- `0.11.0` — the ISO product version (set in `build.cfg`)

Per-build provenance (build date and the `clawdie-iso`, `colibri`, `zot`, and
`clawdie-ai` commits) lives in `build-manifest.json`, not the filename.

Small reference for the current naming convention:

```text
0  = nulla / nihil / zero
1  = unus
2  = duo
3  = tres
4  = quattuor
5  = quinque
6  = sex
7  = septem
8  = octo
9  = novem
10 = decem
11 = undecim
12 = duodecim
13 = tredecim
14 = quattuordecim
15 = quindecim
16 = sedecim
17 = septendecim
18 = duodeviginti
19 = undeviginti
20 = viginti
21 = viginti unus
22 = viginti duo
23 = viginti tres
24 = viginti quattuor
25 = viginti quinque
26 = viginti sex
```

Notes:

- For `0`, Classical Latin did not have one universal everyday numeral word
  equivalent to modern `zero`; `nulla` and `nihil` are both common
  “none/nothing” stand-ins, while `zero` is later Latin.
- For `21+`, Latin number phrasing has multiple acceptable styles. The forms
  above are intentionally simple and readable for image naming.

---

## Write to USB

Published artifacts are compressed as `.img.xz`. Stream them directly into
`dd`; do not unxz first unless you specifically need the raw image file.

Download on Linux or FreeBSD with resume and retries:

```sh
curl -fL --continue-at - --retry 5 --retry-delay 5 --progress-bar -O \
  https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.11.0.img.xz
curl -fL --retry 5 --retry-delay 5 -O \
  https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.11.0.img.xz.sha256
```

Linux:

```sh
sha256sum -c clawdie-quindecim-0.11.0.img.xz.sha256
set -o pipefail 2>/dev/null || true
xz -dc clawdie-quindecim-0.11.0.img.xz | dd of=/dev/sdX bs=4M status=progress conv=fsync && sync
sync
```

FreeBSD:

```sh
HASH=$(awk '{print $1}' clawdie-quindecim-0.11.0.img.xz.sha256)
sha256 -c "$HASH" clawdie-quindecim-0.11.0.img.xz
xz -dc clawdie-quindecim-0.11.0.img.xz | dd of=/dev/daX bs=1M status=progress conv=fsync && sync
sync
```

Replace `/dev/sdX` or `/dev/daX` with the whole USB device, not a partition.

On **Windows**, use Rufus or balenaEtcher — both read `.img.xz` directly (no
manual decompression). See [FLASHING.md](FLASHING.md) for the step-by-step, the
full safety checklist, and the raw `.img` variant.

If you built with `--live-default-password`, both the tty and the SDDM greeter
accept `clawdie` / `quindecim`. The live USB expects an interactive login at
the greeter; autologin is not part of the current operator-USB plan.

The image is sparse on the build host. `build.sh` prints both logical image size
and allocated size; write the logical image to a USB key large enough for it.

---

## Boot the USB

1. Boot from the USB image.
2. `/usr/local/etc/rc.d/clawdie_live_gpu` runs before SDDM and selects a conservative live graphics path.
3. SDDM starts; the operator logs in as `clawdie` and the Clawdie XFCE session launches.
4. A desktop launcher opens the static Clawdie bootstrap page.
5. Confirm the NetworkMgr tray icon appears in the bottom panel, shows interfaces, and can open/join Wi-Fi if needed.
6. Confirm the bottom panel launchers work: Whisker menu, Firefox, pcmanfm, terminal, and volume mixer.
7. Verify the core operator tools:

   ```sh
   pi --help
   tailscale version
   firefox
   tmux -V
   python3 --version
   bastille --help
   mdo -u root bastille --help
   test -f /usr/local/share/fonts/dejavu/DejaVuSansMono.ttf
   ```

8. Tailscale can either autojoin from a baked `--tailscale-auth-key` build or
   be joined later by hand with FreeBSD `mac_do`:

   ```sh
   mdo -u root tailscale up
   ```

Disk deployment, upgrade, rescue, and full Clawdie bootstrap are later phases
on this branch.

---

## Documentation

- **[BUILD.md](BUILD.md)** — build flags, cache behavior, and test flow
- **[FLASHING.md](FLASHING.md)** — Linux, FreeBSD, and Windows (Rufus/Etcher) USB flashing
- **[REQUIREMENTS.md](REQUIREMENTS.md)** — build host and deployment requirements
- **[NETWORKING.md](NETWORKING.md)** — PF, Tailscale, `warden0`, and setup access
- **[TESTING.md](TESTING.md)** — bhyve and hardware validation procedures
- **[FIRSTBOOT.md](FIRSTBOOT.md)** — installed-system firstboot module pipeline (philosophy, dependency graph, per-module reference)
- **[docs/VPS-MIGRATION.md](docs/VPS-MIGRATION.md)** — VPS/cloud deployment path

---

## Current Limitations

- USB persistence work is not implemented yet on this branch.
- Disk deployment is intentionally deferred.
- NVIDIA on the live USB auto-detects the card and routes it through the universal driver lane; this lane is pending hardware validation (see `doc/NVIDIA-UNIVERSAL-HANDOFF.md`), so it still falls back to integrated/open graphics when no `nvidia.ko` loads.
- Provider/model, Telegram, and full `Clawdie-AI` service bootstrap are intentionally deferred.

---

**Last updated:** 13.jun.2026
