Reported on AMD live USB: colibri_daemon blocked rc.d boot until Ctrl-C; XFCE still showed default wallpaper and missing panel/start icons. Stage Colibri but disable daemon at boot by default, validate daemon(8) rc.d supervision, regenerate all icon caches, install Clawdie start icon into hicolor, add a visual guard, and expand hw-report XFCE/Colibri diagnostics.\n\nChecks: sh -n build.sh scripts/stage-colibri-iso.sh live/operator-session/clawdie-xfce-session-inner live/operator-session/hw-report live/operator-session/clawdie-xfce-visuals-guard.sh; ./scripts/check-format.sh; git diff --check; stage-colibri smoke with dummy artifacts.
Codifies the markdown format Sam applied in bd94b87 / 30cf590 as a
project rule rather than per-file judgment. Prettier 3 defaults with
proseWrap=preserve (no prose reflow), printWidth=80, embedded code
formatting off so we don't touch fenced shell/JSON blocks.
.prettierignore scopes Prettier to active docs:
- excludes tmp/, cache/, node_modules/, build artifacts
- excludes CHANGELOG.md + RELEASE-NOTES-*.md (hand-formatted, rigid)
- excludes .archive/ and .opencode/ (historical / tooling internal)
- excludes bundled bootstrap.html
Reformatted 16 active .md files: padded markdown tables, blank line
before lists (CommonMark-strict), `*emph*` -> `_emph_`. No content
changes — diffs are all whitespace/alignment/emphasis style.
Verified: `npx prettier@3 --check '**/*.md'` reports all clean.
Build: not run — docs + tooling config only.
Tests: pass — prettier --check is green; git diff confirms no content
deletions, only formatting.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Follow-up cleanups after c9955c6 review:
- TESTING.md: replace two `find ... | head -1` checks with
`test -z "$(find ... -print -quit)"` so they actually fail the gate
when output is non-empty (the old form printed bad results and exited
0). Same shape applied to both the claude-code absence check and the
recursive ownership check.
- TESTING.md: add agent-CLI runtime probe (`pi`/`gemini`/`codex`
--version, explicit `claude` absence) and a runtime ownership probe
to the ASUS hardware section. If `gemini --version` fails, extend
the install_live_npm_globals case-statement with *gemini-cli*.
- BUILD.md + doc/LIVE-SESSION-REVIEW.md: stop listing `claude` in the
bundled-npm-globals enumeration. State the current live-image policy
explicitly (pi/gemini via npm, codex via FreeBSD pkg, claude
excluded — native deps have no FreeBSD binary).
- live/operator-session/clawdie-live-seed: add status_cmd. The default
rc.subr status checks for a pidfile and reports "not running" even
after a successful import, which is actively misleading for a
one-shot importer. Custom status_cmd tails the seed log so
`service clawdie_live_seed status` answers the question the operator
is actually asking ("did the import run?").
After reading clawdie.si and osa.smilepowered.org, Blender is recognized
as a first-class operator capability (parametric design → CAD/CAM → CNC
fabrication for OSA-style geodesic work; bpy as Python skill substrate),
not a desktop-spin leftover. Long-term home is the live USB.
For the next image build it moves off the live USB anyway — its
ffmpeg/libpulse/mesa-libs/boost surface would partially un-do the
lean-rootfs payoff (1.74 GiB saved by the earlier deferred-bundle move)
during early hardware validation. Held in pkg-list-disk-install-extras
with explicit "do not auto-prune" framing so a future audit doesn't
re-categorize it as desktop-spin cruft.
Package set changes:
packages/pkg-list-live-operator.txt
- blender removed
packages/pkg-list-disk-install-extras.txt
+ blender added (in a "Roadmap-essential (will return to live USB)"
section, separated from the desktop-spin leftovers)
+ file-header comment block distinguishing the two categories of
deferral with explicit "do not auto-prune blender" guidance
Doc changes:
BUILD.md "Packages Deferred to Disk Install"
- reframed: two distinct categories (desktop-spin leftover vs
roadmap-essential), with the osa.smilepowered.org link as the
authority for why blender qualifies
- table gains a "Category" column so leftover vs roadmap-essential
is visible at a glance
- explicit closing paragraph: blender's deferral is a *commitment*
to the CNC/parametric-fabrication roadmap, not a removal
README.md
- "Blender available on the live image" line replaced with one
describing blender as available in the offline repo for the
disk-deploy path, with rationale and pointer to BUILD.md
TESTING.md
- blender removed from live-image pkg static check
- blender removed from `command -v` post-boot smoke
- "What you should see" line updated to drop blender from the
live-image expectation
Net effect on next image build:
- smaller live USB (back to the lean target)
- no ffmpeg/libpulse re-introduction from blender's transitive set
- blender + bpy still flashed onto the USB image (in tmp/packages),
ready for the disk-install consumer when that path lands
- the strategic commitment to CNC/parametric work is now recorded
in the doc set, not just in conversation
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Include packaged oh-my-zsh for the optional zsh path and Blender for Python-capable 3D/operator workflows on the live image. Extend static and runtime checks so the rebuild proves both packages are present.
No image build run.
---
Build: pass — sh -n build.sh; sh -n firstboot/shell-system.sh
Tests: pass — git diff --check; pkg search confirms ohmyzsh and blender package names
Revise the pre-build tmpfs plan to mirror NomadBSD for /tmp and /var/log, keep /var/tmp persistent, and route the live user's cache through /tmp/clawdie/cache instead of a direct home tmpfs mount.
No image build run.
---
Build: not run — docs only
Tests: pass — git diff --check
Three plan adjustments after review of 7cb973c + 930dda2. All doc-only.
PF — drop the pflog stack entirely
Previous plan kept pflog_enable=YES to expose pflog0 for live
tcpdump. With no `log` keywords in the ruleset, the interface is
useless on first boot. Both pflog_enable and pflogd_enable now stay
at their NO defaults. Operator brings the stack up by hand when
debugging:
mdo -u root kldload pflog
mdo -u root ifconfig pflog0 create
mdo -u root tcpdump -ni pflog0
Static check inverted: assert pflog_enable / pflogd_enable are NOT
set to YES anywhere in rc.conf.
tmpfs — phased rollout
Previous plan added /tmp + /var/tmp + ~/.cache in one pass. We have
prior bugs from the stock memstick's blanket /tmp tmpfs overlay
(build.sh:741-742 disables tmpmfs=YES on purpose). A controlled
fstab tmpfs is different, but /tmp is load-bearing for Xorg, SDDM,
NetworkMgr, and screenshot tools — a small permission/mount-timing
issue produces confusing symptoms.
Plan is now:
Phase A (next build): ~/.cache only (biggest UX win,
contained scope)
Phase B (follow-up): /var/tmp + /tmp (after one clean
Phase-A hardware boot)
sshd — build-time fatal gate
Unconditional sshd_enable=YES is safe only because the drop-in
disables password + root auth. If the drop-in is missing, empty, or
installed at the wrong path, the default sshd config allows password
auth and combined with --live-default-password we'd ship a known-
credentials remote service.
Added a build.sh gate: after rc.conf is written, if sshd_enable=YES
then sshd_config.d/clawdie-live.conf must exist, be non-empty, and
contain both PasswordAuthentication=no and PermitRootLogin=no.
Otherwise build.sh exits non-zero. No path lands an sshd-on image
without the restrictive policy.
Implementation order recorded in LIVE-SESSION-REVIEW.md
Eight numbered steps for the next implementation sweep. Mirrors the
user's adjusted order so it survives session boundaries. Adds the
mousepad gap (M9) at step 7.
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Plan-only commit. Brings PF, RAM/tmpfs, and the build-flag gap into the
same pre-build doc set as the SSH and mDNS plans, so the next
implementation sweep has explicit targets.
doc/LIVE-SESSION-REVIEW.md gains three sections:
Pre-build plan: PF firewall baseline for the live USB
- Minimal permissive ruleset (pass out; pass in for icmp, dhcp,
ssh, mdns, tailscale udp 41641; default deny).
- No-disk-logging discipline: pf_enable=YES, pflog_enable=YES
(interface only, no writes), pflogd_enable=NO. Operator can flip
pflogd on post-disk-install if needed.
- Ships as live/operator-session/pf-live.conf; deliberately
separate from firstboot/shell-pf.sh which carries the
installed-system policy.
- Static + post-boot TESTING hooks.
Pre-build plan: targeted tmpfs for write-heavy paths
- /tmp (1G), /var/tmp (512M), ~/.cache (1G) on tmpfs.
- /var/log, /var/lib/sddm/state.conf, /etc/ssh/ssh_host_*,
authorized_keys, panel state stay on disk — with the reason for
each spelled out.
- Explicit non-decision: not doing unionfs root / "XFCE from RAM"
in this phase. UFS buffer cache covers hot reads; unionfs would
regress the persistence we just shipped; 8 GB RAM is tight for
a full mirror. Revisit when disk install + USB-removable mode
become a real requirement.
- fstab entries + ownership setup contract for build.sh.
Build-flag gap: --tailscale-auth-key
- Both BUILD.md and the SSH/mDNS plans reference the flag, but
build.sh does not parse it (verified: only --ssh-key is in the
argument loop, tailscaled_enable=YES is written unconditionally,
no auth-key plumbing).
- Implementation contract: parse flag, drop key into a build-time
0600 secret file, install a one-shot rc.d service that runs
`tailscale up --auth-key=...` after tailscaled and then deletes
the key file and self-disables.
- The key must never appear in build-manifest.json or build.cfg;
only its presence (boolean) is recorded.
BUILD.md gains three short operator-facing subsections under "Useful
Build Modes" parallel to the existing SSH key note and mDNS note:
PF firewall on the live USB (summary + pointer)
Targeted tmpfs for write-heavy paths (summary + pointer)
Known build-flag gap (acknowledges the doc-vs-build
mismatch and tells the operator
the manual `mdo -u root
tailscale up` workaround)
Suggested implementation order (from the user) — recorded here in case
it slips between sessions:
1. mDNS + SSH + PF plan (this commit completes the plan side)
2. implement SSH key live path
3. implement mDNS
4. implement safe PF baseline
5. implement low-risk tmpfs (/tmp, /var/tmp, ~/.cache)
6. implement --tailscale-auth-key
7. then build
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Third access path for the live USB, sitting below Tailscale MagicDNS but
above the bare DHCP-IP fallback:
ssh clawdie@clawdie-live (Tailscale MagicDNS — preferred)
ssh clawdie@clawdie-live.local (mDNS / Avahi — always-on LAN)
ssh clawdie@<dhcp-ip> (last-resort fallback)
The implementation cost is small because Avahi is already in the live
dependency closure. The packaged ssh.service file advertises _ssh._tcp
on port 22, so no Avahi config edits are needed — we just enable the
daemon, add nss_mdns for outbound .local resolution, and patch
nsswitch.conf.
Doc changes (no code yet, implementation lands on the next build):
- BUILD.md gets a "LAN discovery (mDNS / Avahi)" subsection alongside
the SSH key note, with the three-path priority order, the
implementation contract, the scope-discipline reminder that
Clawdie internal services stay on home.arpa (not .local), and the
multicast-hostile-network caveat.
- doc/LIVE-SESSION-REVIEW.md gets a parallel "Pre-build plan: mDNS /
.local discovery for the live USB" section with the requirements
table (matching the format used for the SSH plan), the concrete
package/rc.conf/nsswitch contract, and Level-1 static-check hooks
for TESTING.md to consume once code lands.
Scope discipline carried explicitly in both docs:
home.arpa = Clawdie internal DNS (ai/cms/git/<tenant>)
.local = mDNS LAN discovery for the live USB only
RFC 6762 reserves .local for mDNS; mixing it with internal service
names breaks both. The next-build implementation must not move internal
services to .local.
Package choice fixed:
avahi-app (already transitive; list explicitly to pin contract)
nss_mdns (small, not currently in closure)
Not mDNSResponder — less stack churn and avahi already ships the
ssh.service advertisement we want.
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Confirms three policy points before the implementation pass lands:
1. sshd runs unconditionally on the live USB (sshd_enable=YES even when
--ssh-key is absent). Auth is pubkey-only, so an empty authorized_keys
simply means nobody can log in — predictable and harmless.
2. sshd listens on all interfaces, not bound to tailscale0. Operators
without a configured tailnet still need a LAN SSH path to pull logs.
The restrictive auth policy (no passwords, no root) carries the
security weight, not interface scoping.
3. Tailscale coupling is the preferred path: when --tailscale-auth-key
is also passed at build time, the live USB autojoins the tailnet on
first boot and is reachable as `clawdie@clawdie-live` via MagicDNS.
The LAN path remains a fallback. Recommend passing both flags for
hardware testing.
Doc changes:
- BUILD.md "SSH key note for live-debug builds" — adds the always-on /
all-interfaces policy, the Tailscale coupling section with a combined
build command, and an explicit implementation contract (authorized_keys
perms, sshd_config.d drop-in path and contents, manifest fingerprint).
- doc/LIVE-SESSION-REVIEW.md "Pre-build plan: live SSH access for log
collection" — same clarifications structured as implementation-ready
requirements, plus a distribution-safety note explaining when to bake
--ssh-key into a build and when not to.
No code changes. Implementation lands on the next build.
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Record the plan to reuse the existing --ssh-key flag for live USB SSH access, including operator key discovery/generation commands and the desired no-password/root-disabled SSH policy.
No image build run.
---
Build: not run — docs only
Tests: pass — git diff --check
Small follow-up after 9e64a82's Firefox + deferred-bundle work landed.
Trims wavering language from docs and historical-banners the QML phase 4
doc to match the pattern used elsewhere.
Changes:
- BUILD.md
Audit-candidates row for `bitchx`: drop the "Probably belongs in
the disk-install bundle above; verify before next build" line.
bitchx stays on the live USB; size impact is negligible and the
operator may want a quick chat tool on a fresh boot.
- doc/LIVE-SESSION-REVIEW.md
Remove the L7 "Firefox IS in package list — L5 concern mitigated"
block. Both the cross-ref to L5 (unrelated to browser packages)
and the finding itself were redundant noise once the Firefox swap
landed.
Past-tense the audio expectation: "After the bundle move +
Chromium→Firefox swap (both landed in 9e64a82)..." replaces the
forward-looking phrasing.
Minor: fix broken-line sentence in the Post-84358ac review header.
- TESTING.md
Drop "not the older Lumina-first installer flow" — Lumina is fully
archived; the comparison is no longer informative.
- firstboot/gui/PHASE4-INTEGRATION-COMPLETE.md
Add a historical banner matching the pattern used on
ROADMAP-v1.0.0.md and docs/PHASE4-TEST-REPORT-06.APR.2026.md. The
doc still accurately describes the abandoned Qt6/QML installer
under firstboot/gui/qml-installer/; the banner makes that clear.
Not touched (verified accurate or intentional):
- BUILD.md "Provider keys, Telegram, and disk deployment are deferred
on this branch" — accurate present state.
- README.md "later phases" / "intentionally deferred" wording — accurate.
- FIRSTBOOT.md "deferred to runtime" in shell-deploy error handling —
accurate.
- ROADMAP-v1.0.0.md, RELEASE-NOTES-v0.9.0.md, docs/PHASE4-TEST-REPORT-*
— already banner-marked as historical.
- BUILD.md's two remaining Chromium references — both explain *why*
Firefox was chosen (the chain it avoids). Useful context, kept.
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Replace Chromium with Firefox in the live/operator package closure and XFCE launchers, move the deferred desktop bundle into pkg-list-disk-install-extras.txt, and keep that extras list in pkg_list_all() without installing it onto the live rootfs.
No image build run; another agent will build and hardware-test.
---
Build: pass — sh -n build.sh
Tests: pass — git diff --check; package-list smoke confirms live excludes chromium/deferred extras
BUILD.md gains two new pieces under "Packages Deferred to Disk Install":
- **Audio surface implications.** Replaces the abstract "drops most of
the PulseAudio transitive surface" sentence with the confirmed
pipewire + pulseaudio + libpulse pull-in table. simplescreenrecorder
is the worst offender (drags both pulseaudio AND pipewire daemons).
xfce4-mixer is the remaining live-USB libpulse puller after the
bundle move via gstreamer1-plugins-pulse.
- **Decisions queued for next build.** Captures four decisions in one
table so the build agent picks them up in one sweep:
- decided: chromium → firefox (multi-agent confirmation)
- decided: split deferred bundle into pkg-list-disk-install-extras.txt
- open: simplescreenrecorder — defer or drop outright?
- open: PulseAudio installable as option on disk-install target?
The chromium-essentials line in the same doc now flags the queued swap
inline so the source-of-truth list doesn't lie about what current pkg
lists contain.
doc/SESSION-STAB-HANDOFF.md audio section collapses from an
investigation to a pointer at BUILD.md (since the investigation is now
confirmed). The pkg-rquery snippet stays as a validation tool for the
next image; updated to also grep for pipewire.
No code changes — pkg-list files and build.sh untouched.
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Replace the abstract deferred-bundle pull-in table with measured direct package and installed sizes so the live USB slimming decision is easier to review.
---
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Add a new section to BUILD.md capturing the package-set split between
the lean live operator USB and the eventual full installed operator
desktop. No code changes — this is the authoritative "what we will
deploy to disk" reference so the bundle is not lost between commits
once it leaves pkg-list-live-operator.txt.
Three tables:
- Packages deferred to disk install (the office/media/comms bundle
inherited from the earlier desktop-spin direction).
- Audit candidates that stay on the live USB for now but should be
revisited (xfce4-mixer, pcmanfm, bitchx).
- Currently essential packages that belong on both live USB and disk
install, listed for completeness so the lean/full split stays honest.
Build: pass — sh -n build.sh
Tests: pass — git diff --check
The xfce-operator-usb live USB has been failing with the documented
FreeBSD-specific LightDM+XFCE login-loop bug: ConsoleKit session
activation fails on FreeBSD, X session exits rc=1, LightDM restarts
the greeter, loop. The FreeBSD forum thread tracking this exact symptom
remains unresolved upstream as of January 2026.
NomadBSD — the FreeBSD live-USB spin we already borrow ideas from —
switched from SLiM to SDDM for the same class of reasons. SDDM does
not depend on ConsoleKit the same way LightDM does, and its QtQuick
greeter shares a toolkit with the QML installer we already maintain.
This commit:
- Drops lightdm/lightdm-gtk-greeter, adds sddm in pkg-list-xfce.
- Replaces live/operator-session/lightdm-live.conf with
live/operator-session/sddm.conf, installed to
/usr/local/etc/sddm.conf.d/50-clawdie-live.conf.
- Drops autologin by default. The live USB now boots to the SDDM
greeter; the operator logs in as clawdie with the documented live
password (quindecim when built with --live-default-password).
Autologin can be re-enabled per machine by setting User= and
Session= under [Autologin] in the installed sddm.conf.d file.
- Flips rc.conf to sddm_enable / display_manager=sddm in build.sh,
firstboot/shell-system.sh, and firstboot/shell-desktop.sh.
- Updates the clawdie_live_gpu rc.d ordering directive from
BEFORE: lightdm to BEFORE: sddm so the GPU detector still runs
before the display manager.
- Removes the LightDM placeholder-config workaround in build.sh
(SDDM has no equivalent pkg-script requirement).
- Removes the unused live/installer-session/lightdm-live.conf
(build.sh hasn't referenced it since the move to XFCE).
- Sweeps LightDM references in README, BUILD, TESTING, SHELL-MODULES,
SHELL-ARCHITECTURE, and MODULE-MANIFEST. Leaves historical
validation findings in doc/NOMADBSD-XFCE-USB-POC.md alone (those
document prior LightDM-era inspections and should remain accurate
for that point in time).
Build: pass — sh -n build.sh, sh -n firstboot/shell-system.sh,
sh -n firstboot/shell-desktop.sh
Tests: pass — git diff --check
Document head verification before builds, add post-flash filesystem and XKB runtime probes, and include the read-write root/no tmpfs overlay expectations in the hardware acceptance checklist.
---
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Document that the same curl resume-and-retry pattern applies on FreeBSD, and point TESTING at FLASHING as the canonical Linux and FreeBSD guide.
---
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Add a dedicated flashing guide for Linux and FreeBSD, make gzip-to-dd streaming the documented default for published .img.gz artifacts, and link the safety checklist from README, BUILD, and TESTING.
---
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Refresh build, testing, requirements, and historical design docs for the current XFCE operator USB path, including pre-LightDM GPU detection, mdo-based operator actions, and the published quindecim workflow.
---
Build: pass — sh -n build.sh
Tests: pass — git diff --check
Drop the remaining TAILSCALE_AUTHKEY example from BUILD.md so active docs consistently describe Tailscale authentication as a later running-USB step.
---
Build: not run — doc-only correction
Tests: not run — doc-only correction
Remove the build-time warning for a missing Tailscale auth key and align docs with the operator USB flow where Tailscale authentication happens later from the running USB alongside other operator key collection.
---
Build: not run — warning removal while existing build is running
Tests: not run — docs/script messaging only
BREAKING CHANGE: Removes --target and --gpu-driver flags, unified ISO for all use cases
## Phase 0: GPU Fix + Unified ISO
### Core Changes
**GPU Package Installation (FIXES CRITICAL GAP):**
- Add clawdie_shell_nvidia_install() function to shell-nvidia.sh
- NVIDIA drivers now installed after detection (previously only configured)
- Works offline (USB packages) or online (pkg install)
- Resolves issue where rc.conf was set but driver not installed
**Unified ISO Architecture:**
- Remove --target flag from build.sh (no more vps/baremetal branching)
- Remove --gpu-driver flag from build.sh (runtime detection instead)
- All packages included on every ISO (desktop + all GPU drivers)
- Single image works on VPS, baremetal, and cloud
**Runtime Detection:**
- Add shell-desktop.sh for display detection at firstboot
- VPS/cloud: no display → lightdm disabled (headless)
- Baremetal: display detected → lightdm enabled (Lumina desktop)
- GPU detection always runs, installs correct driver version
**Sudo Unification:**
- Replace all doas references with sudo across entire codebase
- Update AGENTS.md with system configuration guidelines
- Update all documentation (BUILD.md, README.md, REQUIREMENTS.md, etc.)
- Admin panel now uses sudo for privileged operations
### Files Modified
**Core System:**
- build.sh: Remove target/gpu-driver logic, unified package selection
- firstboot/firstboot.sh: Add desktop detection module
- firstboot/shell-nvidia.sh: Add package installation function (+33 lines)
**New Files:**
- firstboot/shell-desktop.sh: Display detection and desktop enablement
- packages/pkg-list-nvidia-all.txt: All three NVIDIA driver versions (390/470/590)
- .opencode/plans/phase0-gpu-fix-unified-iso.md: Implementation plan
**Documentation:**
- PLAN-UNIFY.md: Update Step 3 for unified approach
- REQUIREMENTS.md: Simplify (no target choice), update for sudo
- BUILD.md: Update for unified ISO, sudo commands
- README.md: Update installation instructions
- AGENTS.md: Add system configuration section (sudo standardization)
- ADMIN-PANEL.md: Update privileged operations to use sudo
- CLAWDIE-SHELL.md: Update example commands to sudo
- CLAWDIE-ISO-REFACTORED.md: Update access paths to sudo
- REFACTOR-SUMMARY.md: Update permissions section to sudo
### Benefits
**Simplicity:**
- One build command: ./build.sh (no flags needed)
- One ISO to test and maintain
- No wrong choices for users
- No documentation explaining target differences
**Flexibility:**
- VPS can use GUI via VNC (wayvnc always available)
- Baremetal can run headless (disable lightdm)
- Repurpose hardware without reinstall
- All GPU drivers available for any hardware
**Technical:**
- Fixes critical GPU driver installation gap
- Runtime detection replaces build-time decisions
- Disk overhead: ~650MB (1-2% of 50GB - acceptable)
- No runtime overhead on VPS (services disabled by detection)
### Testing Required
- [ ] Build unified ISO: ./build.sh
- [ ] Test on VPS (no display): lightdm disabled, packages installed
- [ ] Test on baremetal (display): lightdm enabled, Lumina boots
- [ ] Test on NVIDIA hardware: driver installed and loaded
- [ ] Test sudo commands work without password prompts
- [ ] Verify all doas references removed
- Change default FEATURE_TAILSCALE from NO to YES
- Add build-time warning if TAILSCALE_AUTHKEY not set
- Update firstboot wizard: Tailscale moves to screen 2
- Add summary screen showing Tailscale status
- Update shell-tailscale.sh to handle missing auth key gracefully
- Update BUILD.md with new recommended/optional flow
User experience:
- With auth key: Tailscale auto-connects (secure)
- Without auth key: Warning shown, build continues (public SSH)
- Wizard allows enabling/disabling with clear warnings
No breaking changes - existing builds still work.
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>
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>