Commit graph

275 commits

Author SHA1 Message Date
18586d3f09 Harden firstboot scripts: POSIX fixes, quoting, offline pkg path
- shell-system.sh: exit → return in sourced module (would kill firstboot)
- maintenance-mode.sh: replace bash += with POSIX concat, fix subshell
  scope in pipe-to-while-read (vdev_status/failed_disks were always
  empty), quote all $POOL_NAME and $disk expansions
- build-vps.sh: portable _sed_i() wrapper for FreeBSD/Linux
- firstboot.sh: set -eu; set USB_PKG_PATH to SHARE/packages so offline
  package repo works after HDD boot (was defaulting to /mnt/media)
- firstboot-vps.sh: remove plaintext password log, check loader.efi
  exists before EFI copy

Integration test: PASS (7/7 modules)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
4c78af00f9 Tests pass for tmp/ restructuring; fix sparse-copy size display
Integration test: PASS (7/7 modules, state handoff OK)
Build --skip-fetch: PASS (7.3GB image at tmp/output/, DOS/MBR valid)

Add sync before du -sh so sparse image size reports correctly
instead of showing 512B.

Build: PASS | Tests: PASS (integration + build --skip-fetch)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
60c35361a0 Make ISO builds cleaner by default (Sam & Codex)
---

Build: FAIL | Tests: FAIL — not run (deferred)
2026-06-04 20:04:22 +02:00
33bcb648de Harden upgrade staging: validate, propagate failures, safe copy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
2ea21ddc9e Deploy: branch on boot mode, preserve customizations on upgrade (Sam & Claude)
shell-deploy.sh now branches on CLAWDIE_BOOT_MODE:
- install: existing fresh path (extract tarball, seed .env, install-all)
- upgrade: extract to staging dir, run skills-engine applyUpdate()
  for three-way merge preserving customizations, restore existing
  .env, then install-all for db migrations. Falls back to overwrite
  + migrateExisting() if no .nanoclaw/ present.

Overwrite fallback preserves data/, store/, logs/, groups/,
.nanoclaw/, node_modules/ across the upgrade.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
7ae1e694f9 Align VPS firstboot with modular pipeline (Sam & Claude)
Rewrite vps/firstboot-vps.sh as phase-1 only: partition disk,
create ZFS pool "clawdie", install FreeBSD base, inject firstboot
payload, install bootloader, reboot. On first HDD boot the standard
firstboot.sh modular pipeline runs (zfs detect, wizard, gpu, pkg,
ssh, env, system, tailscale, deploy).

Pre-baked clawdie.conf values get written to build.cfg with
TARGET=cloud so the wizard is skipped. Pool named "clawdie"
(not zroot) for pool detection compatibility.

Remove duplicate clawdie-vps-setup.sh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
8cc7b2dcaf Wire ZFS pool detection into firstboot pipeline (Sam & Claude)
New shell-zfs.sh module: detects existing clawdie pool, presents
boot mode menu (install/upgrade/maintenance/shell). Runs as first
step in firstboot.sh before wizard. Upgrade mode loads existing
.env and skips wizard. Maintenance mode exec's to maintenance-mode.sh.

Also: fix POSIX herestrings in maintenance-mode.sh, fix paren
mismatch in snapshot age calc, add nda (NVMe) to disk detection
patterns across all ZFS scripts for FreeBSD 15.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
5e0649dcdc Wire skills-engine init into install pipeline (Sam & Claude)
Add .nanoclaw/ and bootstrap artifact checks to shell-deploy.sh
post-install verification. Complements the new skills-init step
added to clawdie-ai's install pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
8e280cb40c Merge origin/main: ZFS pool migration, VPS support, Syncoid docs (Sam & Claude)
Resolve conflicts keeping modular shell-*.sh firstboot architecture
from implementation branch. New from main:
- firstboot/zfs-pool-detect.sh, zfs-pool-migrate.sh, maintenance-mode.sh
- vps/ directory (build-vps.sh, migration scripts)
- docs/SYNCOID-SETUP.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00
74e7b583d0 Clarify Tailscale auth key prompt (Sam & Codex)
Explain reusable key for host + jails and seed auth key into .env.

---

Build: FAIL — not run

Tests: FAIL — not run
2026-06-04 20:04:22 +02:00
d65ef7c33f Add Tailscale firstboot module (Sam & Codex) 2026-06-04 20:04:21 +02:00
fdacdb0327 Harden bhyve tests and home.arpa defaults (Sam & Codex)
---

