Three additions from pre-merge review:
1. .pkgnew config merge — pkgbase drops updated configs as /etc/*.pkgnew.
Find and merge them before rebooting so the 15.1 system boots with its
own configs, not 15.0-era ones.
2. Service health check — post-reboot verification now includes explicit
checks: colibri_daemon, postgresql, tailscaled, bastille jails, pfctl.
Version numbers matching is not enough — services must be running.
3. pkg autoremove — clean up orphaned packages the upgrade leaves behind.
Dry-run first, then remove.
Fleet nodes (USB/disk, built from release memstick) use freebsd-update —
one command, zero flags. OSA uses pkgbase, carrying the repo-editing +
IGNORE_OSVERSION complexity. Make the distinction visible before anyone
starts reading steps meant for the other path.
The node OS version changed after the upgrade, but the mother hive_nodes
row still shows the old freebsd_version. Re-running the probe + node_register
makes the upgrade visible to the scheduler.
Renumbered: 8→9 (vulnerability audit).
Four corrections from Codex review:
1. One-time caveat: OSVERSION/IGNORE_OSVERSION is for the boundary only.
Remove it after reboot — persisting would spoof the wrong version on
the next upgrade and silently pull mismatched packages.
2. IGNORE_OSVERSION=yes as the canonical idiom (does not require knowing
the exact __FreeBSD_version number).
3. ABI="FreeBSD:15:amd64" marked as redundant (it is already the default
on 15.x; OSVERSION is the actual lever).
4. Date format: DD.mon.YY → DD.mon.YYYY (matches eu-date-format convention).
Live BE renamed to 15.1-upgrade-25.jun.2026.
Two improvements from the live OSA upgrade run:
1. Boot environment rollback: step 2 (before any base changes) now creates
a BE with naming convention MAJOR.MINOR-upgrade-DD.mon.YY. pkgbase does
NOT auto-snapshot ZFS — this must be done manually. If the upgrade
misbehaves after reboot, bectl activate + reboot = instant rollback.
2. Cross-release override: pkgbase refuses to fetch 15.1 packages while
running 15.0 userland. Document the env OSVERSION=1501000 override
needed to cross the boundary.
Renumbered subsequent steps 2→3, 3→4, ..., 7→8.
Covers the case where df unchanged after rm -rf or cargo clean because
sanoid snapshots captured the deleted files. Documents the vacuum
procedure: identify holding snapshots, destroy them to reclaim space
immediately, or use sanoid --prune-snapshots for the gentler path.
Updates Pitfalls to acknowledge this as the exception to "never touch
sanoid-managed snaps."
Discovered 2026-06-24: cargo clean freed 5.5G but df showed 16G unchanged.
usedbysnapshots = 26.6G across 9 sanoid snapshots. Full vacuum freed 13G
(16G → 29G free, pool 80% → 72%).
Covers: canonical command with FEATURE_COLIBRI=YES, flag matrix with
cache dependencies, pre-flight checklist, build steps overview, tmux
usage for long builds, --live-default-password, and common pitfalls.
Distilled from 2026-06-22 build session on OSA.
Discovered 2026-06-22: zroot/home/clawdie was missing from sanoid config,
allowing 10 autosnaps from April to accumulate 23.6G of dead weight.
Skill covers: pool/dataset audit, sanoid coverage check, safe destroy
of orphaned snapshots, template reference, and pitfall avoidance.
Session-based operations with no interactive prompts. Covers:
- Session setup from provider.env
- Read (list, get by name, get by ID)
- Create (base64-encoded JSON, with collection)
- Update (get → modify → pipe to edit)
- Delete
- Upsert pattern (create if absent, update if exists)
- Rebuild authorized_keys from vault items
Proven working: full round-trip of key creation → vault
publish → read back → delete on OSA 2026-06-21.
truss traces every kernel call a process makes. Quick reference,
full walkthrough (start daemon→trigger→stop→analyze), common
daemon pitfalls and their truss signatures, ktrace alternative.
Proven debugging colibri-daemon jail-spawn Permission Denied:
found bare command names unresolved under daemon(8) PATH and
staging directory ownership issues.
Follow-up to #74. Two concrete fixes to the "identity wallpaper on join" step:
1. tmp policy: the join script hardcoded WP=/tmp/clawdie-wallpaper.png, passing
it to clawdie-wallpaper-gen and overriding the safe SCRATCH_DIR default that
9ae8d25 had just introduced (project-local tmp/ or app-owned cache). The
generator now prints its chosen path on stdout (human note → stderr) and the
join script captures it: WP=$(clawdie-wallpaper-gen). No host-global /tmp.
2. wallpaper actually applies: replaced the hardcoded
/backdrop/screen0/monitor0/workspace0/last-image with an enumeration over
every existing */last-image property (XFCE keys backdrops by connector name,
e.g. monitorHDMI-1, not monitor0), falling back to creating the default
property on first boot/headless, then xfdesktop --reload.
SKILL.md updated to document the stdout contract and multi-monitor wiring.
Validation: sh -n on both scripts; prettier@3 --check SKILL.md;
python3 scripts/layered_soul.py validate . — all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Panel indicator: add have() checks for nc/python3, warn on missing
deps instead of failing silently, distinct states for socket-down
vs no-response with actionable tooltip text
- Join Hive: generate and apply identity wallpaper on success as
visual 'you're in' confirmation via xfconf-query
- SKILL.md: document new behaviors
Sync the wallpaper helper and iso-visuals guidance with the project-local tmp policy, falling back to app-owned live cache paths when no project root exists.\n\nValidation: sh -n skills/iso-visuals/scripts/clawdie-wallpaper-gen.sh skills/iso-visuals/scripts/clawdie-join-hive.sh; npx --yes prettier@3 --check skills/iso-visuals/SKILL.md; python3 scripts/layered_soul.py validate .
Mirror the Clawdie ISO Join Hive and wallpaper helper hardening in the iso-visuals skill, fix the desktop Exec path, and clarify staged-helper versus wired-default behavior.\n\nValidation: sh -n skills/iso-visuals/scripts/clawdie-join-hive.sh skills/iso-visuals/scripts/clawdie-wallpaper-gen.sh; npx --yes prettier@3 --check skills/iso-visuals/SKILL.md; python3 scripts/layered_soul.py validate .
Three improvements for the Clawdie ISO first-boot desktop:
1. Panel health indicator (xfce4-genmon)
- polls colibri socket every 30s
- green/red dot + agent count + task count
- click to open colibri status in terminal
2. Identity wallpaper generator
- overlays hostname, Tailscale IP, Colibri port, FreeBSD release
- runs on first boot, caches result
- requires ImageMagick (add to ISO pkg list)
3. Join Hive launcher
- one-click agent registration in visible terminal
- checks daemon → vault creds → detect capabilities → register
- idempotent, safe to re-run
- pauses on result so operator reads before closing
All three scripts + skill.md + desktop entry in skills/iso-visuals/.
Real tailnet IPs and Telegram bot handles were being committed in docs/
memories/skills. Scrubbed all tracked markdown to ${VAR} placeholders; real
values now live in fleet.env (gitignored) and stay live via 'tailscale status'.
- add fleet.env.example (committed) + fleet.env (gitignored); .gitignore *.env
- AGENTS.md + HOST-MATRIX: masking convention so it can't recur
- also: domedog registered as Colibri agent (image-render/ffmpeg/build lane);
correct CAPABILITY-ROUTING example to real registered caps (domedog headless)
Past commits not rewritten (history moves to Codeberg at v1.0); this fixes HEAD.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move skills/freebsd/freebsd-cost-optimization.md to
skills/freebsd-cost-optimization/SKILL.md so the Colibri importer (skills/**/SKILL.md)
picks it up. Import smoke now loads 10 skills.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Creates the cross-harness Layered Soul repository skeleton while keeping hermes-soul as the Hermes-native Debby Linux backup.\n\nChecks: npx --yes prettier@3 --write touched docs/manifests