1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
#+TITLE: Sentry Code Findings — 2026-07-19 overnight run
#+AUTHOR: Craig Jennings
#+DATE: 2026-07-19
* About
Bug and refactoring findings from the overnight sentry code-inspection pass
(Craig's request, 2026-07-19). Detection only — nothing in the codebase was
changed. Each finding is a candidate to triage into todo.org (bug priority via
the severity x frequency matrix; refactors as :refactor: tasks) or discard, at
the morning sentry teardown.
Scope: the archsetup repo's own code (installer, scripts/, VM test framework,
Python, elisp). Dotfiles-side findings, if any, are tagged [dotfiles] since
that is a separate repo.
Severity legend for bugs: Critical (data loss / unbootable / security),
Major (feature broken), Minor (edge case / wrong under rare input),
Cosmetic. Refactors: High / Medium / Low value.
* Coverage tracker
Each fire takes the next uncovered slice. Mark done as fires complete.
- [X] S1 — archsetup installer, lines ~1-1050 (pre-flight, config, install primitives, GPU detect) — NB partitioning/filesystem code is past line 1050, so S2/S3 cover it
- [X] S2 — archsetup installer, lines ~1050-2100 (post-chroot system config: locale, mirrors, user, dotfiles/stow, AUR, services, snapshot tooling, WM packages). NB still NO partitioning/mkfs/mount in this range either — the disk path is in S3 or delegated to a separate tool.
- [X] S3 — archsetup installer, lines ~2100-3124 (desktop/WM, gaming, boot_ux: mkinitcpio/GRUB, finalize). RESOLVED: archsetup does NO partitioning/mkfs/mount anywhere in the file — it is a post-install config layer; disk setup is upstream (archinstall/separate tool).
- [X] S4 — scripts/*.sh production scripts (audit-packages, cmail-setup-finish, post-install, import-wireguard, normalize-notify-sounds, generate-palette, easyeffects, games, setup-chess)
- [X] S5 — scripts/testing/ framework + lib (run-test, vm-utils, validation, logging, network-diagnostics, testinfra, run-maint*, create-base-vm, cleanup, debug, setup-testing-env)
- [X] S6 — Python: gen_tokens + test suites (refactor lens; test-quality per testing.md)
- [X] S7 — elisp (gallery-widget.el)
* Findings
(appended per fire, newest slice last. Findings are unverified detection candidates for the morning triage — severity is the scanner's estimate, not a confirmed grade.)
** S1 — archsetup installer lines 1-1050 (fire 1, 2026-07-20 00:05)
*** [BUG Major] archsetup:487 — df available-space parse breaks on wrapped output
=available_kb=$(df / | awk 'NR==2 {print $4}')= parses df's second line. df wraps to two lines when the source device name is long (common on a live ISO / device-mapper root). When wrapped, NR==2 is the device-name line and $4 is empty, so available_kb="" -> available_gb=0 -> the script wrongly aborts with "Insufficient disk space" on a disk with plenty. Fails safe (blocks) but blocks a valid install.
Fix: =df -P / | awk 'NR==2 {print $4}'= (POSIX -P forces single-line) or =df --output=avail / | tail -1=.
*** [BUG Major] archsetup:298-305, 690-695 — run_step drops the state marker on a non-fatal step failure
run_step marks a step complete only when $step_func returns 0, but error_warn (the "non-fatal, continue" path) and run_task return 1 on failure. If a step function's last statement is a run_task/error_warn that fails, the function returns 1, so run_step prints FAILED and never writes the state marker even though the error was designated non-fatal. On resume the step re-runs every time, and =if $step_func; then= in main can abort on a survivable warning. (Full confirmation needs step bodies past line 1050.)
Fix: step functions =return 0= explicitly after their work, or have run_step gate on a per-step error flag rather than the function's last-command status.
*** [BUG Minor] archsetup:1034 — crash message reports the wrong exit code
=$refresh_ok || error_fatal "$action" "$?" ...= — $? is the status of evaluating $refresh_ok (the command =false=), not pacman's. The crash always reports "error: 1" regardless of why =pacman -Syu= failed, discarding the real code.
Fix: capture pacman's code inside the retry loop (last_rc=$?) and pass that.
*** [BUG Minor] archsetup:290-291, 318-320 — run_step locals leak to global scope
run_step sets step_name/step_func (and timestamp/step) without =local=. They leak globally; step_name persists across calls, a latent aliasing hazard if a step function reads a same-named global. No current failure, but fragile.
Fix: =local step_name step_func= (and local timestamp/step).
*** [BUG Minor] archsetup:488 — integer truncation biases the disk-space gate against the user
=available_gb=$((available_kb / 1024 / 1024))= truncates. Real df "available" runs slightly under nominal, so a nominally-20GB-free disk truncates to 19 and is rejected against min_disk_space_gb=20.
Fix: compare in KB directly (min_kb=$((min_disk_space_gb*1024*1024)); test available_kb -ge min_kb).
*** [REFACTOR High] archsetup:435-455, 908-934 — GPU modalias scan duplicated
The DRM-glob-then-PCI-fallback modalias scan is implemented twice — nvidia_preflight_report (NVIDIA-only) and install_gpu_drivers (Intel/AMD/NVIDIA) — with duplicated bc03 display-class filtering and the same =*v000010DE*|*v000010de*= casing. Two copies drift independently.
Fix: extract one scan_gpu_modalias helper (walk DRM then PCI, echo the detected vendor set); both callers consume it.
*** [REFACTOR Medium] archsetup:715-729, 762-786, 1026-1033 — bounded retry loop hand-rolled three times
retry_install, git_install, and the pacman -Syu refresh each re-derive attempt, the <= MAX_INSTALL_RETRIES guard, and the "retrying (attempt N/M)" message. The $?-capture subtlety must be re-remembered at each site (and the refresh loop at 1034 already got it wrong — see the Minor bug).
Fix: a =retry_cmd <desc> <max> -- cmd...= primitive that runs the loop, captures the real exit code, and emits the message.
*** [REFACTOR Low] archsetup:183-198 — four near-identical yes/no validation blocks
AUTOLOGIN, NO_GPU_DRIVERS, INSTALL_CLAUDE_CODE, INSTALL_DEVICE_UDEV_RULES each get a copy-pasted five-line yes/no check. A =validate_yesno <VARNAME> <value>= helper looped over the key list removes the duplication.
*** [REFACTOR Low] archsetup:459,471,476 — NVIDIA driver floor 535 is a magic literal in three spots
Repeated in the guidance text, the numeric comparison, and the error message. A NVIDIA_MIN_DRIVER=535 constant referenced in all three prevents drift.
S1 verdict: 5 bugs (2 Major, 3 Minor), 4 refactors (1 High, 1 Medium, 2 Low).
** S2 — archsetup installer lines 1050-2100 (fire 2, 2026-07-20 00:55)
Global note: =set -e= is commented out at archsetup:21, so any command without an explicit =|| error_*= guard fails silently and continues. Resume granularity is the top-level STEPS array (line 262), so a re-run repeats every command inside a failed step. Both facts amplify the bugs below.
*** [BUG Major] archsetup:1168 — chpasswd failure silently leaves an unloggable primary user
=echo "$username:$password" | chpasswd= has no guard, then =unset password= runs next line. With set -e off, a chpasswd failure is swallowed; useradd made the account with no password (locked), so the installed system has an unloggable primary user and no log diagnostic. Every other privileged step guards with error_fatal/error_warn; this one doesn't.
Fix: =... | chpasswd 2>> "$logfile" || error_fatal "setting password for $username" "$?" "set it by hand: passwd $username"= before unsetting.
*** [BUG Minor] archsetup:1820-1821 — unguarded cp of zfs-replicate leaves a service pointing at a missing binary
=cp "$user_archsetup_dir/scripts/zfs-replicate" /usr/local/bin/zfs-replicate= + chmod, no guard/redirect. The dotfiles/archsetup clone at 1231 is non-fatal; if it left no tree, the cp prints to console and continues, chmod fails, and the zfs-replicate.service (1824) has an ExecStart to a binary never installed.
Fix: =(cp ... && chmod +x ...) >> "$logfile" 2>&1 || error_warn "installing zfs-replicate script" "$?"=.
*** [BUG Minor] archsetup:1943-1944 — same unguarded cp for zfs-pre-snapshot -> broken pacman hook
Same pattern as 1820. A missing source silently yields a pacman PreTransaction hook (written at 1953) whose Exec target doesn't exist, so every future pacman transaction logs a hook failure with no record of why.
Fix: wrap in =(...) >> "$logfile" 2>&1 || error_warn ...=.
*** [BUG Minor] archsetup:1713 — crontab log-cleanup line duplicates on resume
=(crontab -l 2>/dev/null; echo "0 12 * * * ...log-cleanup") | crontab -= appends unconditionally. essential_services is one resume STEP; a failure after this point plus a re-run appends a second identical cron line each time.
Fix: guard on absence — =crontab -l 2>/dev/null | grep -qF 'cron/log-cleanup' || { ...; }=.
*** [BUG Minor] archsetup:1146 — blind copy of sudoers.pacnew risks a hard lockout
=[ -f /etc/sudoers.pacnew ] && cp /etc/sudoers.pacnew /etc/sudoers= with no =visudo -c= validation. A malformed pacnew replaces /etc/sudoers with a file sudo refuses to parse, locking out privilege escalation right before the NOPASSWD rule at 1183. Low probability, hard consequence.
Fix: =visudo -cf /etc/sudoers.pacnew && cp ... || error_warn ...=.
*** [BUG Minor] archsetup:1857 — zfs scrub timer uses an arbitrary pool via head -1
=zfs_pool=$(zpool list -H -o name | head -1)= then enables =zfs-scrub-weekly@${zfs_pool}.timer=. head -1 picks a wrong pool when several exist; an empty result yields the malformed unit =zfs-scrub-weekly@.timer=.
Fix: derive the pool hosting the root dataset explicitly; skip enabling when empty.
*** [REFACTOR Medium] archsetup:1263-1283 — stow invocation copy-pasted four times
The stow block (=(cd "$dotfiles_dir" && stow --target=... --no-folding --adopt <pkg> >> log) || error_warn=) repeats for common/desktop_env/host_tier/minimal, differing only in package name. A flag change means four edits.
Fix: extract =stow_pkg() { ... }= and call per package.
*** [REFACTOR Low] archsetup:1901-1907 — seven snapper set-config calls, mixed guarding
Seven consecutive =snapper -c root set-config "TIMELINE_...=N"= calls, most unguarded, mixing guarded/unguarded forms. Loop over a KEY=VALUE array with one uniform guard.
*** [REFACTOR Low] archsetup:1290-1300 — waybar battery pruned with position-dependent sed on JSON
=prune_waybar_battery= edits JSON with three positional =sed -i= including a trailing-comma fixup that assumes the battery entry's position. A reordering of the modules array silently produces invalid JSON. A jq-based edit (or a battery-less config variant in the hyprland tier) is robust.
S2 verdict: 6 bugs (1 Major, 5 Minor), 3 refactors (1 Medium, 2 Low). Range is post-chroot config, not partitioning.
** S3 — archsetup installer lines 2100-3124 (fire 3, 2026-07-20 02:00)
RESOLVED architectural fact: archsetup performs NO disk partitioning, formatting, or mounting. Grep of all 3124 lines finds no wipefs/sgdisk/parted/mkfs/mkswap/genfstab/cryptsetup/zpool-create/zfs-create. The only mounts are a tmpfs AUR-build RAM disk (1188), a btrfs /.snapshots remount (1878-1896), and an /efi fstab permission tweak (2900-2904). The installer assumes an already-partitioned, formatted, mounted base system with a bootloader present; disk layout and encryption are done upstream (archinstall or a separate tool). archsetup is a post-install package-and-config layer that only edits the existing bootloader/initramfs. This reframes the whole risk model: the data-loss surface is boot config, not partitioning.
*** [BUG Major] archsetup:3054 — GRUB_CMDLINE overwrite drops boot-critical params -> unbootable
=sed -i "s/.*GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"rw loglevel=2 ... quiet splash\"/g"= replaces the whole cmdline with a fixed string. The file sets no cryptdevice/root=ZFS/resume= anywhere, so any boot-critical param the base install placed there (encrypted-root cryptdevice=, hibernation resume=, a ZFS hint, a hardware quirk) is silently dropped, and the grub-mkconfig at 3059 then bakes an unbootable config. Highest boot-risk line in the range.
Fix: read the existing value and append only the missing tokens; assert the result still contains any pre-existing cryptdevice/root/resume before grub-mkconfig.
*** [BUG Major] archsetup:2910-2921, 2943-2948 — nvme early module never built into initramfs on ZFS-root non-Framework
add_nvme_early_module writes =MODULES=(nvme)= into mkinitcpio.conf, but the only rebuild in boot_ux (=mkinitcpio -P= in configure_initramfs_hook) runs =if ! is_zfs_root=, and trim_firmware's rebuild is Framework-only. So on a ZFS-root NVMe machine that is not a Framework 13 — exactly the target — the MODULES edit is never compiled in. Not fatal (autoload still boots), but the intended early-load hardening silently does nothing on the systems it was written for.
Fix: run =mkinitcpio -P= after the MODULES edit regardless of ZFS (or an unconditional rebuild at the end of boot_ux), guarded with error_warn.
*** [BUG Minor] archsetup:2918 — nvme presence check scans the whole file, not the MODULES line
=... && ! grep -q "nvme" /etc/mkinitcpio.conf= concludes nvme is present if "nvme" appears anywhere (a comment, a HOOKS entry), so the module is never inserted into MODULES.
Fix: scope it: =! grep -qE '^MODULES=\([^)]*\bnvme\b' /etc/mkinitcpio.conf=.
*** [BUG Minor] archsetup:2419 — gamemode enabled via systemctl --user, which the script knows fails at install time
=run_task ... sudo -u "$username" systemctl --user enable gamemoded.service=. The script documents at 2333-2338 that =systemctl --user= fails during install (no user session bus) and hand-creates the symlink there; gaming() ignores that lesson, so gamemoded is likely left un-enabled (silent warn, set -e off).
Fix: enable it the way syncthing is — manual wants-symlink under /home/$username/.config/systemd/user/, chown to the user.
*** [BUG Minor] archsetup:2108, 2144 — unguarded chmod after a non-fatal cp/heredoc
=chmod 755 /usr/local/bin/hypr-live-update-guard= and =chmod 644 .../10-hypr-live-update-guard.hook= run unguarded right after a run_task/cat that could have failed; with set -e off, the chmod hits a missing/partial file and fails silently.
Fix: fold the chmod into the guarded step or add =|| error_warn=.
*** [REFACTOR Medium] archsetup:2148-2183 — display_server() and window_manager() duplicate the same case dispatch
Near-identical case statements over $desktop_env, including a byte-for-byte duplicated =error_fatal "Unknown DESKTOP_ENV..."= default arm. Extract one dispatch helper, or validate $desktop_env once up front.
*** [REFACTOR Low] archsetup:2952-2963 — identical fsck drop-in heredoc written twice
The same =[Service] StandardOutput=null StandardError=journal+console= drop-in goes to systemd-fsck-root.service.d and systemd-fsck@.service.d. Write once to a variable, loop over the two dirs.
*** [REFACTOR Low] archsetup:3049-3054 — five unguarded GRUB sed lines
Five =sed -i "s/.*GRUB_.*=.*/.../g"= lines, all unguarded, each silently no-ops or mis-edits. Drive from a key->value table in a loop, add error_warn.
S3 verdict: 5 bugs (2 Major, 3 Minor), 3 refactors (1 Medium, 2 Low). Installer fully covered (S1-S3): 16 bugs, 10 refactors total.
** S4 — scripts/*.sh production scripts (fire 4, 2026-07-20 03:05)
Most scripts are solid (SHA-pinned downloads, atomic mv, trap cleanup, guarded rm). Findings:
*** [BUG Major] scripts/cmail-setup-finish.sh:52-54 — mail password decrypted world-readable before chmod
=gpg --decrypt --output "$cmailpass_plain" "$cmailpass_enc"= then =chmod 600 "$cmailpass_plain"= on the next line. gpg creates the file at the process umask (typically 0644), so the plaintext mail password is world-readable in the window between decrypt and chmod. import-wireguard-configs.sh uses the safe pattern (mktemp -d 0700 first) this should mirror.
Fix: =(umask 077; gpg ... --output "$cmailpass_plain" ...)= or decrypt into a mktemp 0600 file and mv into place.
*** [BUG Minor] scripts/import-wireguard-configs.sh:51-62 — a failed modify leaves the full-tunnel VPN live
=nmcli connection import= brings the 0.0.0.0/0 tunnel up immediately; the script renames then =down=s it. Under set -e, if the modify (58) fails, the script aborts before the down (62), leaving a live full-tunnel VPN routing all traffic through Proton — the exact "unasked-for VPN" the header says it prevents. The next-run guard catches the leftover profile but not the still-active tunnel.
Fix: bring the connection down right after parsing the UUID, before the rename.
*** [BUG Minor] scripts/normalize-notify-sounds.sh:39-46 — no temp trap + non-atomic write can corrupt a tracked repo file
=tmp=$(mktemp ...); ffmpeg ... "$tmp"; cat "$tmp" > "$f"; rm -f "$tmp"=. No EXIT trap (a mid-loop ffmpeg failure orphans the temp), and =cat "$tmp" > "$f"= truncates first, so a zero-byte/failed encode writes a corrupt/empty file. Since $f is a stow symlink into the repo, that corruption lands in the tracked file with no rollback.
Fix: EXIT trap to remove temp; =[ -s "$tmp" ]= before the write-through; write to $f.tmp and overwrite on success.
*** [REFACTOR Low] scripts/setup-chess.sh:354,377,489 — Maia ELO range spelled out three times
=for elo in 1100 1200 ... 1900= at 354 and 377, =range(1100,2000,100)= at 489, plus the MAIA_SHA256 map. Adding/dropping a level means four edits. Define one MAIA_ELOS array.
*** [REFACTOR Low] multiple — per-script log-helper boilerplate re-defined
info/ok/skip/warn/err printf helpers re-defined in setup-chess.sh:61-65, cmail-setup-finish.sh:29-31, and ad hoc elsewhere. A sourced lib/log.sh would dedupe, but these are standalone installers so it is defensible. Low priority.
Per-file: audit-packages clean; cmail 1 (Major); post-install clean (deliberate best-effort); import-wireguard 1 (Minor, key handling itself correct); normalize-notify 1 (Minor); games clean; setup-chess 2 refactors; generate-palette clean; easyeffects clean.
S4 verdict: 3 bugs (1 Major, 2 Minor), 2 refactors (2 Low). Plus a SECURITY item escalated to the approval queue (tracked WireGuard private keys).
** S5 — scripts/testing/ framework + lib (speedrun audit, 2026-07-20 ~16:00)
*** [BUG Major] scripts/testing/run-net-scenarios.sh:103 — diagnose-check failure is printed but never counted, run exits green
The scenario_diagnose_expect branch prints fail "$name: diagnose did NOT name it" but does not exit 1 (unlike the break and assert branches). Because the whole scenario runs inside ( ... ) || fails=$((fails+1)), a subshell whose only failure is the diagnose check still exits 0, so fails is not incremented and the script prints "all scenarios passed" and exit 0. A regression where net doctor can no longer identify a fault it is supposed to name is reported as a visible FAIL line yet a green exit code, so CI/automated callers treat the run as passing. Fix: make the diagnose-else branch force a non-zero subshell exit (exit 1 like the other two checks). First-draft harness per its own header — reviewed, not yet relied on.
*** [BUG Minor] scripts/testing/debug-vm.sh:49 — hardcoded base-disk name ignores FS_PROFILE
BASE_DISK is hardcoded to the btrfs image archsetup-base.qcow2, while init_vm_paths (line 56) already computes the profile-correct DISK_PATH (archsetup-base-zfs.qcow2 for FS_PROFILE=zfs). FS_PROFILE=zfs ./debug-vm.sh boots the btrfs base or fatals "Base disk not found." Fix: use DISK_PATH from init_vm_paths. Debug-only tool, zfs path only.
*** [BUG Minor] scripts/testing/lib/vm-utils.sh:284 — snapshot restore races the force-killed QEMU's qcow2 lock
kill_qemu sends kill -9 and deletes the PID file without waiting for reaping, so vm_is_running reports false at once. In the force-kill fallback, restore_snapshot then runs qemu-img snapshot -a while the dying qemu may still hold the qcow2 lock; qemu-img refuses a locked image, the restore fails, and in the trap it is swallowed by || true, leaving the base image dirty with no signal. Only bites on ACPI-powerdown timeout. Fix: wait for the killed PID (or poll /proc/$pid) before returning.
*** [BUG Minor] scripts/testing/lib/vm-utils.sh:69 — runtime paths not profile-suffixed, parallel btrfs+zfs runs collide
init_vm_paths suffixes DISK_PATH and OVMF_VARS by FS_PROFILE but leaves PID_FILE, MONITOR_SOCK, SERIAL_LOG fixed. A concurrent btrfs and zfs run shares those three: the second run's stop_qemu/vm_is_running reads the first run's PID file and can shutdown/kill the other VM; both truncate the same serial log. The default SSH_PORT check partially masks it. Fix: suffix these three like DISK_PATH.
*** [BUG Minor] scripts/testing/run-test.sh:287 — ARCHSETUP_EXIT_CODE never holds the installer's real exit status
The variable is set from a completion-marker grep, not archsetup's real exit code — the installer is launched detached (setsid ... &) and runs with set -e off, so it can error mid-run, continue, reach the end, and still write the marker. The report prints "ArchSetup Exit Code: 0" and the final gate treats that as success. Testinfra is the real backstop, so a broken install is still caught, but the reported code is misleading. Same pattern run-test-baremetal.sh:234. Fix: rename (ARCHSETUP_COMPLETED) and/or capture the true exit status via a file.
*** [REFACTOR Medium] scripts/testing/run-test.sh + run-test-baremetal.sh — large-scale duplication of the run/poll/report skeleton
The two runners duplicate the git-bundle transfer, the 30s MAX_POLLS loop, the completion-marker exit derivation, the Testinfra invocation, and the near-identical report heredoc — and have drifted (VM: setsid launch + copy_to_vm/copy_from_vm helpers; baremetal: nohup + hand-rolled sshpass scp). Extract the shared poll-and-report core into a sourced helper so baremetal inherits the sturdier launch/copy paths.
*** [REFACTOR Low] scripts/testing/run-maint-nspawn.sh:66 + run-maint-scenarios.sh:78 — duplicated scenario plumbing beyond the acknowledged helper trio
_scenario_var, _validate_scenario, and the mexec/mmaint/mfix/massert_metric helpers are byte-for-byte duplicated. The transport-specific trio (ssh vs nspawn) is defensibly duplicated, but _scenario_var and _validate_scenario are transport-independent pure functions that could live in a sourced lib/maint-scenario.sh. run_scenario is also nearly identical.
*** [REFACTOR Low] scripts/testing/run-test.sh:251,265 — two different mechanisms to detect the same process
The launch check uses pgrep -f 'bash archsetup' (251) and the poll loop uses ps aux | grep '[b]ash archsetup' (265) for the identical liveness question. Use one mechanism to remove a maintenance trap.
S5 verdict: 5 bugs (1 Major, 4 Minor), 3 refactors (1 Medium, 2 Low). No syntax errors; temp-file traps, snapshot-stopped guards, mfix PIPESTATUS, and the errexit-off window handled correctly.
** S6 — Python: gen_tokens + test suites (speedrun audit, 2026-07-20 ~16:00)
*** [TEST-QUALITY High] tests/installer-steps/test_pacman_hook_order.py:20 — ordering "invariant" is a tautology that never touches the file
test_safety_hooks_precede_mkinitcpio_removal claims to guard that 05-zfs-snapshot and 10-hypr-live-update-guard hooks are created before 60-mkinitcpio-remove. But the two assertLess calls compare two string literals ("05..." < "60...") — a constant ASCII fact always true regardless of file content. The ordering is never verified; the test would still pass if the hooks appeared after the removal or the removal moved above them. Only the assertIn presence checks do real work. Fix: assert on positions — text.index("05-zfs-snapshot.hook") < text.index("60-mkinitcpio-remove.hook") (and the guard hook). Matters because a real reorder can remove the current initramfs without a rebuild (unbootable) and this test would ship it green.
*** [BUG Minor] scripts/testing/tests/test_desktop.py:96 — shell glob passed to `test -S` breaks on zero or multiple compositor sockets
test_hyprland_socket runs host.run("test -S /tmp/hypr/*/.socket.sock"). The remote shell expands the glob: zero matches leaves the literal pattern (rc 1), two+ instances pass multiple args (rc 2 "too many arguments"). Either way the assertion fails for a reason unrelated to socket existence. Masked today because the test gates on compositor_running, which the headless VM never satisfies (always skips). Fix: resolve one socket first (find /tmp/hypr -name .socket.sock -type s | head -1).
*** [TEST-QUALITY Low] tests/gallery-tokens/test_gen_tokens.py:181 — degenerate-marker test asserts properties too weak to notice garbled output
test_start_marker_on_final_line_without_newline feeds "keep\n<START> <END>" and asserts only startswith("keep\n"), END present, "X" present — all hold, but the actual output is malformed (duplicated start marker, content spliced mid-line). Passes on broken output. The input can't occur in real HTML (markers always on their own newline-terminated lines), so severity is low; tighten to the exact expected string or drop as impossible.
*** [REFACTOR Low] docs/prototypes/gen_tokens.py:78 — four emitters repeat the section-iteration skeleton
emit_web_css, emit_waybar_gtk, emit_elisp each walk COLOR_SECTIONS then glow (resolving through resolve_color), then font/timing for two of three. A generator yielding resolved (name, color_value) pairs with each emitter supplying its formatter would remove the triplicated traversal. Readability only — divergences are load-bearing (waybar's font/timing omission is deliberate); keep them visible.
S6 verdict: 1 bug (Minor), 2 test-quality (1 High, 1 Low), 1 refactor (Low). gen_tokens.py has no correctness bugs; the sed-extract unit tiers import real function bodies, fake only at the system boundary, assert behavior not prose, carry N/B/E coverage, no shared state or hardcoded dates. Testinfra tiers sound.
** S7 — elisp: gallery-widget.el + gallery-tokens.el (speedrun audit, 2026-07-20 ~16:00)
*** [BUG Minor] docs/prototypes/gallery-widget.el:139 — readout renders raw value while the needle clamps
The needle angle is clamped 0-100 in gallery-widget--needle-angle, but the readout at line 139 uses (round value) on the unclamped input. Value 150 draws the needle pinned at +60 degrees (x2=82.64) while the text reads "150%" — confirmed live. The two halves disagree at any out-of-range input. Fix: compute a single clamped value once and format both the angle and the readout from it.
*** [BUG Minor] docs/prototypes/gallery-widget.el:69 — cl-loop used without (require 'cl-lib)
gallery-widget--node calls cl-loop, but the file requires only svg and dom. Works today only via cl-loop's autoload cookie; bites on byte-compile in a context that macroexpands cl-loop without cl-lib, or if a future cl- macro isn't autoloaded (cold-load void-function). Fix: add (require 'cl-lib).
*** [BUG Minor] docs/prototypes/gallery-widget.el:29 — file-name-directory on a possibly-nil path
The token load computes its directory from (or load-file-name buffer-file-name); both are nil when the form is eval'd outside a load and outside a file buffer, so file-name-directory receives nil and errors. Doesn't bite in the normal load/require path or the test harness, but makes interactive re-eval fragile. Fix: fall back to default-directory when neither is set.
*** [REFACTOR Medium] docs/prototypes/gallery-widget.el:95,136 — hardcoded SVG path strings duplicate the geometry the constants encode
The arc path "M 1 48 A 47 47 0 0 1 95 48" and hub path "M 44 48 A 4 4 0 0 1 52 48 Z" bake in cx=48, cy=48, radius 47, hub radius 4 — the same values expressed numerically elsewhere and passed to --polar for ticks/needle. Change cx/cy/radii and ticks/needle move while arc/hub silently stay put (dial desyncs, no error). Derive the arc endpoints and hub path from cx/cy/radius via the existing --polar/--fmt machinery, or name the magic numbers as shared defconsts.
*** [REFACTOR Low] docs/prototypes/gallery-widget.el:72,84 — reliance on the private svg--append internal
gallery-widget--node (72) and the defs/filter insertion (84) call svg--append, a double-dash private of svg.el with no cross-version stability guarantee. Low severity (prototype pinned to a known Emacs); prefer public svg.el builders or isolate the private call behind the single --node helper.
*** [TEST-QUALITY Medium] tests/gallery-widgets/test-gallery-widget.el:77 — obtuse tick count via split-string + cl-count-if :start 1
The "exactly three ticks" assertion splits on class="tick" then cl-count-if with an always-true predicate and :start 1 to count length-minus-one — a coincidence of split semantics, not a match count. Brittle: an empty leading/trailing segment or a stray class="tick" substring elsewhere throws it off. Replace with a direct occurrence count.
*** [TEST-QUALITY Medium] tests/gallery-widgets/test-gallery-widget.el:47 — clamp coverage tests the angle helper but never the rendered readout
The boundary test asserts gallery-widget--needle-angle clamps -5 and 150, but nothing asserts the full gauge's readout at an out-of-range value — exactly why the readout/needle mismatch (S7 bug 1) ships green. Add a gauge-level boundary case checking both the needle endpoint and the readout string at an out-of-range input.
*** [TEST-QUALITY Low] tests/gallery-widgets/test-gallery-widget.el:159 — output helper gallery-widget-write-svg is untested
gallery-widget-svg-string is exercised indirectly, but gallery-widget-write-svg has no coverage. A Normal case (write to temp, assert file exists, head is "<svg", return value equals the path) closes the last uncovered public entry point.
S7 verdict: 3 bugs (3 Minor), 2 refactors (1 Medium, 1 Low), 3 test-quality (2 Medium, 1 Low). No Critical/Major; SVG geometry, needle math, token lookup, error handling otherwise sound; all 10 existing tests pass.
** Audit complete (S1-S7)
Installer (S1-S3): 16 bugs, 10 refactors. Scripts (S4): 3 bugs, 2 refactors + WireGuard secrets (remediated). Test framework (S5): 5 bugs, 3 refactors. Python (S6): 1 bug, 2 test-quality, 1 refactor. Elisp (S7): 3 bugs, 2 refactors, 3 test-quality. All slices covered. Speedrun triaged S1-S4 bugs into tasks (chpasswd, df, run_step, sudoers, wireguard, idempotency, chmod/cp, normalize-notify shipped; GRUB-overwrite + others filed). S5-S7 triaged into the tasks below.
|