#+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 -- 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 = 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 >> 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 " 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 "