First Boot
Current ISO validation note: the live ISO path is moving to a QML installer followed by post-install
/setupin the Clawdie controlplane. Provider keys and Telegram are no longer install-time requirements. Thesetup.txtflow below documents the older non-interactive contract and will be rewritten after the current ISO live-install validation completes.
The first-boot model below is intentionally small. You edit a single
first-boot setup file (setup.txt), flash the USB, boot the
machine, and the
installer reads your file on first start. No interactive
out-of-the-box wizard, no autogenerated secrets you have to write
down later.
The first-boot setup file is versioned. If you do not set these yourself, the installer fills safe defaults:
SETUP_SCHEMA_VERSION=1ISO_RELEASE=v0.10.0ISO_GIT_COMMIT=SETUP_SCHEMA_VERSIONtracks the file format the installer understandsISO_RELEASErecords which Clawdie release the install media came fromISO_GIT_COMMITis optional exact build provenance
What you need
Section titled “What you need”- The Clawdie ISO (tags)
- A USB stick (16 GB+)
- A flashing tool (
dd, Etcher, Rufus — your call) - An OpenRouter account (the recommended bootstrap path; you can switch to direct provider keys later)
- A Telegram account and a bot token from @BotFather
- Your Telegram numeric user ID from @userinfobot
Optional: inspect first
Section titled “Optional: inspect first”If you do not know your disk names, pool layout, PF-facing interface names, or whether the machine already contains a Clawdie install, run inspect first from the live environment:
./scripts/inspect-system.sh --output /path/to/writable/mediaOn a full Clawdie repo checkout, npm run inspect -- --output ... is
just a convenience wrapper around the same shell script.
To write the suggested install/storage values straight back into your first-boot setup file:
./scripts/inspect-system.sh \ --output /path/to/writable/media \ --apply-setup /path/to/writable/media/setup.txtThat only fills blank or missing fields. It does not overwrite values you already chose explicitly.
To populate the hardware contract file directly:
./scripts/inspect-system.sh \ --output /path/to/writable/media \ --apply-system-env /path/to/writable/media/system.envThat fills blank or missing hardware fields in system.env such as:
SYSTEM_SCHEMA_VERSIONNETWORK_EXTERNAL_IFNETWORK_INTERNAL_IFTAILSCALE_IFZFS_POOLZFS_LAYOUTZFS_DATA_DISKSZFS_HOT_SPARESZFS_DISKSZFS_SPARE_DISKSZFS_PREFIXGPU_DEVICESND_DEVICE
That writes:
system.txt— a human summarysystem.env— hardware contract values the installer can use directlyinspect-facts.env— richer machine-readable inspect metadatasuggested-setup.txt— lines you can copy back intosetup.txt- raw artifacts such as
dmesg.txt,ifconfig.txt,zpool-status.txt,zfs-list.txt, andpf-interfaces.txt
The summary includes:
- detected disk device names
- observed ZFS pools, layouts, and datasets
- suggested
INSTALL_MODE - suggested
ZFS_LAYOUT,ZFS_DATA_DISKS, andZFS_HOT_SPARES - detected interface names you can later reuse for PF/network setup
The four lines
Section titled “The four lines”Open the first-boot setup file (setup.txt) in a text editor. The
required cognitive surface is four lines:
OPENROUTER_API_KEY=sk-or-v1-...TELEGRAM_BOT_TOKEN=123456:AA...TELEGRAM_ADMIN_ID=12345678ASSISTANT_NAME=AtlasThat is the minimum for a working install. Everything else in the first-boot setup file is either prefilled with a sensible default or optional. Leave any line you don’t care about blank — the installer will fall back.
What each line does
Section titled “What each line does”| Line | What it controls |
|---|---|
OPENROUTER_API_KEY | The LLM provider used for chat and compaction. |
TELEGRAM_BOT_TOKEN | The bot identity your assistant runs as. |
TELEGRAM_ADMIN_ID | The one Telegram account that can talk to it as operator. |
ASSISTANT_NAME | What your assistant calls itself in chat. It is display-only and does not rename shared DBs, datasets, or the service account. Blank → Clawdie. |
Optional fields worth knowing about
Section titled “Optional fields worth knowing about”You don’t have to fill these in. They exist because you might want them later or because some installs need them on day one.
Install mode
Section titled “Install mode”INSTALL_MODE=autoauto— detect an existing install and choose fresh vs upgradefresh— fail if an existing install is detectedupgrade— require an existing install and upgrade it in placerescue— require an existing install and attempt recovery/repair
auto is the default and the right starting point for most
operators. It also supports reinstall, upgrade, and rescue flows when paired
with system.env and existing ZFS metadata.
If you ran inspect first, system.txt will suggest the install mode
it thinks fits the machine right now.
Profile
Section titled “Profile”PROFILE=balancedeconomy, balanced, or quality. Maps to a coordinated bundle
of chat + fallback + compaction models. balanced is the prefilled
default. Switch only if you have a reason.
Time zone and hostname
Section titled “Time zone and hostname”TIMEZONE=Europe/LjubljanaHOSTNAME=TIMEZONE defaults to UTC. HOSTNAME defaults to clawdie unless you set it explicitly. It does not derive from ASSISTANT_NAME.
Storage layout
Section titled “Storage layout”ZFS_POOL=zrootZFS_LAYOUT=singleZFS_DATA_DISKS=1ZFS_HOT_SPARES=0ZFS_PREFIX=clawdie-runtimeThese fields declare the intended storage shape.
ZFS_POOL— pool name, usuallyzrootZFS_LAYOUT—single,mirror,raidz1, orraidz2ZFS_DATA_DISKS— number of disks in the main data layoutZFS_HOT_SPARES— standby disks reserved as hot sparesZFS_PREFIX— dataset root for the install
Defaults:
singleis the default because it matches the simplest one-disk installsingleis not the recommended long-running layoutraidz1is the recommended durable multi-disk shape once the operator opts in
Examples:
# Simple one-disk installZFS_LAYOUT=singleZFS_DATA_DISKS=1ZFS_HOT_SPARES=0
# Three-disk raidz1ZFS_LAYOUT=raidz1ZFS_DATA_DISKS=3ZFS_HOT_SPARES=0
# Four disks total: 3 in raidz1, 1 hot spareZFS_LAYOUT=raidz1ZFS_DATA_DISKS=3ZFS_HOT_SPARES=1The installer derives full dataset paths from these values. You do not type raw dataset paths into the first-boot setup file.
These storage declarations are also part of the long-term upgrade contract. The installer can later compare:
setup.txtoperator intentsystem.envhardware intent- persisted ZFS dataset metadata
For advanced operators, that metadata lives as ZFS user properties on
the root dataset <ZFS_POOL>/<ZFS_PREFIX>, using keys such as:
org.clawdie:install-uuidorg.clawdie:setup-schemaorg.clawdie:system-schemaorg.clawdie:iso-releaseorg.clawdie:iso-commitorg.clawdie:assistant-nameorg.clawdie:hostnameorg.clawdie:telegram-admin-hashorg.clawdie:zfs-layoutorg.clawdie:zfs-data-disksorg.clawdie:zfs-hot-spares
This is deliberate: the upgrade fingerprint lives with the data,
survives reflash, and can be inspected with native zfs get.
If you ran inspect first, it will already have written suggested storage lines based on:
- detected disk count
- observed ZFS pool topology
- existing pool/dataset state when present
Dashboard credentials
Section titled “Dashboard credentials”OPERATOR_EMAIL=you@example.comOPERATOR_PASSWORD=...Optional. If you set both, the dashboard is preconfigured. If you
leave them blank, the dashboard waits until you run
npm run set-operator -- <email> from the running system. Telegram
is your operator interface in the meantime.
Plaintext warning:
OPERATOR_PASSWORDlives in plaintext on the install media until you reformat it. The installer will warn you about this in the post-install summary. Reformat the USB before storing it or handing it to anyone else.
Headless / unattended access
Section titled “Headless / unattended access”For installs you don’t sit at the console for:
SSH_AUTHORIZED_KEY=ssh-ed25519 AAAAC3... you@laptopCLAWDIE_USER_PASSWORD=SSH_AUTHORIZED_KEY is the recommended way. Public keys are not
secrets, so plaintext on the USB is fine. When set, the installer
enables key-only SSH for the service user and disables password
SSH.
CLAWDIE_USER_PASSWORD is a fallback for console login or sudo,
used only if no SSH key is provided. Same plaintext warning as
above. There is no ROOT_PASSWORD field — root login is
locked by design. Use sudo from the service user.
Where The First-Boot Setup Lives
Section titled “Where The First-Boot Setup Lives”The flashed USB exposes a writable FAT32 config surface. Edit these files there:
setup.txtsystem.env
The installer reads those files on first boot.
Why this path works:
- it is writable from Windows, macOS, Linux, and FreeBSD
- it supports long API keys without console typing
- it works with the inspect loop naturally
- it matches the ISO repo’s existing “editable config on removable media” direction without requiring a second USB
Operator flow:
- Flash the USB.
- Reinsert it on your normal computer.
- Open the writable config surface.
- Edit
setup.txt. - Optionally leave
system.envblank and let inspect populate it. - Boot the target machine from that USB.
The installer treats:
setup.txtas operator intentsystem.envas hardware intent
Both files are versioned and can be compared against persisted ZFS metadata during later upgrade and rescue flows.
- Plug the USB into the target machine.
- Power on. Boot from USB (BIOS/UEFI key varies by hardware).
- The installer reads the first-boot setup and proceeds without prompting.
Expect first boot to take several minutes — the installer provisions databases, jails, and copies skills. The post-install summary tells you what’s ready and surfaces any warnings (plaintext passwords, unset optional fields).
After first boot
Section titled “After first boot”Talk to your assistant
Section titled “Talk to your assistant”Open Telegram, find the bot you registered, send /start. If your
TELEGRAM_ADMIN_ID matches, you’re talking to your operator
channel.
Set dashboard credentials (if you skipped them)
Section titled “Set dashboard credentials (if you skipped them)”If you left OPERATOR_EMAIL / OPERATOR_PASSWORD blank in the
first-boot setup:
npm run set-operator -- you@example.comYou’ll be prompted for a password (twice, no echo). The dashboard becomes available afterwards. This is first-set only — to rotate a password later, use the dashboard’s change-password flow.
Switch off OpenRouter
Section titled “Switch off OpenRouter”OpenRouter is the bootstrap path, not a permanent commitment. To move chat to a direct provider:
- Per chat:
/modelin Telegram lets you swap provider/model for a single chat. - System-wide: set
DEEPSEEK_API_KEYinprovider.env. The agent uses DeepSeek by default. Provider Fallback.
Reformat the install media
Section titled “Reformat the install media”If your first-boot setup contained any password fields
(OPERATOR_PASSWORD, CLAWDIE_USER_PASSWORD), the installer did
not delete the file (by design — operators have lost installs
to overzealous auto-wipes). Reformat the USB once you’ve confirmed
the install is healthy.
Troubleshooting
Section titled “Troubleshooting”Check the first-boot log and progress files first:
tail -100 /var/log/${AGENT_NAME}-firstboot.logcat /var/log/${AGENT_NAME}-firstboot.progressIf the install stopped after a named setup step, resume from that step:
cd /home/${AGENT_NAME}/clawdie-aijust install-from <step>For a full post-install verification pass, use the Fresh install checklist.
Reflashing later
Section titled “Reflashing later”Use INSTALL_MODE to choose how the installer treats an existing system:
auto— detect the existing install and choose the safest pathfresh— fail if an existing install is detectedupgrade— require an existing install and upgrade it in placerescue— require an existing install and attempt recovery/repair
Keep backups before upgrade or rescue work, especially when changing storage layout values.
Related
Section titled “Related”- ISO Install — image selection, USB writing, rebuild path.
- Operator Commands — what’s available in Telegram once your assistant is up.
- Provider Fallback — how the agent stays alive when a provider hits a usage cap.