Build: not run | Tests: not run
2026-06-04 20:04:21 +02:00
16252fb67c iso: sync clawdie-ai v1.0.2 + codex baseline (Sam & Codex) 2026-06-04 20:04:21 +02:00
536f9ea90c docs: update integration env var count 2026-06-04 20:04:21 +02:00
28f2100a47 feat: add local LLM choice and model seeding 2026-06-04 20:04:21 +02:00
780a3a3c7f docs: expand git/forgejo checks in testing 2026-06-04 20:04:21 +02:00
4559e6fc5c docs: add forgejo checks to testing 2026-06-04 20:04:21 +02:00
c3c6a74879 docs: add forgejo port detail 2026-06-04 20:04:21 +02:00
f1a7f5b8b4 docs: note optional forgejo in firstboot 2026-06-04 20:04:21 +02:00
93a690db85 feat: enable forgejo by default in firstboot 2026-06-04 20:04:21 +02:00
e3a2b1113a Document isolated bhyve bridge for tests (Sam & Codex) 2026-06-04 20:04:21 +02:00
6da6e6e9fa fix(bhyve): isolate VM network on dedicated bhyve0 bridge (10.99.0.0/24)
Moves bhyve VMs off warden0 (jail bridge) to avoid ARP/routing conflicts
with running agent jails. Auto-picks unused tap interface, adds PF NAT
idempotently, cleans up tap on exit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
9817a04a2c Clarify vmm device checks in host preflight (Sam & Codex) 2026-06-04 20:04:21 +02:00
92873b5203 Link fresh-install checklist from testing guide (Sam & Codex) 2026-06-04 20:04:21 +02:00
15962d782e Add host preflight for bhyve readiness (Sam & Codex) 2026-06-04 20:04:21 +02:00
ed09223233 Add commit attribution policy (C&C) 2026-06-04 20:04:21 +02:00
74752134c1 feat(build): bake new agent config vars into ISO image
build.cfg now uses ${VAR:-} pattern so env vars take precedence,
enabling cloud builds with arbitrary agent config via environment.

build.sh step 6 now injects all new fields (AGENT_GENDER,
PI_TUI_PROVIDER, PI_TUI_MODEL, API keys, Telegram, embeddings)
into the baked build.cfg inside the image.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
e46d955527 feat: make firstboot agent-name-agnostic for multi-agent deployments
Derive AGENT_NAME from ASSISTANT_NAME instead of hardcoding "clawdie".
Database names, users, and identity vars now follow the agent name.

Add configurable fields to build.cfg and shell-env.sh:
- AGENT_GENDER, PI_TUI_PROVIDER, PI_TUI_MODEL
- ZAI_API_KEY, OPENROUTER_API_KEY, EMBED_BASE_URL, EMBED_MODEL
- TELEGRAM_BOT_TOKEN, FEATURE_TELEGRAM (pre-bakeable for cloud)

Add gender selection to baremetal wizard (bsddialog radiolist).
Update bhyve-test.sh with --name flag, tap0/bridge auto-setup,
sparse disk reuse, and reduced default disk size (25G).

Tested: dry-run env generation produces correct Mevy config
(agent_name=mevy, db=mevy, provider=zai, model=glm-5).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
46028a7e6d fix: locale-safe date in build.sh + dynamic ISO detection in bhyve-test.sh
- build.sh: force LC_TIME=C so date +%b always outputs "Mar" not "Mar."
  Prevents double-dot filenames (e.g. 30.mar..2026.img) on sl_SI locale
- bhyve-test.sh: auto-detect newest baremetal .img or accept path as $1
  Removes hardcoded filename that breaks after each new build

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
702909c3c7 feat(scripts): add build-and-log.sh — build ISO + publish HTML log
Wraps build.sh, captures stdout+stderr with tee, generates a styled
HTML page matching the site's dark theme (DM Mono terminal block,
status badge, duration). Publishes two copies:
  - /docs/iso-build-log.html  (always latest)
  - /docs/iso-build-YYYY-MM-DD.html  (dated archive permalink)

Usage: sudo ./scripts/build-and-log.sh [build.sh args...]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
0caa9004f6 feat(firstboot): resume/reset flags, checkpoint guards + move bhyve scripts
firstboot.sh:
- Set SHELL_{GPU,NVIDIA,PKG,ENV,DEPLOY}_TEST=1 before sourcing modules
  (prevents double-execution on source — same bug fixed in integration-test)
