<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-09-13T12:02:39+00:00</updated>
<entry>
<title>feat(install): default DNS over TLS off on the Proton tunnel links</title>
<updated>2026-09-13T12:02:39+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-09-13T12:02:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=2e303a07d1a6e4de85277a34669f8da61f7fdb6e'/>
<id>urn:sha1:2e303a07d1a6e4de85277a34669f8da61f7fdb6e</id>
<content type='text'>
The resolved drop-in pins DNSOverTLS=yes for every link. Proton VPN (proton0) and the static Proton WireGuard profiles (wgpvpn) push an in-tunnel resolver (10.2.0.1) that answers plain port 53 and never completes TLS on 853, so every lookup through the tunnel hung. The Proton client recreates its NetworkManager profile on each connect, so a per-profile setting can't stick.

NM pushes a [connection-tunnel-dot] default matched on those two interface names to resolved on every activation. Wifi and everything else keep the strict setting. Ratio and velox already carry the drop-in by hand. This makes a rebuild carry it too.
</content>
</entry>
<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>
</feed>
