---
name: clawdie-freebsd
description: Set up Clawdie on FreeBSD using Bastille-managed jails with the Warden runtime. Creates ZFS datasets, provisions controlplane and db jails, configures Telegram, and starts the service. Triggers on "freebsd setup", "jail setup", "clawdie install", "freebsd jail".
---

# Clawdie FreeBSD Setup

Complete setup of Clawdie on FreeBSD 15 using Bastille-managed jails with the Warden runtime model. This skill covers the full path from bare FreeBSD to a running control-plane.

**Principle:** When something is broken or missing, fix it. Don't tell the user to go fix it themselves unless it genuinely requires their manual action (e.g., creating a Telegram bot). If a dependency is missing, install it. If a service won't start, diagnose and repair.

**UX Note:** Use `AskUserQuestion` for all user-facing questions.

**Attribution:** Clawdie is a fork of [NanoClaw](https://github.com/openclaw/nanoclaw) by [Gavriel](https://github.com/openclaw), part of the [OpenClaw](https://github.com/openclaw/openclaw) ecosystem by [Peter Steinberger](https://github.com/steipete).

## Prerequisites

- FreeBSD 15.0-RELEASE or later
- ZFS root pool (typically `zroot`)
- Root access or sudo privileges
- Internet connection

## Workflow

This skill orchestrates the other infrastructure skills in sequence. For each step, check if it's already been done before running.

### Step 1: Host Prerequisites

```bash
freebsd-version         # Must be 15.0-RELEASE+
zpool status zroot      # Must be ONLINE
sysctl net.inet.ip.forwarding  # Must be 1
```

Install base packages on the host:

```bash
sudo pkg install node24 npm git python312 py312-uv bastille sanoid
npm install -g @mariozechner/pi-coding-agent
```

Enable forwarding:

```bash
sudo sysrc gateway_enable="YES"
sudo sysctl net.inet.ip.forwarding=1
```

### Step 2: ZFS Dataset Layout

Delegate to `/warden-zfs` to create:

- `zroot/clawdie-runtime`
- `zroot/clawdie-runtime/jails/controlplane`
- `zroot/clawdie-runtime/jails/db`

### Step 3: Host Networking

Delegate to `/bastille-network` to create persistent `warden0` bridge at `192.168.100.1/24`.

Delegate to `/warden-pf` to configure PF NAT rules for jail egress.

### Step 4: Control-Plane Jail

Delegate to `/warden-bootstrap` to create the thick VNET `controlplane` jail:

- Jail: `controlplane`
- Hostname: `ai.clawdie.si`
- IP: `192.168.100.100/24`
- Bridge: `warden0`
- Gateway: `192.168.100.1`

### Step 5: Database Jail

Delegate to `/postgres-memory` to provision the `db` jail:

- Jail: `db`
- Hostname: `db.clawdie.si`
- IP: `192.168.100.2/24`
- PostgreSQL 18.1 with `allow.sysvipc=1`

### Step 6: Sanoid Snapshot Policy

Delegate to `/sanoid` to configure automated snapshot retention for both `controlplane` and `db` datasets.

### Step 7: Clawdie Code Deployment

```bash
git clone https://codeberg.org/Clawdie/Clawdie-AI.git /home/clawdie/clawdie-ai
cd /home/clawdie/clawdie-ai
npm install
cp .env.example .env
```

### Step 8: Telegram Bot Setup

AskUserQuestion: Do you have a Telegram bot token?

If not:

> 1. Open Telegram and search for `@BotFather`
> 2. Send `/newbot` and follow prompts
> 3. Copy the bot token

Add `TELEGRAM_BOT_TOKEN=<token>` to `.env`.

Configure provider key (OpenRouter, Anthropic, or Claude subscription).

Run `npm run auth` to validate Telegram connectivity.

### Step 9: Build and Service

```bash
npm run build
```

Create rc.d service:

```bash
sudo tee /usr/local/etc/rc.d/clawdie << 'RCEOF'
#!/bin/sh

# PROVIDE: clawdie
# REQUIRE: LOGIN DAEMON NETWORKING
# KEYWORD: shutdown

. /etc/rc.subr

name="clawdie"
rcvar="clawdie_enable"
command="/usr/local/bin/node"
command_args="/home/clawdie/clawdie-ai/dist/index.js"
pidfile="/var/run/clawdie.pid"
clawdie_chdir="/home/clawdie/clawdie-ai"
clawdie_user="clawdie"

load_rc_config $name
run_rc_command "$1"
RCEOF
sudo chmod +x /usr/local/etc/rc.d/clawdie
sudo sysrc clawdie_enable=YES
sudo service clawdie start
```

### Step 10: Milestone Snapshot

```bash
sudo zfs snapshot zroot/clawdie-runtime/jails/controlplane@setup-complete-$(date +%d-%b-%Y | tr '[:upper:]' '[:lower:]')
```

### Step 11: Verification

```bash
npm run doctor
service clawdie status
jls
tail -f logs/clawdie.log
zfs list -t snapshot -r zroot/clawdie-runtime
```

Test: Send a message to the Telegram bot.

## Troubleshooting

**Jail won't start:** Check `bastille list`, verify `ifconfig warden0`, check `sudo pfctl -sr`.

**Service fails:** Check `logs/clawdie.error.log`. Common: missing `.env`, missing token, permissions.

**Build fails (better-sqlite3):** Install `gmake pkgconf`, then `npm rebuild better-sqlite3`.

**Network issues in jail:** Run `/warden-health` to diagnose bridge, PF, and forwarding state.

**PostgreSQL won't init:** Verify `allow.sysvipc=1` in jail config. See `/postgres-memory` skill.