- Add --resume: run_step() skips steps already recorded in progress file
- Add --reset: clears progress file, starts over from scratch
- Add --help
- Wizard tracked as checkpoint so --resume skips re-prompting the user
- run_step() helper: guard → run → mark done in one call

scripts/bhyve-test.sh (was tmp/bhyve-test-setup.sh):
- Moved to tracked scripts/ directory (tmp/ is gitignored)
- Timeout 300→1800s (full install is 20–25 min, not 5)

scripts/run-bhyve-test.sh (was tmp/run-bhyve-test.sh):
- Moved to scripts/, log output redirected to logs/ (also gitignored)

BUILD.md, TESTING.md, IMPLEMENTATION-PLAN.md:
- Update all bhyve script references to scripts/bhyve-test.sh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
ec69aa817d fix(test): suppress double-execution and mock tarball in integration test
Each shell module guards auto-run with SHELL_*_TEST env vars but the
integration test wasn't setting them, causing every module to execute
twice (once on source, once on explicit call).

Fixes:
- Set SHELL_{ENV,PKG,GPU,NVIDIA,SYSTEM,DEPLOY}_TEST=1 before sourcing
- Mock CLAWDIE_TARBALL with a real tar.gz of the pre-populated test dir
  so the deploy module can extract + verify without needing the ISO
- Redirect shell-system stdout+stderr to /dev/null (service enables
  write "does not exist" to stdout on a headless host)

All 6 modules now execute exactly once, cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
26010f0e41 fix: sync integration-test and docs to shell-*.sh rename
integration-test.sh still sourced old clawdie-shell-*.sh names after
the rename in 66484dc. BUILD.md and TESTING.md referenced /tmp/ (system)
instead of ./tmp/ (repo-local) for bhyve-test-setup.sh. Add /tmp/ to
.gitignore.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
5f99178683 docs: Complete documentation for v0.9.0 shell modules
Updated IMPLEMENTATION-PLAN.md:
- Mark Phase 1 (shell modules) complete: 26.mar.2026
- Mark all 5 tasks (1.1-1.5) as  COMPLETE
- Add Phase 2 status section (integration & testing)
- Reference TESTING.md for test procedures

