aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* test(archsetup): branch boot/backup checks on the ZFS boot pathCraig Jennings25 hours2-7/+37
| | | | | | 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.
* fix(archsetup): run reflector during install to avoid mirror stallsCraig Jennings29 hours1-0/+15
| | | | | | The base image ships the full unsorted worldwide mirrorlist (hundreds of mirrors), and archsetup only configured reflector's timer, so the install ran every download against that list. pacman then stalled for many minutes on a slow or unresponsive mirror during the package installs. archsetup now runs reflector once before the heavy installs, curating a few fast recently-synced HTTPS mirrors and refreshing the databases against them. The run is bounded by `timeout` and non-fatal, so a flaky mirror-status service falls back to the base list instead of blocking the install. Surfaced by the ZFS VM test path, where a worldwide-list mirror stalled a full run at the ditaa/JRE download.
* fix(archsetup): keep pacman.conf world-readable for AUR buildsCraig Jennings31 hours1-0/+7
| | | | | | User-level makepkg reads /etc/pacman.conf to resolve dependencies, so a root-only file makes every AUR build (starting with yay) fail with "could not be read: Permission denied". A current archangel ISO ships the base pacman.conf as 0600. archsetup already edits the file (ParallelDownloads, Color, multilib), so it now chmods it back to 0644, the Arch default, before the AUR installer runs. The ZFS VM test path surfaced this on a fresh archangel base. The older btrfs base shipped it 0644.
* fix(archsetup): clear informant news hook before pacman runsCraig Jennings31 hours1-0/+11
| | | | | | An archangel-installed base ships informant, which registers a pacman PreTransaction hook (AbortOnFail) that blocks every package transaction until Arch news is marked read. archsetup's first transaction (the keyring reinstall) tripped it and the script halted at the bootstrap step. archsetup now marks all news read up front with `informant read --all` so the keyring, refresh, and install steps proceed. The --all flag marks without printing or prompting. A bare `informant read` is interactive and would hang an unattended run. The guard is a no-op when informant isn't installed. The new ZFS VM test path surfaced this. Its base image comes from a current archangel ISO that includes informant, and the older btrfs base predated it.
* test(archsetup): add FS_PROFILE selector for ZFS VM coverageCraig Jennings33 hours6-19/+105
| | | | | | | | | | The VM harness only built one btrfs base image, so every ZFS-conditional check in the Testinfra suite skipped and the ZFS install path went untested in automation. I added an FS_PROFILE selector (btrfs default, zfs) so `make test FS_PROFILE=zfs` can target a ZFS root. init_vm_paths derives the image name from FS_PROFILE and validates it. btrfs keeps the legacy unsuffixed archsetup-base.qcow2 so existing images and invocations are untouched. The zfs profile gets archsetup-base-zfs.qcow2. create-base-vm.sh picks archsetup-test.conf vs the new archsetup-test-zfs.conf (FILESYSTEM=zfs, NO_ENCRYPT=yes for an unattended install), and the Makefile resolves the matching image for its base-VM check. The archsetup run config stays shared. archsetup reads no filesystem key. It detects ZFS from the live root via is_zfs_root, so the ZFS branch fires on its own once the base image is ZFS. The design doc is reconciled to that: no separate archsetup-vm-zfs.conf, and the non-ZFS profile is btrfs, not ext4. Building the ZFS base image and running the ZFS sweep green is next.
* docs(design): plan ZFS VM test coverage + bare-metal runner migrationCraig Jennings33 hours2-0/+121
| | | | | | | | Adds a design note for building a ZFS base VM via archangel with a filesystem profile selector (so make test covers the ZFS install path, currently only exercised on bare metal), migrating run-test-baremetal.sh to key auth and the Testinfra sweep, and then deleting the dead shell-sweep functions. Links it from the bare-metal migration follow-up.
* docs(todo): close the Testinfra validation taskCraig Jennings35 hours1-1/+4
| | | | | | Final fresh make test passed green (96 passed, 10 skipped) with Testinfra as the authoritative post-install validator. Records the end-state and the three bugs the work surfaced and fixed.
* fix(testing): raise the install monitor timeout to 150 minutesCraig Jennings37 hours2-2/+5
| | | | | | | | A full archsetup install with heavy AUR builds (vagrant and its git-cloned installers) can run past the old 90-minute monitor cap on a slow mirror. When that happened the run stopped monitoring mid-install and validated a half-installed system, producing spurious late-step failures. Raise MAX_POLLS from 180 to 300 (90 -> 150 minutes) so a slow-but-healthy install completes.
* test(archsetup): make Testinfra the authoritative validator (P3 cutover)Craig Jennings42 hours3-39/+71
| | | | | | | | | | | | | run-test.sh no longer runs the shell run_all_validations sweep; the Testinfra pytest sweep now drives the run's pass/fail. run_testinfra_validation returns pytest's exit code (and treats "could not run" as a failure, not a silent pass), surfaces the pass/skip/fail counts through the shared VALIDATION_* counters, and parses the attribution file so generate_issue_report still buckets failures into archsetup / base_install / unknown. The shell-sweep functions stay in validation.sh for now because run-test-baremetal.sh still calls them; removing them (after migrating the bare-metal runner) is filed as a follow-up.
* test(archsetup): expand validation coverage + fix ParallelDownloads (P4)Craig Jennings42 hours5-1/+140
| | | | | | | | | | | | | | | | | | Add post-install checks beyond the original shell sweep, validated against a live VM: test_hardening (sshd prohibit-password, quiet-printk sysctl, emptied /etc/issue, console font, EFI mount perms), test_config_applied (pacman ParallelDownloads/Color/multilib, makepkg flags, NetworkManager drop-ins, fail2ban jail, reflector), and test_backups (the .archsetup.bak files backup_system_file leaves behind — end-to-end proof of that feature). The new tests caught a real bug: ParallelDownloads stayed at Arch's default 5 because the sed only matched a commented "#ParallelDownloads", but current Arch ships it uncommented. Match both (^#?ParallelDownloads) so the intended 10 takes effect. Verified against a kept VM: 95 passed, 10 skipped (the one remaining failure was the pre-fix ParallelDownloads on the already-built VM, which the sed fix resolves on the next fresh install).
* test(archsetup): fix fixture scope and initramfs path in the sweepCraig Jennings43 hours2-10/+14
| | | | | | | | | | | | | VM run #2 exposed two test bugs (archsetup itself passed clean, 53/0/0): - ScopeMismatch errors on 26 tests: the host-dependent fixtures were session-scoped, but Testinfra's host fixture is module-scoped, and a session fixture cannot request a module one. Drop those fixtures to module scope. - test_console_font_in_initramfs hardcoded /boot/initramfs-linux.img; this fleet runs linux-lts, so the image is initramfs-linux-lts.img. Pick the main (non-fallback) initramfs by glob instead.
* fix(testing): authorize a root key so make test survives sshd hardeningCraig Jennings44 hours5-19/+65
| | | | | | The VM test SSHes into the guest as root with a password for the whole run. archsetup hardens sshd to PermitRootLogin prohibit-password and reloads it partway through the install, so every SSH after that step failed with "Permission denied" and the run aborted before any validation — make test had been silently broken since the hardening landed. inject_root_key authorizes a throwaway root key right after the first SSH (before archsetup runs) and the ssh/scp helpers now add -i <key> via SSH_KEY_OPT. prohibit-password still allows root key auth, so the harness survives the very hardening it validates. Password stays as the fallback, so the change is additive.
* test(archsetup): port full shell validation sweep to Testinfra (P2)Craig Jennings44 hours9-6/+419
| | | | | | | | | | | | | | | | | | Port all ~26 post-install checks from validation.sh to pytest/Testinfra, reaching parity before the cutover. Adds test_users, test_packages, test_services, test_desktop, test_boot, test_keyring, and test_archsetup (88 tests after parametrizing groups, services, timers, tools, and configs), plus shared conftest fixtures for ZFS/NVMe/compositor/networking gating. The shell sweep's three outcomes map cleanly: hard failures become assertions, advisory warnings and unmet preconditions (headless compositor, slirp networking, optional services, non-ZFS/non-NVMe hosts) become skips. One correctness fix vs the shell sweep: check awww, not swww — archsetup installs awww (swww's successor) and `pacman -Q swww` no longer matches. Verified on the host: py_compile clean, pytest --collect-only green (88 tests). The sweep against a real VM is verified by the make test run that follows.
* test(archsetup): scaffold Testinfra post-install validation (P1)Craig Jennings44 hours8-1/+213
| | | | | | | | Stand up the Testinfra/pytest harness alongside the existing shell sweep so the two can be compared for parity before pytest takes over. Adds scripts/testing/tests/ (conftest with failure attribution markers, a report hook, and a target_user fixture, plus three parity checks: user, ufw, dotfiles) and scripts/testing/lib/testinfra.sh, which injects a throwaway SSH key into the VM and runs pytest over SSH. The sweep is advisory here (RUN_TESTINFRA toggle, non-fatal) and does not yet affect pass/fail. Pulls python-pytest and python-pytest-testinfra into make deps. Verified on the host: py_compile clean, pytest --collect-only green, bash -n and shellcheck clean. The sweep running against a real VM is verified by the next make test run.
* docs(design): accept Testinfra post-install validation planCraig Jennings44 hours2-1/+241
| | | | | | Plan to port the VM harness's shell validation sweep (validation.sh, ~26 checks) to Testinfra + pytest for more expressive checks and better reporting, then expand coverage to the parts of archsetup that aren't validated today. Records the design: where pytest fits in run-test.sh, the SSH connection model (inject a throwaway test key), preserving the three-way issue attribution via pytest markers, smoke/integration tiering, a parity-then-expand migration, and a Goss comparison.
* feat(archsetup): back up system files before in-place editsCraig Jennings45 hours3-1/+203
| | | | | | | | Add a backup_system_file helper that snapshots a pre-existing file to <path>.archsetup.bak before archsetup edits it in place, so a botched edit to fstab, mkinitcpio.conf, or sudoers is recoverable. It is idempotent: it never overwrites an existing backup, so the pristine original survives repeated edits within a run and across re-runs. It uses cp -p to preserve mode and ownership. Only the in-place sed and append edits to pre-existing files route through it (locale.gen, makepkg.conf, pacman.conf, sudoers, wireless-regdom, geoclue.conf, pacman-contrib, fstab, mkinitcpio.conf, vconsole.conf). The brand-new drop-in files archsetup fully owns are skipped: there is no prior state to save, and recovery is just deleting them. Covered by tests/backup-system-file/ (Normal, Boundary, Error cases, including mode preservation and the no-overwrite guarantee).
* docs(todo): close wallpaper login-restore task, file symlink follow-upCraig Jennings45 hours1-1/+16
| | | | Mark the waypaper --restore task DONE, add the relogin manual-test under "Manual testing and validation", and file a follow-up: set-wallpaper's mv detaches the waypaper config from its stow symlink.
* docs(todo): restore heading, groom review batch, close bridge taskCraig Jennings45 hours3-9/+31
| | | | | | | - Restore the dropped "Collapsible waybar sides" heading. Its drawer and body were orphaned when an earlier edit clobbered the heading line. - Re-stamp the oldest-unreviewed task batch; drop "security education" to [#C]; tag the bridge-font and wallpaper-restore items. - Close the Proton Mail Bridge font task (UI font scaled via QT_FONT_DPI). - Archive two resolved inbox items to assets/outbox/.
* docs(todo): archive the resolved wallpaper taskCraig Jennings46 hours1-10/+9
|
* docs(todo): close wallpaper task, archive done, file restore follow-upCraig Jennings47 hours1-79/+78
|
* docs(todo): claim wallpaper item, close release-prep and mpd tasksCraig Jennings2 days1-8/+17
| | | | Claimed the dirvish-wallpaper item from the roam inbox (it's a Wayland wallpaper-utility issue). Filed it with the awww/set-wallpaper findings and handed the Emacs dirvish-command piece to that project. Closed the four next-set tasks: the device-udev flag, SPDX headers, boolean-comparison style, and the mpd playlist_directory split.
* chore: open-source release-prep (udev flag, SPDX headers, boolean style)Craig Jennings2 days25-10/+50
| | | | | | | | Three release cleanups, all behavior-preserving for my machines: - Gated the Logitech BRIO udev rule behind INSTALL_DEVICE_UDEV_RULES (default yes, opt-out), so the device-specific rule is off for anyone without that hardware. Added the config read, validation, and a conf.example entry. - Added a GPL-3.0-or-later SPDX-License-Identifier header after the shebang of all 24 shell scripts in the repo. - Standardized boolean conditionals on the explicit [ "$var" = "true" ] form, replacing the bare `if $var` idiom. The STEPS function-dispatch is left alone, since it runs a function name rather than testing a boolean.
* docs(todo): correct the nautilus dark-theme root causeCraig Jennings2 days1-1/+7
| | | | The first note said the system dconf db fixed it, but that left the running session white: a system-db default emits no change signal, so the appearance portal kept reporting no-preference, and libadwaita reads the portal, not GTK_THEME. The working fix added a user-level color-scheme set to signal the portal live.
* docs(todo): record CLI-tools speedrun and lyricsgenius recheckCraig Jennings2 days1-9/+21
| | | | Closed four solo tasks: nautilus dark theming (velox was missing the system dconf db that archsetup already declares), the CLI-tools install, the waybar tray-spacing fix, and the calendar-hover month/year highlight. Recorded the python-lyricsgenius recheck, which stays open: it still needs --skipinteg, but the cause moved from an expired PGP signature to a drifting LICENSE.txt checksum.
* feat(install): add bat, dust, hyperfine, and doggoCraig Jennings2 days1-2/+10
| | | | | | I adopted four modern CLI tools after the 2026-06-10 evaluation: bat (syntax-highlighting cat), dust (proportional disk-usage tree), hyperfine (statistical benchmarking), and doggo (a DNS client that speaks DoH/DoT/DoQ). tealdeer was already declared. All four are in extra and go in the General Utilities block. I also corrected the python-lyricsgenius --skipinteg note. The original expired-signature cause is gone (the package tarball verifies now), but makepkg still fails integrity on a LICENSE.txt the PKGBUILD pulls from github master, so the workaround stays for a different reason than the old comment claimed.
* docs(todo): reconcile open work via audit, review, and intakeCraig Jennings2 days1-28/+89
| | | | | | Closed the three resolved tool-evaluation tasks into actionable work: adopt the modern CLI tools, migrate the terminal from foot to ghostty, and keep nautilus over yazi. Closed the org-capture popup task as sized to the scratchpad. Demoted nine undated high-priority sub-tasks to B per the priority scheme. Folded the wlogout laptop-test task into the rectangular-buttons task and tagged the whole waybar cluster :waybar: so it filters as a unit. Reviewed the seven oldest-unreviewed tasks and kept all seven. Filed two new waybar tasks (calendar-hover highlight, idle-inhibitor rename) and folded a timer/stopwatch/alarm scope expansion into the existing waybar timer task.
* docs(todo): file Hyprland WM bug tasks, archive completed workCraig Jennings3 days1-35/+35
| | | | Filed the zoom-launches-tiny and focus-on-unhide bugs as tracked tasks (held for a debug pass), and moved this round's completed tasks into Resolved.
* feat(archsetup): harden sshd with a prohibit-password drop-inCraig Jennings3 days2-2/+11
| | | | | | The installer now writes /etc/ssh/sshd_config.d/10-hardening.conf with PermitRootLogin prohibit-password and reloads sshd, right after it starts the service. Root can still log in by key, never by password. PasswordAuthentication is left at the default so a normal user can bootstrap a key with ssh-copy-id. This makes the posture intentional instead of leaning on Arch's commented default. velox and ratio both carried an explicit PermitRootLogin yes from earlier provisioning, which I'd already fixed by hand.
* docs(todo): file installer sshd-hardening follow-up from security workCraig Jennings3 days1-0/+3
|
* docs(todo): close security dashboard command (shipped)Craig Jennings3 days1-2/+3
|
* docs(todo): close host-tier stow (already shipped) and --noconfirm signature ↵Craig Jennings3 days1-6/+11
| | | | audit
* docs(todo): schedule pocketbook finish-or-cancel decision for 2026-08-23Craig Jennings3 days1-0/+4
|
* docs(todo): record idle-inhibitor keybind as shippedCraig Jennings3 days1-0/+4
|
* docs(todo): file Fn+F9 pocketbook task, close paru-vs-yay defectCraig Jennings3 days1-1/+15
| | | | | | Filed a [#C] task for the Fn+F9-toggles-pocketbook behavior on velox, with the investigation findings: the trigger isn't in any Hyprland bind, remapper, or pocketbook's own source, so it's parked until it resurfaces. Also closed the paru-vs-yay research task properly: it had been left as a level-2 dated header, which is a sub-task shape, so it became DONE + CLOSED.
* docs: add dirvish-popup manual tests and capture new waybar/bridge tasksCraig Jennings5 days1-0/+32
| | | | Manual-test checklists for the Super+F Dirvish popup (launch, focus-loss dismiss, per-type external launch, single-instance, q). New tasks captured from the roam inbox: wifi remediation scope, waybar emacs-service control, collapse sysmonitor to one icon, and Proton Mail Bridge font size.
* docs: replace hardcoded machine identity with runtime uname -n lookupCraig Jennings5 days1-1/+1
|
* docs: spec out collapsible waybar sidesCraig Jennings7 days3-3/+164
| | | | | | A spike disproved the CSS / state-file approach. GTK3 has no display:none, so native modules go invisible but hold their space, and the bar never reflows. The mechanism is config-swap plus a SIGUSR2 reload, driven through an active config copied into XDG_RUNTIME_DIR so the toggle never rewrites the stowed canonical config. The spec locks the base sets (left: menu + workspaces; right: date + worldclock + tray), keeps the two sides independent, and stays host-agnostic: the base set is constant, the full set is whatever each host already defines. Spec and spike findings live under working/.
* feat: pin zig 0.15.2 under /opt for the Emacs ghostel terminalCraig Jennings8 days2-0/+302
| | | | | | | | | | Arch's rolling repo ships zig 0.16+, but ghostel's native-module compile fallback needs exactly 0.15.2: ghostel pins ghostty 1.3.2-dev, whose build does requireZig(0.15.2), and 0.16's build-API changes break the dependency build scripts. So a plain pacman -S zig produces a zig that can't build ghostel. install_zig_pin downloads zig-x86_64-linux-0.15.2.tar.xz from ziglang.org, verifies the sha256, extracts to /opt/zig-0.15.2, and symlinks /usr/local/bin/zig ahead of /usr/bin on PATH, where pacman -Syu can't bump it. I split the verify-and-install core (zig_install_from_tarball) out so it stays network-free and unit-testable: it refuses on a sha256 mismatch, a missing tarball, or a tree with no zig binary, and short-circuits when a correct install already exists. ghostel's default path downloads a prebuilt module and needs no zig, so this only matters for the offline compile fallback. The pin needs a one-line bump (ZIG_VERSION + ZIG_SHA256) whenever ghostel moves to a newer ghostty. Tests live in tests/zig-pin/: 7 cases covering extract+symlink, idempotency, sha256-mismatch refusal, missing tarball, and no-binary cleanup, run against the real function extracted from the script.
* chore(todo): reconcile audit, move dotfiles tasks out, add tag legendCraig Jennings10 days1-37/+21
| | | | | | | | I ran an audit pass over the open-work tasks. I moved the six release-prep sub-tasks that target the now-standalone ~/.dotfiles repo out of the GitHub-release epic into that project, leaving a dated note pointing at the handoff. The epic now covers archsetup-proper release work only. I reconciled two stale facts: dropped the dead scripts/gitrepos.sh reference (consolidated into post-install.sh in dae7659), and noted on the install-errors task that the latest VM run holds the error set at four known residuals. I added a Tags section to the priority scheme (type, effort/autonomy, and an open set of topic tags) so the file declares its tag vocabulary, not just its priorities. I also de-linked two dead handoff-file references and filed the Waybar Wi-Fi no-internet task.
* chore(inbox): file org-capture popup handoff, open sizing todoCraig Jennings11 days2-0/+16
|
* chore(todo): archive completed package-inventory tasks to ResolvedCraig Jennings12 days1-19/+17
|
* chore(todo): add undeclared-package review task from ratio diffCraig Jennings12 days1-0/+46
|
* chore(inbox): file processed .emacs.d reply to outboxCraig Jennings12 days1-0/+7
|
* chore(todo): close package-inventory tasks, regrade CI/CDCraig Jennings12 days1-12/+21
| | | | I marked the two package-inventory tasks DONE. Both are satisfied by scripts/package-inventory, now covered by characterization tests and a make package-diff target. I demoted the CI/CD pipeline task to C, since a full VM install per commit isn't realistic active backlog.
* test(scripts): lock package-inventory behavior with characterization testsCraig Jennings12 days3-6/+172
| | | | | | | | package-inventory compares archsetup's declared packages against the live system but had no tests, so a future archsetup edit (a new for-loop shape, a renamed install helper) could silently break the extraction. I added two env seams so the script is testable without the real system. PKGINV_ARCHSETUP points the extractor at a fixture installer, PKGINV_PACMAN swaps in a fake pacman serving controlled query output. Both default to the real targets, so normal use is unchanged, and the seams match the env-override pattern audit-packages.sh already uses. The 7 tests pin the extraction (direct calls, for-loop lists, variable-arg skip) and both diff directions against the fixture, with no network or real pacman db. I also added a make package-diff target so the tool is reachable alongside the test targets.
* chore(todo): close quick-capture popup task, file scroll-layout follow-upCraig Jennings14 days4-21/+98
| | | | The popup fix shipped in the dotfiles repo (the script now calls cj/quick-capture; the scrolling layout is disabled and Super+Shift+S reassigned to a fullscreen screenshot). I filed the scrolling-layout frame-fit and wrap-around work as a follow-up, and archived the processed cross-project handoff replies.
* chore(todo): file quick-capture coordination and scroll-layout tasksCraig Jennings14 days1-0/+22
|
* chore(todo): close silent mic-mute notifications — shippedCraig Jennings2026-06-111-2/+3
|
* chore(todo): file silent mic-mute notifications taskCraig Jennings2026-06-111-0/+6
|
* chore(todo): archive completed level-2 tasks to ResolvedCraig Jennings2026-06-111-253/+233
|