<feed xmlns='http://www.w3.org/2005/Atom'>
<title>archsetup/scripts/testing/tests, branch main</title>
<subtitle>Builds a full dev workstation from a bare Arch Linux install.
</subtitle>
<id>https://git.cjennings.net/archsetup/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/archsetup/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/'/>
<updated>2026-07-21T04:44:35+00:00</updated>
<entry>
<title>test: fix the weak assertions from the S6/S7 audit</title>
<updated>2026-07-21T04:44:35+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-21T04:44:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=58904be957de0555dcd1f163890dcacb568e262a'/>
<id>urn:sha1:58904be957de0555dcd1f163890dcacb568e262a</id>
<content type='text'>
The Hyprland socket check passed a shell glob to `test -S`, which breaks at both edges: zero matches leaves the literal pattern and several instances pass multiple args, failing for reasons unrelated to the socket. It now resolves one socket with find -type s.

The gen_tokens degenerate-marker test asserted properties loose enough to pass on garbled output. It now pins the exact reconstruction as a characterization, with the impossible-input caveat stated, so any change to the branch surfaces.

The gallery tick count leaned on split-string omit-nulls arithmetic that happened to equal the match count. It now counts occurrences directly. gallery-widget-write-svg, the last uncovered public entry point, gets a Normal-case test.
</content>
</entry>
<entry>
<title>fix: order pacman safety hooks</title>
<updated>2026-07-19T00:46:05+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-19T00:46:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=be2277d0db1afa06c1a1ab468f70b34c8d98e0a1'/>
<id>urn:sha1:be2277d0db1afa06c1a1ab468f70b34c8d98e0a1</id>
<content type='text'>
Install snapshot and live-update hooks before mkinitcpio removal, migrate legacy paths, and cover the ordering invariant.
</content>
</entry>
<entry>
<title>feat(vpn): proton CLI replaces the GTK app, tailscale operator at install</title>
<updated>2026-07-02T23:16:52+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T23:16:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=158836ff433fdc51416f23d022a68a483b69603b'/>
<id>urn:sha1:158836ff433fdc51416f23d022a68a483b69603b</id>
<content type='text'>
The net panel's Tunnels view drives proton-vpn-cli, and the CLI and GTK app can't run concurrently, so the installer swaps them. tailscaled now enables with --now and the install grants operator to the primary user (brief retry — the daemon takes a moment to accept its socket), so tailscale up/down works without sudo from the panel. VM asserts the vpn stack, the retirement, and the OperatorUser pref (format verified against a live daemon).
</content>
</entry>
<entry>
<title>feat(packages): retire zoom, meetings open in the browser</title>
<updated>2026-07-02T21:50:49+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T21:50:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=b253fa0dd22a940d75d9e6c75179a2128168d27a'/>
<id>urn:sha1:b253fa0dd22a940d75d9e6c75179a2128168d27a</id>
<content type='text'>
The dotfiles zoom-web handler rewrites zoommtg:// links to the web client, so the AUR zoom package leaves the install. The retired-package VM assertion now covers blueman and zoom.
</content>
</entry>
<entry>
<title>feat(tooling): provision eask via user-local npm install</title>
<updated>2026-07-02T21:11:05+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T21:11:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=b9ff12704cb64e93c8275903dbddd70daf9cd99e'/>
<id>urn:sha1:b9ff12704cb64e93c8275903dbddd70daf9cd99e</id>
<content type='text'>
chime and linear-emacs shell out to eask but nothing installed it. The block runs npm install -g --prefix ~/.local as the user after the node tooling, so eask lands on PATH without root. A stowed .npmrc pins the same prefix in dotfiles. VM asserts both.
</content>
</entry>
<entry>
<title>feat(bluetooth): prove the fresh-install panel wiring in VM assertions</title>
<updated>2026-07-02T19:21:13+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T19:21:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=d60e59ef08a6532e60da14fb455efafa4086c78e'/>
<id>urn:sha1:d60e59ef08a6532e60da14fb455efafa4086c78e</id>
<content type='text'>
Phase 5 needed no new install code: the waybar module, keybind, and shared panel css ride the dotfiles hyprland tier the installer already stows, and sudoers is covered by the existing grant. I added hyprland-gated assertions instead: bt bins stowed executable, custom/bluetooth in the waybar config, the bt-panel bind in hyprland.conf, panel.css present. This closes the bluetooth-panel task and flips the spec to implemented.
</content>
</entry>
<entry>
<title>feat(bluetooth): retire blueman, assert the swap in VM tests</title>
<updated>2026-07-02T19:18:20+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T19:18:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=c659ab9b24716736390429a733e45c4ea688c13f'/>
<id>urn:sha1:c659ab9b24716736390429a733e45c4ea688c13f</id>
<content type='text'>
I dropped blueman from the desktop_environment bluetooth loop (bluez + bluez-utils stay) and added the VM assertions: bluetooth stack installed, blueman absent as the retirement regression guard. No new sudoers rule was needed for bt-priv, since the existing blanket grant already covers systemctl restart bluetooth.
</content>
</entry>
<entry>
<title>feat: install pre-pacman ZFS snapshot hook on ZFS-root systems</title>
<updated>2026-06-30T11:56:41+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-30T11:56:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=db045b2f8296f450bf29053ad66e708f00b48ca0'/>
<id>urn:sha1:db045b2f8296f450bf29053ad66e708f00b48ca0</id>
<content type='text'>
archsetup took sanoid from install-archzfs but never ported the pre-pacman snapshot hook, so a ZFS-root install had no transaction-triggered rollback point — the working setup only existed as a hand-placed script on velox, lost on reinstall. Add configure_pre_pacman_snapshots(): a PreTransaction pacman hook plus a self-pruning script that keeps the 10 most recent pre-pacman snapshots (sanoid ignores them — they aren't autosnap_ names). It's gated to ZFS-root and runs late in boot_ux, so the hook doesn't fire during the install's own package operations and the first snapshot is the fresh system.

The script ships as scripts/zfs-pre-snapshot, made ZFS_PRE_* env-overridable so the pruning logic is unit-testable. Unit tests drive it against a fake zfs (creates a snapshot, prunes the oldest past KEEP, ignores non-pre-pacman snapshots, honors the lockfile interval, warns on failure); a Testinfra test asserts the hook and script land on a ZFS install; the orchestrator test pins the new boot_ux substep.
</content>
</entry>
<entry>
<title>test(vm): assert the live-update guard + hook are installed</title>
<updated>2026-06-28T05:51:52+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-28T05:51:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=6ba103e484118c2803ec59a991f091c364a4e775'/>
<id>urn:sha1:6ba103e484118c2803ec59a991f091c364a4e775</id>
<content type='text'>
</content>
</entry>
<entry>
<title>test(archsetup): branch boot/backup checks on the ZFS boot path</title>
<updated>2026-06-25T23:52:46+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-25T23:52:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=d84ddbb80e00af4799ce8c69ddf7a717f3eb956e'/>
<id>urn:sha1:d84ddbb80e00af4799ce8c69ddf7a717f3eb956e</id>
<content type='text'>
The Testinfra boot and backup checks asserted btrfs behavior unconditionally, so they failed on a ZFS root once the ZFS VM path started running them. ZFS boots via ZFSBootMenu, not GRUB. archsetup skips the systemd-hook switch and the mkinitcpio rebuild on ZFS, and on a ZFS+virtio VM it never edits mkinitcpio.conf at all. Branch each check on the existing zfs_root/has_nvme fixtures: assert the ZFSBootMenu EFI binary on ZFS (GRUB on btrfs), gate the mkinitcpio.conf backup on archsetup actually editing the file, and check the console font in /etc/vconsole.conf on ZFS (the initramfs on non-ZFS).

Surfaced by the first full ZFS VM run, which completed archsetup cleanly (exit 0). These were the only 3 failures.
</content>
</entry>
</feed>