Created TESTING.md (comprehensive guide):
- Level 1: Module integration test (5 min, offline)
- Level 2: Full bhyve boot test (20-25 min, interactive)
- Boot sequence & expected output
- Troubleshooting guide (VM won't boot, bsdinstall hangs, etc)
- Test results checklist
- CI/CD integration notes

Created SHELL-MODULES.md (implementation reference):
- Module index (7 modules, 1,500 LOC)
- Detailed documentation for each module:
  * shell-gpu.sh (Intel/AMD/NVIDIA/VMware detection)
  * shell-nvidia.sh (Driver version selection)
  * shell-pkg.sh (Repo config + USB cache seeding)
  * shell-env.sh (.env generation + secrets)
  * shell-system.sh (rc.conf + hostname + services)
  * shell-ssh.sh (SSH keys + passwords)
  * shell-deploy.sh (Tarball extraction + install-all)
- Execution order and state handoff
- POSIX compliance notes
- Individual module testing examples

Updated BUILD.md:
- Add "Testing the Built ISO" section
- Link to TESTING.md for procedures
- Note module integration test and bhyve boot test

This completes the documentation for v0.9.0 Phase 1
(implementation) and provides clear guidance for Phase 2 (testing).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
d28d38b49f impl: Complete all 5 shell modules for v0.9.0 installer
Implements critical firstboot orchestration:
- shell-gpu.sh: GPU detection (Intel i915kms, AMD amdgpu, NVIDIA, VMware vmwgfx)
- shell-nvidia.sh: NVIDIA driver version selection (590/470/390 per GPU)
- shell-pkg.sh: Package repository config + Bastille cache seeding
- shell-env.sh: .env generation with secrets and jail IP allocation
- shell-deploy.sh: Clawdie-AI tarball extraction + npm run install-all

All modules:
- POSIX-compliant (no bash-isms)
- Proper error handling and validation
- Comprehensive logging to /var/log/clawdie-firstboot.log
- Progress tracking to /var/log/clawdie-firstboot.progress
- Environment variable overrides for testing

Unblocks firstboot.sh which was calling undefined functions.
Ready for end-to-end installation testing on bhyve VM.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
01cbe6e962 refactor: replace XFCE/MATE/KDE with Lumina across all files
- Create packages/pkg-list-lumina.txt with Lumina desktop environment packages
- Delete pkg-list-xfce.txt, pkg-list-mate.txt, pkg-list-kde.txt
- Remove desktop-installer from pkg-list-desktop-base.txt
- build.cfg: DEFAULT_DESKTOP=lumina (sole supported DE)
- build.sh: use pkg-list-lumina.txt instead of pkg-list-xfce.txt
- BUILD.md: update DEFAULT_DESKTOP comment
- CLAWDIE-ISO.md: add deprecation notice, update all DE references to Lumina only

Lumina is the sole supported FreeBSD-native desktop environment as per
LUMINA-INTEGRATION.md and CLAWDIE-ISO-REFACTORED.md specifications.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
53d83b26c0 chore: Switch default domain from .local to .internal, bump to v0.9.0
- Update default agent domain: clawdie.local → clawdie.internal
- Avoids mDNS conflicts and uses RFC-compliant .internal TLD
- Update baremetal wizard prompt to show .internal example
- Bump CLAWDIE_VERSION from 0.8.2 to 0.9.0 (cloud/baremetal + SSH support)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
74e8374d59 firstboot: Update wizard with SSH key and experimental disclaimer
- Add welcome screen with experimental build disclaimer
- Add SSH public key input field to baremetal wizard
- Export SSH_PUBLIC_KEY to environment
- Call clawdie_shell_ssh_setup in module sequence (after pkg, before env)

Wizard now collects: name, domain, timezone, SSH key
Users can optionally provide SSH key to enable passwordless auth.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
d2513243e4 firstboot: Add shell-ssh.sh module and restore shell-system.sh
- Create new shell-ssh.sh module for SSH key installation and password setup
  * Install SSH public keys to authorized_keys (root + clawdie)
  * Configure sshd: disable password auth if key provided, enable if not
  * Set system user passwords (auto-generate or use provided)
  * Save emergency root password to root/.firstboot-emergency-password
- Restore shell-system.sh (was accidentally overwritten during rename)

Enables secure SSH-key-first access with password fallback.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
17f0259d6d build: Add SSH key and system password support
- Add --ssh-key flag for providing SSH public key at build time
- Add --root-password and --clawdie-password flags for custom system passwords
- Update build.cfg with SSH_PUBLIC_KEY, ROOT_PASSWORD, CLAWDIE_USER_PASSWORD
- Bake all security-related vars into ISO for firstboot access

Enables secure passwordless SSH auth and custom password provisioning.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
954dcebee2 refactor: Rename clawdie-shell-*.sh to shell-*.sh (remove redundant prefix)
- Rename all modules: clawdie-shell-{func}.sh → shell-{func}.sh
- Update references in firstboot.sh and installerconfig
- Update self-detection case statements in each module
- Reduces naming redundancy and improves clarity

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
0353ccb9b2 installerconfig: Glob chmod +x for all clawdie-shell-*.sh modules
- Remove individual chmod for legacy gpu-detect.sh (no longer called)
- Replace with loop glob over clawdie-shell-*.sh pattern
- Ensures all present and future shell modules are executable

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
d6d9c7906d firstboot/clawdie-shell-pkg.sh: Fix USB path from /mnt/media to SHARE-relative
- Remove hardcoded USB_MOUNT_POINT=/mnt/media
- Remove USB_PKG_PATH based on mount point
- Add SHARE (default: /usr/local/share/clawdie-iso)
- Add USB_PACKAGES (default: \${SHARE}/packages)
- Update all references to use SHARE-relative paths:
  * clawdie_shell_pkg_write_clawdie_usb_conf()
  * clawdie_shell_pkg_seed_cache()

Path now resolves at install time from actual ISO payload location,
not a hardcoded mount point that may not exist.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
9bec1992e1 firstboot/clawdie-shell-gpu.sh: Add cloud target bypass
Add early return for cloud deployments before any GPU detection logic.
Cloud VMs have no real GPU hardware, so skip pciconf detection entirely.
Mark [GPU] COMPLETE in progress file and return cleanly.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
ef17278a8a firstboot/firstboot.sh: Rewrite as clean orchestrator with cloud/baremetal branching
- Replace 265-line monolithic script with clean dispatcher
- Remove legacy eval \$(sh gpu-detect.sh) pattern
- Remove commented-out package install
- Remove inline tarball extraction
- Add cloud/baremetal branching:
  * Cloud: validate pre-baked ASSISTANT_NAME, AGENT_DOMAIN, TZ
  * Baremetal: bsddialog wizard for simple inputs only
- API keys deferred to web UI on first desktop login (left blank in .env)
- Source all clawdie-shell-*.sh modules at top
- Call module functions in sequence: gpu, nvidia, pkg, env, system, deploy

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
8a0418b23c build.sh: Add --target flag, cloud args, VARIANT IMAGE_NAME, pkg_list_all branch, bake runtime vars
- Add argument parsing for --target, --assistant-name, --domain, --tz
- Validate TARGET (cloud|baremetal) and enforce cloud requirements
- Replace GPU_SUFFIX logic with VARIANT-based IMAGE_NAME generation
  * Cloud: clawdie-iso-cloud-24.mar.2026.img
  * GPU: clawdie-iso-{amd,intel,nvidia}-24.mar.2026.img
  * Auto: clawdie-iso-baremetal-24.mar.2026.img
- Update pkg_list_all() with cloud branch (headless, no desktop, no GPU)
- Bake TARGET, GPU_DRIVER, ASSISTANT_NAME, AGENT_DOMAIN, TZ into ISO

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
b430d9053c build.cfg: Add TARGET, ASSISTANT_NAME, AGENT_DOMAIN, TZ defaults
Add deploy target configuration and cloud pre-bake variables.
Cloud builds accept these via CLI flags; baremetal leaves them blank
for interactive collection via bsddialog wizard.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
b8f3bb4042 firstboot/clawdie-shell-nvidia.sh: Extract NVIDIA driver version from GPU_DRIVER
Add early check in clawdie_shell_nvidia_detect(): if GPU_DRIVER is pre-baked as
nvidia-590, nvidia-470, or nvidia-390, extract version number and set
NVIDIA_DRIVER_VERSION env var for unattended mode.

Logic:
- Case match GPU_DRIVER (nvidia-590|nvidia-470|nvidia-390)
- Set DETECTED_GPU=nvidia and NVIDIA_DRIVER_VERSION to extracted version (e.g., "470")
- Existing clawdie_shell_nvidia_select_version() already bypasses bsddialog when
  NVIDIA_DRIVER_VERSION is set (L71-74)

Benefit: Automates NVIDIA driver version selection when pre-baked at build time,
eliminating the interactive bsddialog menu in firstboot. Combined with GPU
pre-bake logic, enables fully unattended firstboot for GPU-specific ISO variants.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
451672d7d9 firstboot/clawdie-shell-gpu.sh: Pre-bake bypass when GPU_DRIVER set
Add early check in clawdie_shell_gpu_detect(): if GPU_DRIVER is pre-baked
(set via build.cfg at ISO build time), skip live pciconf detection and proceed
directly to kld_list configuration.

Logic:
- Check if GPU_DRIVER env var is non-empty
- Map GPU_DRIVER to kld modules (intel→i915kms, amd→amdgpu, nvidia-*→nvidia-modeset nvidia)
- Write kld_list to rc.conf (idempotent)
- Mark GPU detection complete; return early

Benefit: Eliminates variable hardware detection at firstboot. rc.d/kld reads
kld_list from rc.conf early in boot (REQUIRE: NETWORKING), before
clawdie-firstboot service runs (REQUIRE: NETWORKING LOGIN), so driver is live
when Lumina starts. Guarantees ONE reboot instead of risking TWO.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00
0dd5402d6e build.sh: --gpu-driver parametrization + payload baking + IMAGE_SIZE fix
Major changes enable 6 GPU-specific ISO variants with pre-baked driver configuration:

1. Argument parsing: Add --gpu-driver flag with validation (intel|amd|nvidia-{590,470,390}|vesa)
2. IMAGE_NAME: Add GPU suffix to output filename:
   - clawdie-iso-intel-24.mar.2026.img (with --gpu-driver intel)
   - clawdie-iso-24.mar.2026.img (without flag, auto-detect)
3. pkg_list_all(): Conditional GPU package selection based on GPU_DRIVER
4. Payload baking (Step 6): Append GPU_DRIVER to build.cfg on ISO so firstboot
   can skip live pciconf detection—driver is pre-baked in kld_list at boot time
5. Fix IMAGE_SIZE usage: Replace hardcoded 25G with "${IMAGE_SIZE}" variable

Result: Firstboot reads GPU_DRIVER from build.cfg, writes kld_list to rc.conf,
and rc.d/kld loads driver early in boot (REQUIRE: NETWORKING) before clawdie-firstboot
service runs—guaranteeing ONE reboot instead of risking TWO.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-04 20:04:21 +02:00