channels.scm:45:6: warning: channel 'jointhefreeworld' is not trusted
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/bridges.scm.go'
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;; or pass the --no-auto-compile argument to disable.
;;; compiling /gnu/store/mz104c5q2rq2l27jfdadk0b18da38r7z-profile/bin/guild
;;; compiled /tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/gnu/store/4kp7dc3jp6jc1q6a6zx7i229kslcxack-guile-3.0.11/bin/guild.go
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/btop.scm.go'
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:01 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/capture.scm.go'
heks-linux/capture.scm:223:2: warning: non-literal format string
heks-linux/capture.scm:471:2: warning: non-literal format string
heks-linux/capture.scm:643:2: warning: non-literal format string
heks-linux/capture.scm:47:0: warning: unused module (srfi srfi-13)
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/containers.scm.go'
[INFO] [2026-11-10 20:48:02 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:02 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:02 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/dconf.scm.go'
heks-linux/distrobox.scm:176:2: warning: non-literal format string
heks-linux/distrobox.scm:36:0: warning: unused module (srfi srfi-13)
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/distrobox.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/eca.scm.go'
[INFO] [2026-11-10 20:48:03 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:03 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:03 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/fastfetch.scm.go'
[INFO] [2026-11-10 20:48:03 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:03 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:03 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/fontconfig.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/git.scm.go'
[INFO] [2026-11-10 20:48:04 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:04 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:04 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/gtk.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/icons.scm.go'
[INFO] [2026-11-10 20:48:04 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:04 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:04 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/image.scm.go'
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/lambdock.scm.go'
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/mako.scm.go'
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:05 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/niri.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/palette.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/prelude.scm.go'
[INFO] [2026-11-10 20:48:08 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:08 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:08 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/rmpc.scm.go'
[INFO] [2026-11-10 20:48:08 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:08 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:08 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/rofi.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/ssh.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/toon.scm.go'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/user-settings.scm.go'
[INFO] [2026-11-10 20:48:10 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:10 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:10 CET] load-local-overrides: Could not resolve a config directory. Skipping.
heks-linux/wallpaper.scm:164:4: warning: unused variable `failure'
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/wallpaper.scm.go'
[INFO] [2026-11-10 20:48:10 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:10 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:10 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/waybar.scm.go'
[INFO] [2026-11-10 20:48:11 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:11 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:11 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/wezterm.scm.go'
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Warning - Neither $XDG_CONFIG_HOME nor $HOME is defined.
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Could not resolve a config directory. Skipping.
wrote `/tmp/tmp.qb3gDxgs5j/1/guile/ccache/3.0-LE-8-4.7/etc/byggsteg/job-clone/heks-linux/trunk/src/heks-linux/zen.scm.go'
channels.scm:45:6: warning: channel 'jointhefreeworld' is not trusted
scanning directories for unit tests...
scanning present working directory for unit tests...
shuffled the files with seed 223379907 (replay with VERITAS_SEED=223379907)
found unit tests: (distrobox-spec.scm niri-spec.scm bridges-spec.scm nix-spec.scm fontconfig-spec.scm mako-spec.scm updates-spec.scm lambdock-spec.scm git-spec.scm capture-spec.scm flatpak-spec.scm zen-spec.scm image-spec.scm waybar-spec.scm rmpc-spec.scm ssh-spec.scm prelude-spec.scm toon-spec.scm palette-spec.scm wallpaper-spec.scm wezterm-spec.scm dconf-spec.scm icons-spec.scm eca-spec.scm rofi-spec.scm gtk-spec.scm)
running unit tests from file: distrobox-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)[INFO] [2026-11-10 20:48:12 CET] Installing distrobox configuration
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Attempting override resolution for module (heks-linux distrobox) with profile 'distrobox-settings'
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/distrobox-settings.scm
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: No override file found at /tmp/heks-linux/distrobox-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:12 CET] Creating directory: /tmp/heks-distrobox-spec-17783
[INFO] [2026-11-10 20:48:12 CET] Creating directory: /tmp/heks-distrobox-spec-17783/config
[INFO] [2026-11-10 20:48:12 CET] Writing config to file: /tmp/heks-distrobox-spec-17783/config/heks-deb.ini
[INFO] [2026-11-10 20:48:12 CET] Creating directory: /tmp/heks-distrobox-spec-17783/bin
[INFO] [2026-11-10 20:48:12 CET] Writing config to file: /tmp/heks-distrobox-spec-17783/bin/heks-deb
[SUCCESS] [2026-11-10 20:48:12 CET] Installed distrobox configuration
+----------------------------------------------+
[📑 suite] distrobox Suite
[🧪 test] The NVIDIA Flag Follows The Machine
[⚙️ assert] An NVIDIA machine integrates its drivers
✅ got: #t
[⚙️ assert] Every other machine leaves the drivers alone
✅ got: #t
[🧪 test] The Box Gets Audio And A GPU
[⚙️ assert] The box carries the PipeWire client libraries
✅ got: #t
[⚙️ assert] ALSA applications are routed to PipeWire
✅ got: #t
[⚙️ assert] PulseAudio applications are routed to PipeWire
✅ got: #t
[⚙️ assert] The box carries the Mesa drivers for this GPU
✅ got: #t
[🧪 test] The Program Drives The Manifest
[⚙️ assert] The program is a bash script
✅ got: #t
[⚙️ assert] Creating the box reads the generated manifest
✅ got: #t
[⚙️ assert] The program reads the manifest this configuration writes
✅ got: #t
[⚙️ assert] A .deb file is installed by apt inside the box
✅ got: #t
[⚙️ assert] The program can enable the 32-bit libraries a .deb asks for
✅ got: #t
[⚙️ assert] The program copies a file into the box
✅ got: #t
[⚙️ assert] A destination you own is copied without sudo
✅ got: #t
[⚙️ assert] A destination the box's root owns is written through sudo
✅ got: #t
[⚙️ assert] The doctor blames state another user owns for a false already-running
✅ got: #t
[⚙️ assert] The program names the box the manifest creates
✅ got: #t
[🧪 test] The Manifest Describes The Box
[⚙️ assert] The manifest names the box
✅ got: #t
[⚙️ assert] The manifest names the image to run it from
✅ got: #t
[⚙️ assert] Assembling an existing box must not wipe it
✅ got: #t
[🧪 test] Installing Writes Both Files
[⚙️ assert] Installing writes the program
✅ got: #t
[⚙️ assert] Installing writes the manifest
✅ got: #t
[⚙️ assert] The program is executable
✅ got: #t
[⚙️ assert] The manifest on disk is the rendered one
✅ got: # ====== Heks-Linux: the .deb box ======
#
# auto-generated file, DO NOT EDIT! Rendered from (heks-linux distrobox);
# run maak install-distrobox to write it again.
#
# Distrobox shares the home directory, the Wayland and PipeWire sockets and
# /dev/dri with the container, so a program installed in this box uses this
# session's audio and GPU. nvidia=true is for the proprietary driver, the one
# thing that is not shared on its own.
[deb]
image=docker.io/library/debian:stable
additional_packages="libasound2-plugins libegl1 libgl1 libpulse0 mesa-utils mesa-vulkan-drivers pipewire-audio-client-libraries pulseaudio-utils xdg-utils"
nvidia=false
init=false
pull=true
replace=false
start_now=false
ℹ️ info - ran 1 tasks in: 0 seconds, 20180 microseconds
ℹ️ info - counted 1 file, 1 suite, 5 tests and 23 assertions
running unit tests from file: niri-spec.scm, entrypoint: spec
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Attempting override resolution for module (heks-linux user-settings) with profile 'local-settings'
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/local-settings.scm
[INFO] [2026-11-10 20:48:12 CET] load-local-overrides: No override file found at /tmp/heks-linux/local-settings.scm. Skipping.
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Niri Configuration Suite
[🧪 test] Rounded Windows And Soft Shadows
[⚙️ assert] Windows should get a rounded corner radius
✅ got: #t
[⚙️ assert] Windows should cast a drop shadow
✅ got: #t
[🧪 test] The Notifications Get No Rule At All
[⚙️ assert] No layer rule should match mako's banners
✅ got: #f
[⚙️ assert] The launcher keeps its rule; only the banners lost theirs
✅ got: #t
[🧪 test] The Dock's Launchpad Frosts What It Covers
[⚙️ assert] The launchpad should be matched by its layer namespace
✅ got: #t
[⚙️ assert] The compositor should frost the launchpad's backdrop
✅ got: #t
[⚙️ assert] The launchpad's glass should show what it covers
✅ got: #t
[⚙️ assert] Turning blur off should tell the compositor, not just omit the rule
✅ got: #t
[🧪 test] The Reference Window Opens Focused And Blurred
[⚙️ assert] The window should be matched by its application id
✅ got: #t
[⚙️ assert] The window should be focused the moment it opens
✅ got: #t
[⚙️ assert] The compositor should blur what is behind the glass
✅ got: #t
[🧪 test] Configuration Serializes To KDL
[⚙️ assert] The generated config should start with the Heks header
✅ got: #t
[⚙️ assert] An input block should be emitted
✅ got: #t
[⚙️ assert] A binds block should be emitted
✅ got: #t
[🧪 test] The Session Starts The Machine's Password Manager
[⚙️ assert] The session should start the password manager quietly
✅ got: #t
[⚙️ assert] Another manager and its own quiet flag should come through
✅ got: #t
[⚙️ assert] A manager with no quiet start should start plainly
✅ got: keepassxc
[⚙️ assert] The default should be the distribution's 1password, not the Flatpak
✅ got: #t
[🧪 test] The Menu Bar Casts No Shadow And Sips The Wallpaper
[⚙️ assert] The bar should be matched by its layer namespace
✅ got: #t
[⚙️ assert] The bar should cast no shadow by default
✅ got: #t
[⚙️ assert] A machine that wants the shadow back should get it, short and soft
✅ got: #t
[⚙️ assert] The backdrop should be saturated under the bar's veil
✅ got: #t
[⚙️ assert] The menus should be matched by their layer namespace
✅ got: #t
[⚙️ assert] The menus' shadow should follow the panel's own corners
✅ got: #t
[⚙️ assert] A menu's glass should show the window it drops over
✅ got: #t
[⚙️ assert] The bar should keep its shadow on a machine without blur
✅ got: #t
[⚙️ assert] Turning blur off should tell the compositor, not just omit the rule
✅ got: #t
[⚙️ assert] The bar's shadow softness should be a setting
✅ got: #t
[⚙️ assert] So should the menus'
✅ got: #t
[⚙️ assert] So should its colour
✅ got: #t
[⚙️ assert] So should where it falls
✅ got: #t
[⚙️ assert] The vibrancy should be a setting
✅ got: #t
[⚙️ assert] The menus' shadow should follow the panel's own radius setting
✅ got: #t
[🧪 test] Startup Scripts Exist Under ~/.local/bin
[⚙️ assert] The startup entry must name the script that the dconf module installs
✅ got: #t
[⚙️ assert] The stale, non-existent startup script name must be gone
✅ got: #t
[🧪 test] Reference And Omarchy Parity Bindings
[⚙️ assert] Super+Space should open the launcher
✅ got: #t
[⚙️ assert] Toggling floating mode should move to Super+Shift+Space
✅ got: #t
[⚙️ assert] Super+Return should open a terminal, as in Omarchy
✅ got: #t
[⚙️ assert] Super+Q should close the focused window
✅ got: #t
[⚙️ assert] Super+V should browse the clipboard history
✅ got: #t
[⚙️ assert] The palette chooser should be reachable from a binding, on its own view
✅ got: #t
[⚙️ assert] Do-not-disturb should be reachable from a binding
✅ got: #t
[🧪 test] Springy Reference Style Motion
[⚙️ assert] Window opening should be animated
✅ got: #t
[⚙️ assert] Animations should be spring driven
✅ got: #t
[⚙️ assert] Workspace switches should be animated
✅ got: #t
[🧪 test] The Lock Screen Wears The Palette
[⚙️ assert] The lock ring should be the palette's own accent
✅ got: #t
[⚙️ assert] The lock screen's field should be the palette's background
✅ got: #t
[⚙️ assert] Mocha's text colour should not survive a Nord lock screen
✅ got: #t
[🧪 test] The Dock Is Started Once Per Session
[⚙️ assert] The dock should start under a lock held for its lifetime
✅ got: #t
[⚙️ assert] The dock should never be started under its bare name
✅ got: #t
[⚙️ assert] Restarting the dock should queue for the same lock
✅ got: #t
[🧪 test] Extra Keyboard Options Are Composed With Caps To Ctrl
[⚙️ assert] Extra XKB options should be comma-joined with ctrl:nocaps
✅ got: #t
[⚙️ assert] A single extra option should still compose with ctrl:nocaps
✅ got: #t
[⚙️ assert] Without ctrl:nocaps the extra options stand alone
✅ got: #t
[⚙️ assert] Repeated configuration does not generate redundancies
✅ got: #t
[🧪 test] Natural Scrolling Follows Its Setting
[⚙️ assert] Natural scrolling should stay off while the setting is disabled
✅ got: #t
[⚙️ assert] Enabling the setting should emit natural-scroll into the config
✅ got: #t
[🧪 test] The Wide Applications Open At The Full Width, Bar And All
[⚙️ assert] Chrome should open at the full width
✅ got: #t
[⚙️ assert] Firefox should open at the full width
✅ got: #t
[⚙️ assert] So should the Flatpak, which announces its sandbox id
✅ got: #t
[⚙️ assert] The video editor should open at the full width
✅ got: #t
[⚙️ assert] The live mixer should open at the full width
✅ got: #t
[⚙️ assert] So should the video players
✅ got: #t
[⚙️ assert] A file manager should take the width and keep the bar
✅ got: #t
[⚙️ assert] Nothing should open fullscreen by default
✅ got: #t
[⚙️ assert] But a machine should still be able to ask for it
✅ got: #t
[⚙️ assert] A mixer should float over the work it is changing
✅ got: #t
[⚙️ assert] The vault should stay out of screenshots and screencasts
✅ got: #t
[⚙️ assert] Application ids should be matched whole
✅ got: "^obs$"
[⚙️ assert] The maximized list should be a setting
✅ got: #t
[⚙️ assert] Emptying the lists should leave no rule that matches nothing
✅ got: #t
[⚙️ assert] A machine that wants its vault in screenshots should say so
✅ got: #t
[🧪 test] Clipboard History Is Recorded
[⚙️ assert] The clipboard watcher should be started with the session
✅ got: #t
[🧪 test] WezTerm Is The Main Terminal
[⚙️ assert] Super+T should launch WezTerm
✅ got: #t
[⚙️ assert] The terminal binding should spawn wezterm
✅ got: #t
[⚙️ assert] Alacritty must no longer be referenced
✅ got: #t
[⚙️ assert] kitty must no longer be referenced
✅ got: #t
ℹ️ info - ran 1 tasks in: 1 seconds, -251243 microseconds
ℹ️ info - counted 1 file, 1 suite, 17 tests and 77 assertions
running unit tests from file: bridges-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] bridges test suite
[🧪 test] Bash Bridge String Generation
[⚙️ assert] Bash bridge should start with correct shebang
✅ got: #t
[⚙️ assert] Bash bridge should export the highlight variable
✅ got: #t
[🧪 test] Emacs Bridge Carries The Settings Values
[⚙️ assert] The mono font setting should travel across the bridge
✅ got: JuliaMono
[⚙️ assert] The clone directory should travel across the bridge
✅ got: ~/Hacking/heks-linux
[🧪 test] Emacs Bridge Elisp Generation
[⚙️ assert] Bridge output should be a list (S-expression)
✅ got: #t
[⚙️ assert] Bridge output should be wrapped in a 'progn
✅ got: progn
[⚙️ assert] Should configure mono font
✅ got: #t
[⚙️ assert] Should configure the sans font
✅ got: #t
[⚙️ assert] Should configure the Emacs theme
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 10026 microseconds
ℹ️ info - counted 1 file, 1 suite, 3 tests and 9 assertions
running unit tests from file: nix-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Installables
[🧪 test] The Installable Is This Project's Flake
[⚙️ assert] An attribute becomes an attribute of the flake at the root
✅ got: .#nil
[⚙️ assert] The attribute carries no prefix of its own
✅ got: 1
+----------------------------------------------+
[📑 suite] Overrides
[🧪 test] An Extra Package Joins The Union
[⚙️ assert] A machine can add a server of its own
✅ got: #t
[🧪 test] Category Parameters Are Read At Call Time
[⚙️ assert] An emptied category is observed
✅ got: #f
+----------------------------------------------+
[📑 suite] Catalog
[🧪 test] Every Entry Is Installable
[⚙️ assert] Every attribute passes the form check
✅ got: #t
[🧪 test] The Language Servers Are Declared
[⚙️ assert] YAML is covered where the distribution is not
✅ got: #t
[⚙️ assert] Nix is covered
✅ got: #t
[⚙️ assert] Markdown is covered
✅ got: #t
[⚙️ assert] JSON, CSS and HTML arrive in one package
✅ got: #t
[🧪 test] The Disk-Image Readers Are Declared
[⚙️ assert] A .dmg can be unpacked
✅ got: #t
[⚙️ assert] The HFS+ volume can be inspected
✅ got: #t
[🧪 test] The Union Is Sorted And Duplicate-Free
[⚙️ assert] Packages are sorted by attribute
✅ got: #t
[⚙️ assert] No attribute is declared twice
✅ got: 9
+----------------------------------------------+
[📑 suite] The Profile
[🧪 test] Elements Are Read With Their Origin
[⚙️ assert] A name and the flake it came from, in the order the listing prints them
✅ got: ((gifski . flake:nixpkgs) (heks-toon . /nix/store/def-source))
[⚙️ assert] A profile that lists nothing answers with nothing
✅ got: ()
+----------------------------------------------+
[📑 suite] Package Declarations
[🧪 test] An Attribute Becomes A Package
[⚙️ assert] A declaration produces a package record
✅ got: #t
[⚙️ assert] The attribute is kept as written
✅ got: yaml-language-server
[🧪 test] Malformed Attributes Are Rejected
[⚙️ assert] An empty attribute is not an attribute
✅ got: #f
[⚙️ assert] An attribute may not look like an option
✅ got: #f
[⚙️ assert] The installable prefix is not part of it
✅ got: #f
[⚙️ assert] The constructor refuses whitespace
✅ success catching error: misc-error: (#f nix-package: not a nixpkgs attribute: ~S (two words) #f)
[⚙️ assert] The constructor refuses punctuation
✅ success catching error: misc-error: (#f nix-package: not a nixpkgs attribute: ~S (nil!) #f)
[🧪 test] Dotted Attribute Paths Are Allowed
[⚙️ assert] A set attribute is a valid attribute
✅ got: #t
[⚙️ assert] A hyphen is part of an attribute name
✅ got: #t
[🧪 test] Symbols And Strings Are Both Accepted
[⚙️ assert] A symbol is coerced to the attribute string
✅ got: nil
[⚙️ assert] Attributes are always strings
✅ got: #t
ℹ️ info - ran 5 tasks in: 0 seconds, 18930 microseconds
ℹ️ info - counted 1 file, 5 suites, 12 tests and 26 assertions
running unit tests from file: fontconfig-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Fontconfig Configuration Suite
[🧪 test] A Generic Sans Request Answers With The Configured Face
[⚙️ assert] One rule for each way of spelling the generic sans
✅ got: 2
[⚙️ assert] Every alias should be written into the file
✅ got: #t
[⚙️ assert] Each alias should answer with the configured face
✅ got: (#t)
[⚙️ assert] The face should go in front of the name, not after it
✅ got: (prepend)
[⚙️ assert] And outrank what the distribution already put in the pattern
✅ got: (strong)
[⚙️ assert] The rule should fire only when the generic name is what was asked for
✅ got: (first)
[⚙️ assert] A machine that wants the stock generics gets no alias rule
✅ got: 0
[⚙️ assert] The list should be read from the parameter
✅ got: 1
[🧪 test] Emboldening Is Off Unless Asked For
[⚙️ assert] One match by default: the size-gated rule is not written
✅ got: 1
[⚙️ assert] A second, size-gated match appears when faking bold
✅ got: 2
[⚙️ assert] By default there is no size gate to read
✅ got: #t
[⚙️ assert] The faking should be gated on the point size
✅ got: #t
[⚙️ assert] The gate should use the configured size
✅ got: #t
[🧪 test] The Alias Rule Is Read Before The Fallback Rule
[⚙️ assert] The first rule should be an alias rule
✅ got: #t
[⚙️ assert] And the fallback rule, which tests for that family, should follow it
✅ got: Work Sans
[🧪 test] Monospace And Serif Requests Get This Desktop's Faces
[⚙️ assert] One rule for each way of spelling the generic monospace
✅ got: 2
[⚙️ assert] A monospace request should answer with the configured mono
✅ got: (JuliaMono)
[⚙️ assert] A serif request should answer with the configured serif
✅ got: (Source Serif 4)
[⚙️ assert] Every generic spelling should be written into the file
✅ got: #t
[⚙️ assert] They should fire only when the generic name is what was asked for
✅ got: (first)
[⚙️ assert] A machine that wants the stock generics gets no rule from either
✅ got: ()
[🧪 test] An Empty List Writes No Rule
[⚙️ assert] A machine that wants the stock fontconfig gets no rule at all
✅ got: ()
[⚙️ assert] A list that only repeats the configured family has nothing to add
✅ got: ()
[⚙️ assert] A family is not its own fallback
✅ got: 1
[🧪 test] The Fallbacks Outrank The Distribution's Default
[⚙️ assert] The fallbacks should be appended
✅ got: (append)
[⚙️ assert] They should be bound as strongly as the family that was asked for
✅ got: (same)
[⚙️ assert] Every edit should assign a family
✅ got: 0
[🧪 test] The Fallbacks Are Written In The Order They Are Preferred
[⚙️ assert] The last edit written should be the last name in the list
✅ got: Adwaita Sans
[⚙️ assert] And the first edit written should be the first expected face
✅ got: Helvetica Neue
[⚙️ assert] A two-family list should be written bottom-up
✅ got: (Adwaita Sans Helvetica Neue)
[🧪 test] Every Rule Assigns
[⚙️ assert] Every edit should assign, not merely prefer
✅ got: ()
[🧪 test] The Rules Are Overridable
[⚙️ assert] A machine that wants subpixel rendering should be able to ask for it
✅ got: rgb
[⚙️ assert] And a machine that wants no smoothing at all
✅ got: false
[🧪 test] The File Is Valid Fontconfig XML
[⚙️ assert] The file should open with an XML declaration
✅ got: #t
[⚙️ assert] It should carry the DOCTYPE fontconfig's own files carry
✅ got: #t
[⚙️ assert] It should not carry a namespace fontconfig rejects
✅ got: #f
[⚙️ assert] The rules should be one font-targeted match
✅ got: #t
[⚙️ assert] The renderer should return the fontconfig element
✅ got: fontconfig
[🧪 test] Text Is Smoothed The Way The Reference Smooths It
[⚙️ assert] Text should be smoothed in grey, not in subpixels
✅ got: none
[⚙️ assert] Glyphs should be hinted lightly, so the design survives
✅ got: hintslight
[⚙️ assert] The LCD filter should leave the glyphs alone
✅ got: lcdnone
[⚙️ assert] Antialiasing should be a boolean, not a keyword
✅ got: bool
[⚙️ assert] Antialiasing should be on
✅ got: true
[🧪 test] A Missing Sans Family Falls Back To The Faces This Desktop Is Drawn In
[⚙️ assert] One rule, and only when there is something to fall back to
✅ got: 1
[⚙️ assert] The fallback rule matches patterns, not faces
✅ got: #t
[⚙️ assert] The rule should test for the family this desktop asks for
✅ got: #t
[⚙️ assert] The fallback faces should be in the file
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 25822 microseconds
ℹ️ info - counted 1 file, 1 suite, 12 tests and 47 assertions
running unit tests from file: mako-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Mako Notification Suite
[🧪 test] The Banner Drops Below The Menu Bar
[⚙️ assert] Banners belong in the corner the reference keeps them in
✅ got: #t
[⚙️ assert] The top margin should clear the menu bar and the other three should not
✅ got: #t
[⚙️ assert] The margin should be a setting
✅ got: #t
[🧪 test] Banner Background Follows Palette Opacity
[⚙️ assert] The default banner should use its palette mako-opacity
✅ got: #t
[⚙️ assert] Golden Gate should render its own, more transparent banner
✅ got: #t
[🧪 test] Notification behaviour is configured
[⚙️ assert] Notification history should be kept
✅ got: #t
[⚙️ assert] A default timeout should be set
✅ got: #t
[⚙️ assert] Left click should dismiss a notification
✅ got: #t
[🧪 test] Do Not Disturb Mode Is Declared
[⚙️ assert] A do-not-disturb mode section should exist so makoctl can toggle it
✅ got: #t
[⚙️ assert] While in do-not-disturb, notifications must not be drawn
✅ got: #t
[🧪 test] Banners Match The Reference Look
[⚙️ assert] Notification banners should be rounded like the reference's were
✅ got: #t
[⚙️ assert] Notification banners should carry a one-pixel hairline edge
✅ got: #t
[⚙️ assert] The edge should be the secondary text colour at 35% opacity
✅ got: #t
[⚙️ assert] The radius should be a setting the compositor can read
✅ got: 12
[⚙️ assert] A machine should be able to round its banners differently
✅ got: #t
[🧪 test] Urgent Notifications Do Not Look Like The Others
[⚙️ assert] A critical section should exist
✅ got: #t
[⚙️ assert] A critical notification should stay until it is dismissed
✅ got: #t
[⚙️ assert] The rim should be the palette's accent, in every palette
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 18648 microseconds
ℹ️ info - counted 1 file, 1 suite, 6 tests and 18 assertions
running unit tests from file: updates-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-updates-spec-17783
+----------------------------------------------+
[📑 suite] Update Check Suite
[🧪 test] Channel Pins Are Read As Data
[⚙️ assert] Each channel should yield its name, url, branch and commit, in order
✅ got: ((guix https://example.org/guix.git master 1111111111111111111111111111111111111111) (jointhefreeworld https://example.org/jointhefreeworld.git trunk 3333333333333333333333333333333333333333))
[🧪 test] Ls Remote Answers With The Branch Itself
[⚙️ assert] The exact ref should win over the copies under it
✅ got: 72442a6baa199f4944df54cfdb45929af98ef99f
[⚙️ assert] A branch named later in the listing should still be found
✅ got: a1fadeb4bb96422bc0ca1f63e302da5b62575dd7
[⚙️ assert] A ref that only starts the same way should not be taken for the branch
✅ got: #f
[⚙️ assert] An empty listing should answer nothing rather than raise
✅ got: #f
ℹ️ info - ran 1 tasks in: 0 seconds, 5056 microseconds
ℹ️ info - counted 1 file, 1 suite, 2 tests and 5 assertions
running unit tests from file: lambdock-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Lambdock Configuration Suite
[🧪 test] The Dock Is Configured In The File It Loads
[⚙️ assert] The settings file should be the name lambdock reads from its config directory
✅ got: #t
[⚙️ assert] The settings should be emitted as top-level defines
✅ got: #t
[⚙️ assert] The dock item list should be emitted
✅ got: #t
[🧪 test] The Launchpad's Frost Is One Setting In Two Places
[⚙️ assert] The dock should be told whether its launchpad backdrop is frosted
✅ got: #t
[⚙️ assert] The dock's launchpad frost should follow the blur switch
✅ got: #t
[⚙️ assert] The launchpad's layer rule should follow the same blur switch
✅ got: #t
[⚙️ assert] The dock and the compositor should agree about the launchpad's frost
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 33923 microseconds
ℹ️ info - counted 1 file, 1 suite, 2 tests and 7 assertions
running unit tests from file: git-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Git Suite
[🧪 test] Delta Moves Between Sections Of A Diff
[⚙️ assert] n and N should move between the sections of a diff
✅ got: #t
[🧪 test] The Identity Rules Survive The Delta Settings
[⚙️ assert] Core should keep the editor the commits are written in
✅ got: #t
[⚙️ assert] And the machine-wide ignore list
✅ got: #t
[⚙️ assert] One rule for each directory the identity switches on
✅ got: 4
[⚙️ assert] The work identity should still be named by its rule
✅ got: #t
[🧪 test] Diffs Are Read Through Delta
[⚙️ assert] Git should page every diff through delta
✅ got: #t
[⚙️ assert] And colour the hunks it shows under `git add -p' itself
✅ got: #t
[🧪 test] Conflicts Are Shown Against The Common Ancestor
[⚙️ assert] A conflict should keep the common ancestor in view
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 14037 microseconds
ℹ️ info - counted 1 file, 1 suite, 4 tests and 8 assertions
running unit tests from file: capture-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-clipboard-1
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-clipboard-1/bin
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-clipboard-1/shots
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-clipboard-1/videos
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-clipboard-1/gifs
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-clipboard-1/run
[INFO] [2026-11-10 20:48:13 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:13 CET] Writing config to file: /tmp/heks-capture-spec-17783/shot-clipboard-1/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:13 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-annotate-2
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-annotate-2/bin
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-annotate-2/shots
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-annotate-2/videos
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-annotate-2/gifs
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-annotate-2/run
[INFO] [2026-11-10 20:48:13 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:13 CET] Writing config to file: /tmp/heks-capture-spec-17783/shot-annotate-2/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:13 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-window-3
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-window-3/bin
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-window-3/shots
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-window-3/videos
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-window-3/gifs
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-window-3/run
[INFO] [2026-11-10 20:48:13 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:13 CET] Writing config to file: /tmp/heks-capture-spec-17783/shot-window-3/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:13 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-region-4
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-region-4/bin
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-region-4/shots
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-region-4/videos
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-region-4/gifs
[INFO] [2026-11-10 20:48:13 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-region-4/run
[INFO] [2026-11-10 20:48:13 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:13 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:13 CET] Writing config to file: /tmp/heks-capture-spec-17783/shot-region-4/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:13 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-cancelled-5
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-cancelled-5/bin
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-cancelled-5/shots
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-cancelled-5/videos
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-cancelled-5/gifs
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-cancelled-5/run
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-output-6
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-output-6/bin
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-output-6/shots
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-output-6/videos
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-output-6/gifs
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/shot-output-6/run
[INFO] [2026-11-10 20:48:14 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:14 CET] Writing config to file: /tmp/heks-capture-spec-17783/shot-output-6/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:14 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:14 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:14 CET] Writing config to file: /tmp/heks-capture-spec-17783/shot-cancelled-5/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:14 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/stop-7
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/stop-7/bin
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/stop-7/shots
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/stop-7/videos
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/stop-7/gifs
[INFO] [2026-11-10 20:48:14 CET] Creating directory: /tmp/heks-capture-spec-17783/stop-7/run
[INFO] [2026-11-10 20:48:14 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:14 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:14 CET] Writing config to file: /tmp/heks-capture-spec-17783/stop-7/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:14 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/two-presets-8
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/two-presets-8/bin
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/two-presets-8/shots
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/two-presets-8/videos
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/two-presets-8/gifs
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/two-presets-8/run
[INFO] [2026-11-10 20:48:15 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:15 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:15 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:15 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:15 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:15 CET] Writing config to file: /tmp/heks-capture-spec-17783/two-presets-8/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:15 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/status-9
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/status-9/bin
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/status-9/shots
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/status-9/videos
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/status-9/gifs
[INFO] [2026-11-10 20:48:15 CET] Creating directory: /tmp/heks-capture-spec-17783/status-9/run
[INFO] [2026-11-10 20:48:16 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:16 CET] Writing config to file: /tmp/heks-capture-spec-17783/status-9/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:16 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:16 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-high-10
[INFO] [2026-11-10 20:48:16 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-high-10/bin
[INFO] [2026-11-10 20:48:16 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-high-10/shots
[INFO] [2026-11-10 20:48:16 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-high-10/videos
[INFO] [2026-11-10 20:48:16 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-high-10/gifs
[INFO] [2026-11-10 20:48:16 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-high-10/run
[INFO] [2026-11-10 20:48:16 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:16 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:16 CET] Writing config to file: /tmp/heks-capture-spec-17783/gif-high-10/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:16 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-empty-11
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-empty-11/bin
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-empty-11/shots
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-empty-11/videos
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-empty-11/gifs
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-empty-11/run
[INFO] [2026-11-10 20:48:32 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:32 CET] Writing config to file: /tmp/heks-capture-spec-17783/gif-empty-11/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:32 CET] Installed capture tooling
heks-capture: the recording came out empty
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-from-stdout-12
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-from-stdout-12/bin
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-from-stdout-12/shots
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-from-stdout-12/videos
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-from-stdout-12/gifs
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-from-stdout-12/run
[INFO] [2026-11-10 20:48:32 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:32 CET] Writing config to file: /tmp/heks-capture-spec-17783/gif-from-stdout-12/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:32 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-low-13
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-low-13/bin
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-low-13/shots
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-low-13/videos
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-low-13/gifs
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-low-13/run
[INFO] [2026-11-10 20:48:32 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:32 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:32 CET] Writing config to file: /tmp/heks-capture-spec-17783/gif-low-13/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:32 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-fallback-14
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-fallback-14/bin
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-fallback-14/shots
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-fallback-14/videos
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-fallback-14/gifs
[INFO] [2026-11-10 20:48:32 CET] Creating directory: /tmp/heks-capture-spec-17783/gif-fallback-14/run
[INFO] [2026-11-10 20:48:33 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:33 CET] Writing config to file: /tmp/heks-capture-spec-17783/gif-fallback-14/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:33 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:33 CET] Creating directory: /tmp/heks-capture-spec-17783/video-empty-15
[INFO] [2026-11-10 20:48:33 CET] Creating directory: /tmp/heks-capture-spec-17783/video-empty-15/bin
[INFO] [2026-11-10 20:48:33 CET] Creating directory: /tmp/heks-capture-spec-17783/video-empty-15/shots
[INFO] [2026-11-10 20:48:33 CET] Creating directory: /tmp/heks-capture-spec-17783/video-empty-15/videos
[INFO] [2026-11-10 20:48:33 CET] Creating directory: /tmp/heks-capture-spec-17783/video-empty-15/gifs
[INFO] [2026-11-10 20:48:33 CET] Creating directory: /tmp/heks-capture-spec-17783/video-empty-15/run
[INFO] [2026-11-10 20:48:33 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:33 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:33 CET] Writing config to file: /tmp/heks-capture-spec-17783/video-empty-15/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:33 CET] Installed capture tooling
heks-capture: the recording came out empty: see /tmp/heks-capture-spec-17783/video-empty-15/run/heks-capture/video-output.stop.log
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-region-16
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-region-16/bin
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-region-16/shots
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-region-16/videos
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-region-16/gifs
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-region-16/run
[INFO] [2026-11-10 20:48:49 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:49 CET] Writing config to file: /tmp/heks-capture-spec-17783/video-region-16/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:49 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-forced-wf-17
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-forced-wf-17/bin
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-forced-wf-17/shots
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-forced-wf-17/videos
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-forced-wf-17/gifs
[INFO] [2026-11-10 20:48:49 CET] Creating directory: /tmp/heks-capture-spec-17783/video-forced-wf-17/run
[INFO] [2026-11-10 20:48:49 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:49 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:49 CET] Writing config to file: /tmp/heks-capture-spec-17783/video-forced-wf-17/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:49 CET] Installed capture tooling
[INFO] [2026-11-10 20:48:50 CET] Creating directory: /tmp/heks-capture-spec-17783/video-gpu-18
[INFO] [2026-11-10 20:48:50 CET] Creating directory: /tmp/heks-capture-spec-17783/video-gpu-18/bin
[INFO] [2026-11-10 20:48:50 CET] Creating directory: /tmp/heks-capture-spec-17783/video-gpu-18/shots
[INFO] [2026-11-10 20:48:50 CET] Creating directory: /tmp/heks-capture-spec-17783/video-gpu-18/videos
[INFO] [2026-11-10 20:48:50 CET] Creating directory: /tmp/heks-capture-spec-17783/video-gpu-18/gifs
[INFO] [2026-11-10 20:48:50 CET] Creating directory: /tmp/heks-capture-spec-17783/video-gpu-18/run
[INFO] [2026-11-10 20:48:50 CET] Installing capture tooling
[INFO] [2026-11-10 20:48:50 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:48:50 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:48:50 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:48:50 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:48:50 CET] Writing config to file: /tmp/heks-capture-spec-17783/video-gpu-18/bin/heks-capture
[SUCCESS] [2026-11-10 20:48:50 CET] Installed capture tooling
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/video-window-19
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/video-window-19/bin
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/video-window-19/shots
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/video-window-19/videos
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/video-window-19/gifs
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/video-window-19/run
[INFO] [2026-11-10 20:49:06 CET] Installing capture tooling
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:49:06 CET] Writing config to file: /tmp/heks-capture-spec-17783/video-window-19/bin/heks-capture
[SUCCESS] [2026-11-10 20:49:06 CET] Installed capture tooling
heks-capture: video: 'window' cannot be recorded: a window needs a portal recorder such as OBS
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/program-20
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/program-20/bin
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/program-20/shots
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/program-20/videos
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/program-20/gifs
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/program-20/run
[INFO] [2026-11-10 20:49:06 CET] Installing capture tooling
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:49:06 CET] Writing config to file: /tmp/heks-capture-spec-17783/program-20/bin/heks-capture
[SUCCESS] [2026-11-10 20:49:06 CET] Installed capture tooling
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/unknown-21
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/unknown-21/bin
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/unknown-21/shots
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/unknown-21/videos
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/unknown-21/gifs
[INFO] [2026-11-10 20:49:06 CET] Creating directory: /tmp/heks-capture-spec-17783/unknown-21/run
[INFO] [2026-11-10 20:49:06 CET] Installing capture tooling
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Attempting override resolution for module (heks-linux capture) with profile 'capture-settings'
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/capture-settings.scm
[INFO] [2026-11-10 20:49:06 CET] load-local-overrides: No override file found at /tmp/heks-linux/capture-settings.scm. Skipping.
[INFO] [2026-11-10 20:49:06 CET] Writing config to file: /tmp/heks-capture-spec-17783/unknown-21/bin/heks-capture
[SUCCESS] [2026-11-10 20:49:06 CET] Installed capture tooling
heks-capture: pictures and recordings of this desktop
heks-capture shot region|output|window [--annotate] [--clipboard] [--geometry G]
A region, the focused output or the focused window. Saved and copied by
default; --clipboard keeps it off the disk, --annotate opens satty.
heks-capture gif region|output [--low] [--seconds N] [--geometry G]
A GIF as a toggle: the same command starts the recording and converts it.
--low cuts the width, the frame rate and the palette for chat-sized files.
CAPTURE_GIF_ENCODER=auto|gifski|ffmpeg picks the encoder; auto prefers gifski.
heks-capture video region|output [--hevc] [--seconds N] [--geometry G]
A video recording as a toggle; the file's path is copied when it stops.
heks-capture gif-edit [FILE] [--start S] [--duration S] [--speed F] [--crop X,Y+WxH]
[--width W] [--resize WxH] [--colors N] [--hue DEG]
[--saturation F] [--brightness F] [--contrast F]
[--reverse] [--fps N] [--lossy N]
Edit a GIF: gifsicle handles crops, resizes and palettes without
re-encoding; speed, trim, hue and reverse go through ffmpeg.
heks-capture annotate [FILE] [--editor satty|swappy|gimp]
Annotate the newest screenshot (or FILE) in the first editor
installed; the result is a new -annotated.png beside it.
heks-capture choose
One menu: screenshot, GIF or video, then the whole screen or a region.
heks-capture doctor
What the program needs and what is missing, with where to get it.
heks-capture studio [screenshot|gif]
The same edits as a rofi menu, answering prompts.
heks-capture gif-from FILE [--low]
Convert a video that already exists into a GIF.
heks-capture status | stop
What is recording now, and a way to stop all of it.
+----------------------------------------------+
[📑 suite] Screenshots
[🧪 test] A Clipboard-Only Shot Writes No File
[⚙️ assert] the shot succeeds
✅ got: 0
[⚙️ assert] nothing is written to the screenshots directory
✅ got: #t
[⚙️ assert] grim writes to stdout instead
✅ got: #t
[🧪 test] Annotation Runs Only When Asked For
[⚙️ assert] a plain screenshot does not open an editor
✅ got: #t
[⚙️ assert] --annotate hands the picture to satty
✅ got: #t
[🧪 test] A Window Is Captured By The Compositor
[⚙️ assert] the shot succeeds
✅ got: 0
[⚙️ assert] niri's own action takes the picture
✅ got: #t
[⚙️ assert] the file niri wrote is copied
✅ got: #t
[🧪 test] A Region Comes From Slurp, Or Nothing Happens
[⚙️ assert] the shot succeeds
✅ got: 0
[⚙️ assert] the geometry slurp answered is what grim is given
✅ got: #t
[⚙️ assert] a cancelled selection is not an error
✅ got: 0
[⚙️ assert] a cancelled selection captures nothing
✅ got: #t
[🧪 test] An Output Is Captured By Grim And Copied
[⚙️ assert] the shot succeeds
✅ got: 0
[⚙️ assert] grim is given the focused output
✅ got: #t
[⚙️ assert] a PNG lands in the screenshots directory
✅ got: #t
[⚙️ assert] the picture is copied to the clipboard
✅ got: #t
+----------------------------------------------+
[📑 suite] Toggles
[🧪 test] Stop Stops Everything That Started
[⚙️ assert] stop exits successfully
✅ got: 0
[⚙️ assert] the video recording is stopped
✅ got: #t
[⚙️ assert] the low GIF recording is stopped
✅ got: #t
[🧪 test] Two Qualities Are Two Recordings
[⚙️ assert] the high recording starts while the low one runs
✅ got: 0
[⚙️ assert] the low recording is untouched
✅ got: #t
[⚙️ assert] and the high one is its own recording
✅ got: #t
[🧪 test] Status Reports What Is Recording
[⚙️ assert] status exits successfully
✅ got: 0
[⚙️ assert] the GIF recording is on record
✅ got: #t
+----------------------------------------------+
[📑 suite] GIFs
[🧪 test] A High-Quality GIF Goes Through gifski
[⚙️ assert] the recording starts
✅ got: 0
[⚙️ assert] the second press converts it
✅ got: 0
[⚙️ assert] twenty frames a second
✅ got: #t
[⚙️ assert] gifski is given the frame rate and the quality
✅ got: #t
[⚙️ assert] the encoder is told not to shrink the frames
✅ got: #t
[⚙️ assert] a GIF lands in the GIFs directory
✅ got: #t
[⚙️ assert] the GIF is copied to the clipboard
✅ got: #t
[🧪 test] A Recording Without Content Is Not Encoded
[⚙️ assert] an empty recording fails
✅ got: 1
[⚙️ assert] no encoder is started for nothing
✅ got: #t
[🧪 test] gif-from Answers With The Path Alone
[⚙️ assert] the conversion succeeds
✅ got: #t
[⚙️ assert] the answer is one line
✅ got: 0
[⚙️ assert] the line is the path of a GIF
✅ got: #t
[⚙️ assert] the path names the GIF that was written
✅ got: #t
[🧪 test] The Low Preset Cuts The Size
[⚙️ assert] the conversion succeeds
✅ got: 0
[⚙️ assert] twelve frames a second at six hundred and forty pixels wide
✅ got: #t
[⚙️ assert] gifsicle is allowed to lose what nobody will see
✅ got: #t
[⚙️ assert] a GIF is written
✅ got: #t
[🧪 test] Without gifski The Palette Path Runs
[⚙️ assert] the conversion succeeds
✅ got: 0
[⚙️ assert] the small palette is built from the recording
✅ got: #t
[⚙️ assert] the frames are mapped through it
✅ got: #t
+----------------------------------------------+
[📑 suite] Video
[🧪 test] An Empty Recording Is Refused
[⚙️ assert] a recording with no data is a failure
✅ got: 1
[⚙️ assert] the user is not told an empty file was saved
✅ got: #t
[⚙️ assert] a failure is announced with the error icon
✅ got: #t
[🧪 test] A Region Recording Is Rounded To Even Pixels
[⚙️ assert] the recording starts
✅ got: 0
[⚙️ assert] an odd region is cut to what H.264 can encode
✅ got: #t
[⚙️ assert] slurp is asked for the position too, not only the size
✅ got: #t
[🧪 test] wf-recorder Is The Fallback
[⚙️ assert] the recording starts
✅ got: 0
[⚙️ assert] CAPTURE_RECORDER=wf-recorder forces the fallback
✅ got: #t
[⚙️ assert] it is told the encoder explicitly
✅ got: #t
[⚙️ assert] the profile the system's decoder needs is kept
✅ got: #t
[🧪 test] The GPU Recorder Is Used When It Exists
[⚙️ assert] the recording starts
✅ got: 0
[⚙️ assert] wl-screenrec is the recorder
✅ got: #t
[⚙️ assert] the codec is named the way wl-screenrec spells it
✅ got: #t
[⚙️ assert] the focused output is what gets recorded
✅ got: #t
[⚙️ assert] the second press stops the recording
✅ got: 0
[⚙️ assert] the recording is a non-empty file
✅ got: #t
[⚙️ assert] the pid file is gone once it stopped
✅ got: #t
[⚙️ assert] the user is told where it went
✅ got: #t
[🧪 test] A Window Recording Is Refused With A Reason
[⚙️ assert] there is nothing to record a window with
✅ got: 1
[⚙️ assert] the refusal names the tool that could do it
✅ got: #t
+----------------------------------------------+
[📑 suite] The Program
[🧪 test] The Script Is Written As An Executable Program
[⚙️ assert] the program is written
✅ got: #t
[⚙️ assert] it starts with a shell's shebang
✅ got: #t
[⚙️ assert] it is executable
✅ got: #t
[⚙️ assert] the screenshots directory is absolute, not a tilde
✅ got: #t
[⚙️ assert] no directory is left for the shell to expand
✅ got: #t
[🧪 test] An Unknown Verb Is A Usage Error
[⚙️ assert] an unknown verb exits 2
✅ got: 2
ℹ️ info - ran 5 tasks in: 53 seconds, 222781 microseconds
ℹ️ info - counted 1 file, 5 suites, 20 tests and 70 assertions
running unit tests from file: flatpak-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Command Vectors
[🧪 test] Install Arguments Are Separate Strings
[⚙️ assert] The id and remote are never one shell string
✅ got: (flatpak install --user --assumeyes flathub org.gnome.Boxes)
[⚙️ assert] A custom remote is passed through
✅ got: (flatpak install --user --assumeyes flathub-beta org.gnome.Boxes)
[🧪 test] Remote Addition Uses The Registered URL
[⚙️ assert] remote-add carries the .flatpakrepo URL
✅ got: (flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo)
[⚙️ assert] The beta repository is known
✅ got: https://dl.flathub.org/beta-repo/flathub-beta.flatpakrepo
[⚙️ assert] An unknown remote is an error
✅ success catching error: misc-error: (#f flatpak-remote-url: unknown remote: ~S (not-a-remote) #f)
+----------------------------------------------+
[📑 suite] Overrides
[🧪 test] An Extra Can Change An Existing Remote
[⚙️ assert] The extra declaration wins over the category
✅ got: flathub-beta
[🧪 test] Category Parameters Are Read At Call Time
[⚙️ assert] Replacing a category removes its apps
✅ got: #f
[⚙️ assert] The default category is back afterwards
✅ got: #t
[🧪 test] Extra Applications Join The Union
[⚙️ assert] An extra application joins the union
✅ got: #t
[🧪 test] A Duplicate Extra Entry Is Installed Once
[⚙️ assert] The first declaration wins
✅ got: 1
+----------------------------------------------+
[📑 suite] Catalog
[🧪 test] Applications Installed By Hand Are Now Declared
[⚙️ assert] Cantata is in the music category
✅ got: #t
[⚙️ assert] ytdn is in the media category
✅ got: #t
[⚙️ assert] Boxes is in the development category
✅ got: #t
[🧪 test] The Union Is Sorted And Duplicate-Free
[⚙️ assert] Applications are sorted by id
✅ got: #t
[⚙️ assert] No id is declared twice
✅ got: 61
[🧪 test] Every Entry Is Installable
[⚙️ assert] Every id passes the form check
✅ got: #t
[⚙️ assert] Every remote can be bootstrapped
✅ got: #t
[🧪 test] The Curated Additions Are Present
[⚙️ assert] LibreOffice fills the office gap
✅ got: #t
[⚙️ assert] KeePassXC fills the password-manager gap
✅ got: #t
[⚙️ assert] Telegram is declared
✅ got: #t
[⚙️ assert] DejaDup covers backups
✅ got: #t
[⚙️ assert] qBittorrent covers torrents
✅ got: #t
[⚙️ assert] Krita covers digital painting
✅ got: #t
[⚙️ assert] HandBrake covers video conversion
✅ got: #t
[⚙️ assert] Steam is declared for gaming
✅ got: #t
[⚙️ assert] RustDesk covers remote support
✅ got: #t
[⚙️ assert] Warehouse manages the Flatpak installation
✅ got: #t
[⚙️ assert] Zen Browser is still declared
✅ got: #t
+----------------------------------------------+
[📑 suite] Application Declarations
[🧪 test] The Default Remote Is Flathub
[⚙️ assert] A declaration produces an application record
✅ got: #t
[⚙️ assert] The ordinary entry needs no remote
✅ got: flathub
[⚙️ assert] An application can name another remote
✅ got: flathub-beta
[🧪 test] Symbols And Strings Are Both Accepted
[⚙️ assert] A symbol is coerced to the id string
✅ got: org.gnome.Boxes
[⚙️ assert] Ids are always strings in the catalog
✅ got: #t
[🧪 test] Malformed Ids Are Rejected
[⚙️ assert] An underscore in a segment is allowed
✅ got: #t
[⚙️ assert] A bare name is not an id
✅ got: #f
[⚙️ assert] The constructor refuses a bare name
✅ success catching error: misc-error: (#f flatpak-app: not a Flatpak application id: ~S (Boxes) #f)
[⚙️ assert] The constructor refuses whitespace
✅ success catching error: misc-error: (#f flatpak-app: not a Flatpak application id: ~S (org.gnome Boxes) #f)
ℹ️ info - ran 4 tasks in: 0 seconds, 40140 microseconds
ℹ️ info - counted 1 file, 4 suites, 13 tests and 37 assertions
running unit tests from file: zen-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Generated File
[🧪 test] The File Is Self-Describing
[⚙️ assert] The file carries a generated-file header
✅ got: #t
[⚙️ assert] The header says not to edit the file
✅ got: #t
[⚙️ assert] The header names the source of truth
✅ got: #t
[🧪 test] The Browser Toolbox Is Enabled With A Prompt
[⚙️ assert] Chrome debugging is available
✅ got: #t
[⚙️ assert] Remote debugging is available
✅ got: #t
[⚙️ assert] Connecting still asks for confirmation
✅ got: #t
[⚙️ assert] The external editor is off by default
✅ got: #f
[🧪 test] uBlock Origin Is Allowed To Start Enabled
[⚙️ assert] Side-loaded extensions are not disabled
✅ got: #t
[⚙️ assert] The profile scope is enabled
✅ got: #t
[🧪 test] The DevTools Theme Follows The Palette
[⚙️ assert] A dark palette asks for the dark theme
✅ got: #t
[⚙️ assert] A light palette asks for the light theme
✅ got: #t
[🧪 test] Vertical Tabs Are Declared
[⚙️ assert] The tab bar is vertical
✅ got: #t
[⚙️ assert] The tab bar stays on the left
✅ got: #t
[⚙️ assert] The sidebar starts expanded
✅ got: #t
[⚙️ assert] The sidebar has a laptop-friendly width
✅ got: #t
+----------------------------------------------+
[📑 suite] Parameters
[🧪 test] Compact Mode Is Opt-In
[⚙️ assert] Compact mode is off by default
✅ got: #f
[⚙️ assert] Turning it on adds the master preference
✅ got: #t
[⚙️ assert] The address bar stays visible
✅ got: #t
[🧪 test] Local Overrides Are Rendered Last
[⚙️ assert] The override line is present
✅ got: #t
[⚙️ assert] The generated line stays, so the override wins on load
✅ got: #t
[🧪 test] The Site-Breaking Prefs Are Opt-In
[⚙️ assert] Fingerprinting protection is off, and says so
✅ got: #t
[⚙️ assert] It is rendered when asked for
✅ got: #t
[⚙️ assert] The fingerprinting blocker travels with it
✅ got: #t
[⚙️ assert] HTTPS-Only mode is off, and says so
✅ got: #t
[⚙️ assert] It is rendered when asked for
✅ got: #t
[⚙️ assert] A trimmed profile is put back to Firefox's own policy
✅ got: #t
[🧪 test] Adblock Prefs Can Be Turned Off
[⚙️ assert] The sideload scopes disappear
✅ got: #f
[🧪 test] DevTools Can Be Turned Off
[⚙️ assert] The Toolbox prefs disappear together
✅ got: #f
[⚙️ assert] The external editor is enabled by its parameter
✅ got: #t
[⚙️ assert] The editor path follows its parameter
✅ got: #t
[⚙️ assert] The editor receives the line number
✅ got: #t
[⚙️ assert] The editor prefs disappear once it is unset
✅ got: #f
[🧪 test] Tracking Protection Is On By Default
[⚙️ assert] The custom ETP category keeps the individual prefs in charge
✅ got: #t
[⚙️ assert] Tracking protection is on
✅ got: #t
[⚙️ assert] Cryptominer blocking is on
✅ got: #t
[⚙️ assert] Link prefetching is off
✅ got: #t
[🧪 test] Hardening Can Be Turned Off
[⚙️ assert] Turning hardening off drops the block
✅ got: #f
[⚙️ assert] The layout is still declared
✅ got: #t
+----------------------------------------------+
[📑 suite] Value Serialization
[🧪 test] Scalars Render As JavaScript Literals
[⚙️ assert] Booleans render unquoted
✅ got: true
[⚙️ assert] False renders unquoted
✅ got: false
[⚙️ assert] Zero is a pref value, not an absence
✅ got: 0
[⚙️ assert] Integers render without Scheme punctuation
✅ got: 300
[🧪 test] Preference Lines Are user_pref Calls
[⚙️ assert] A boolean pref keeps its name and literal
✅ got: user_pref("zen.tabs.vertical", true);
[⚙️ assert] A numeric pref has no quotes
✅ got: user_pref("zen.view.sidebar-expanded.max-width", 300);
[🧪 test] Strings Are Quoted And Escaped
[⚙️ assert] A plain string is double-quoted
✅ got: "dark"
[⚙️ assert] A quote inside the value is escaped
✅ got: "a \"quoted\" path"
[⚙️ assert] A backslash inside the value is escaped
✅ got: "C:\\tmp"
ℹ️ info - ran 3 tasks in: 1 seconds, -801950 microseconds
ℹ️ info - counted 1 file, 3 suites, 15 tests and 47 assertions
running unit tests from file: image-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Heks-Linux Live Image Suite
[🧪 test] It Is Rendered Before It Ships
[⚙️ assert] heks-render should run maak home-reconfigure
✅ got: #t
[⚙️ assert] heks-render should run maak install-bash
✅ got: #t
[⚙️ assert] heks-render should run maak install-icon-files
✅ got: #t
[⚙️ assert] heks-render should run maak install-heks-toon
✅ got: #t
[⚙️ assert] heks-render should run maak install-lambdock
✅ got: #t
[⚙️ assert] The build should run maak home-reconfigure
✅ got: #t
[⚙️ assert] The build should run maak install-bash
✅ got: #t
[⚙️ assert] The build should run maak install-icon-files
✅ got: #t
[⚙️ assert] The build should run maak install-heks-toon
✅ got: #t
[⚙️ assert] The build should run maak install-lambdock
✅ got: #t
[⚙️ assert] heks-render should refuse to render another user's home as a user
✅ got: #t
[⚙️ assert] The unit should skip itself once the desktop is rendered
✅ got: #t
[⚙️ assert] The build should leave the marker the unit reads
✅ got: #t
[⚙️ assert] It is a one-shot, not a daemon
✅ got: #t
[⚙️ assert] Rendering downloads, so it should wait for the network
✅ got: #t
[🧪 test] The Live Account Is The One That Logs In
[⚙️ assert] The image should create the user it is named after
✅ got: heks
[⚙️ assert] The live user's home should be the one the checkouts are cloned into
✅ got: /home/heks
[⚙️ assert] The live user should be able to use sudo
✅ got: #t
[⚙️ assert] GDM should log in the same user the image creates
✅ got: #t
[⚙️ assert] The autologin should be enabled, not merely configured
✅ got: #t
[⚙️ assert] The display manager should be enabled
✅ got: #t
[⚙️ assert] The image should boot to the graphical target
✅ got: #t
[🧪 test] The Distribution Is Slowroll
[⚙️ assert] The image should be built from exactly two repositories
✅ got: 2
[⚙️ assert] The first repository should be Slowroll's open source one
✅ got: https://download.opensuse.org/slowroll/repo/oss/
[⚙️ assert] The repository should be included in the image, not only used to build it
✅ got: true
[⚙️ assert] The bootstrap set should carry the release package, or zypper cannot tell what it is
✅ got: #t
[⚙️ assert] The bootstrap set should carry the tools that create the live user
✅ got: #t
[🧪 test] It Installs As Well As Boots
[⚙️ assert] The description should produce a live ISO and an installable image
✅ got: 2
[⚙️ assert] One of them should be an OEM image
✅ got: #t
[⚙️ assert] The OEM image should ship an install ISO
✅ got: true
[⚙️ assert] An installed image should grow to the disk it lands on
✅ got: true
[⚙️ assert] The initrd module that grows it should be on the image
✅ got: #t
[🧪 test] What The Image Leaves Out
[⚙️ assert] The image should not carry a typesetting system
✅ got: #t
[⚙️ assert] The image should not carry a 3D suite
✅ got: #t
[⚙️ assert] The image should not carry a compiler toolchain
✅ got: #t
[⚙️ assert] The image should not carry an image editor
✅ got: #t
[⚙️ assert] The image should carry one network applet
✅ got: #t
[⚙️ assert] The one it carries should be the GNOME applet
✅ got: #t
[⚙️ assert] The workstation list should still carry the typesetting system
✅ got: #t
[🧪 test] The Image Follows The Desktop's Settings
[⚙️ assert] The image should be in the timezone the desktop declares
✅ got: Europe/Amsterdam
[⚙️ assert] The image should be in the locale the desktop declares
✅ got: nl_NL
[⚙️ assert] The image should carry the desktop's hostname
✅ got: #t
[🧪 test] The Description Is A Live Image
[⚙️ assert] The image should be an ISO
✅ got: iso
[⚙️ assert] The ISO should boot from an overlay, so the medium stays read-only
✅ got: overlay
[⚙️ assert] The same file should keep a session when it is written to a stick
✅ got: true
[⚙️ assert] The description should have preferences at all
✅ got: #t
[🧪 test] The Three Projects Are Pre-Loaded
[⚙️ assert] The image should clone heks-linux
✅ got: #t
[⚙️ assert] The image should clone heks-emacs
✅ got: #t
[⚙️ assert] The image should clone heks-bash
✅ got: #t
[⚙️ assert] The editor's configuration directory should be created
✅ got: #t
[⚙️ assert] The editor's configuration should be installed, not only checked out
✅ got: #t
[⚙️ assert] The editor's modules and snippets should be copied with it
✅ got: #t
[🧪 test] Guix And Nix Are On It
[⚙️ assert] The image should carry Guix
✅ got: #t
[⚙️ assert] The image should carry Nix
✅ got: #t
[⚙️ assert] The Guix daemon should be enabled, or the store cannot be added to
✅ got: #t
[⚙️ assert] Publishing the store on the network is not a desktop's job
✅ got: #t
[⚙️ assert] The store should stay writable, so its read-only mount is masked
✅ got: #t
[⚙️ assert] The nix daemon should start when something asks it to
✅ got: #t
[⚙️ assert] The build should wait for its own nix daemon
✅ got: #t
[⚙️ assert] The build should wait for its own guix daemon
✅ got: #t
[🧪 test] The Build Checks Itself
[⚙️ assert] The build should know what a ready system looks like
✅ got: #t
[⚙️ assert] It should check programs as well as files
✅ got: #t
[⚙️ assert] Guix should be one of the programs a ready image has
✅ got: #t
[⚙️ assert] Nix should be one of them too
✅ got: #t
[⚙️ assert] The build should have a phase that asks
✅ got: #t
[⚙️ assert] And it should refuse to produce an image that fails it
✅ got: #t
[🧪 test] The Description Is Well Formed XML
[⚙️ assert] The description should declare itself as UTF-8 XML
✅ got: #t
[⚙️ assert] The schema version should be the one KIWI 10.3 validates against
✅ got: #t
[⚙️ assert] Every element the description opens should be closed
✅ got: 24
[⚙️ assert] The renderer should not double-escape
✅ got: #f
[🧪 test] The Session Is On The Image
[⚙️ assert] The image should carry the bar
✅ got: #t
[⚙️ assert] The image should carry the compositor
✅ got: #t
[⚙️ assert] The image should carry the display manager
✅ got: #t
[⚙️ assert] The image should carry the editor
✅ got: #t
[⚙️ assert] The image should carry the language the desktop is written in
✅ got: #t
[⚙️ assert] The image should carry the audio server
✅ got: #t
[⚙️ assert] The image should carry the portals a Wayland session needs
✅ got: #t
[⚙️ assert] A live ISO boots from KIWI's own initrd module
✅ got: #t
[⚙️ assert] The image should carry the git its build clones with
✅ got: #t
[⚙️ assert] The image should carry the curl its first boot downloads with
✅ got: #t
[⚙️ assert] The image should carry the gpg that verifies the download
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 146523 microseconds
ℹ️ info - counted 1 file, 1 suite, 12 tests and 81 assertions
running unit tests from file: waybar-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Waybar Configuration Suite
[🧪 test] One Ink, No Accent
[⚙️ assert] The palette's accent should appear nowhere in the bar
✅ got: #f
[⚙️ assert] The bar should not keep a second, dimmer ink
✅ got: #f
[⚙️ assert] Every item should be painted in the palette's one ink
✅ got: ()
[⚙️ assert] The low battery should still be the one exception
✅ got: #t
[⚙️ assert] Every background should be the strip or a veil of the ink
✅ got: ()
[🧪 test] CSS Rules Generation
[⚙️ assert] CSS list should not be empty
✅ got: #t
[⚙️ assert] CSS should contain a rule for the waybar window
✅ got: #t
[⚙️ assert] Module background should be transparent in CSS
✅ got: transparent
[🧪 test] The Bar Wears The Menu Bar Material
[⚙️ assert] The bar should carry a sheen, not a flat fill
✅ got: #t
[⚙️ assert] The top edge should be lit
✅ got: #t
[⚙️ assert] The foot of the bar should be drawn
✅ got: #t
[⚙️ assert] The items should carry the menu bar's text shadow
✅ got: #t
[⚙️ assert] Items should keep the menu bar's tight spacing
✅ got: 0px 8px
[🧪 test] System Menu Rows
[⚙️ assert] The menu should answer what this machine is
✅ got: #t
[⚙️ assert] About should open the generated About window
✅ got: heks-about
[⚙️ assert] Search should be reachable from the menu too
✅ got: #t
[⚙️ assert] Search should open the Rofi launcher
✅ got: #t
[⚙️ assert] The second Rofi should wait for the menu to close
✅ got: #t
[⚙️ assert] The session rows are the power menu's own, not a second copy
✅ got: systemctl poweroff
[⚙️ assert] Locking the session should be one row away
✅ got: #t
[⚙️ assert] So should logging out
✅ got: #t
[⚙️ assert] The groups should be separated by rules nobody can pick
✅ got: #t
[⚙️ assert] A rule should be printed as a row Rofi cannot select
✅ got: #t
[⚙️ assert] The pointer should not be able to select a rule
✅ got: #t
[⚙️ assert] The menu should be a Rofi script-mode menu
✅ got: #t
[⚙️ assert] The script should hand itself to Rofi as the mode it opens
✅ got: #t
[⚙️ assert] The menu should drop from the top left, under the logo
✅ got: #t
[⚙️ assert] The window should be exactly as tall as its rows
✅ got: #t
[⚙️ assert] Every action should be detached from the menu's stdout
✅ got: #t
[🧪 test] Every Control Lights Up Under The Pointer
[⚙️ assert] A readout that opens a menu should light up
✅ got: #t
[⚙️ assert] The clock should wear the same highlight
✅ got: ((background . rgba(255, 255, 255, 0.12)) (border-radius . 6px))
[⚙️ assert] An action should wear the same highlight as its neighbours
✅ got: ((background . rgba(255, 255, 255, 0.12)) (border-radius . 6px))
[⚙️ assert] The wordmark included
✅ got: ((background . rgba(255, 255, 255, 0.12)) (border-radius . 6px))
[⚙️ assert] The tray belongs to other programs, so the bar leaves it alone
✅ got: #f
[🧪 test] About This Heks
[⚙️ assert] The window should read what the machine says it runs
✅ got: #t
[⚙️ assert] It should name the palette the desktop is wearing
✅ got: #t
[⚙️ assert] The uptime should not depend on a flag uptime may not have
✅ got: #t
[⚙️ assert] It should open a window rather than a second Rofi menu
✅ got: #t
[⚙️ assert] A machine with no GTK dialog should still say something
✅ got: #t
[⚙️ assert] The notification should carry the system icon
✅ got: #t
[🧪 test] Search Glyph
[⚙️ assert] The launcher should be a status item on the right
✅ got: #t
[⚙️ assert] The left of the bar is the machine's menu and what is open, as in the reference
✅ got: #f
[⚙️ assert] It should sit immediately before the clock
✅ got: custom/heks-search
[⚙️ assert] It should be the magnifier the search glyph wears
✅ got: #t
[⚙️ assert] It should name the solid face instead of trusting fallback
✅ got: <span font_family="Font Awesome 6 Free Solid"></span>
[⚙️ assert] The family belongs on the rule waybar's labels carry
✅ got: #t
[⚙️ assert] A family on the module never reaches the labels
✅ got: #f
[⚙️ assert] A quoted comma list is one family name, so icons are left to fallback
✅ got: #f
[⚙️ assert] A click should open the launcher
✅ got: #t
[⚙️ assert] An open launcher should be replaced, not left to refuse the click
✅ got: #t
[⚙️ assert] The right button should be the window switcher
✅ got: #t
[⚙️ assert] The launcher should be pointable at another one from the settings file
✅ got: #t
[⚙️ assert] The magnifier should wear the actions' style
✅ got: ((color . #ffffff) (padding . 0px 8px) (margin . 0px) (font-size . 12pt) (font-style . normal))
[🧪 test] Documentation Button
[⚙️ assert] The documentation button should sit on the bar
✅ got: #t
[⚙️ assert] Clicking it should open the documentation view
✅ got: #t
[⚙️ assert] It should ask the compositor for the activation a bar click cannot prove
✅ got: #t
[⚙️ assert] The glyph should be the book, in the solid face that has it
✅ got: <span font_family="Font Awesome 6 Free Solid"></span>
[⚙️ assert] The tooltip should say what the book opens
✅ got: #t
[🧪 test] Clipboard Button
[⚙️ assert] The clipboard button should sit on the bar
✅ got: #t
[⚙️ assert] The button should be the bar's own custom item
✅ got: custom/heks-clipboard
[⚙️ assert] The glyph should be the clipboard, named in the solid face
✅ got: <span font_family="Font Awesome 6 Free Solid"></span>
[⚙️ assert] Clicking it should browse the clipboard history
✅ got: #t
[⚙️ assert] An open rofi should be replaced, not left to refuse the click
✅ got: #t
[⚙️ assert] The picker should be pointable at another one from the settings file
✅ got: #t
[⚙️ assert] The clipboard glyph should wear the actions' style
✅ got: ((color . #ffffff) (padding . 0px 8px) (margin . 0px) (font-size . 12pt) (font-style . normal))
[🧪 test] Do Not Disturb Indicator
[⚙️ assert] Clicking the indicator should toggle the mako DND mode
✅ got: #t
[🧪 test] The Bar Is A Material, Not A White Slab
[⚙️ assert] A tint of zero should leave the neutral material
✅ got: rgba(242, 243, 245, 0.48)
[⚙️ assert] A tint of one should leave the palette's own background
✅ got: rgba(245, 245, 247, 0.48)
[⚙️ assert] The bar's own opacity should override the palette's
✅ got: rgba(242, 243, 245, 0.8)
[⚙️ assert] The light bar should not darken toward its foot
✅ got: #f
[⚙️ assert] The smoked bar should keep a shade at its foot
✅ got: #t
[⚙️ assert] A beige palette should give a warm-white bar
✅ got: rgba(238, 231, 212, 0.68)
[⚙️ assert] The light material's grey should be a setting
✅ got: rgba(10, 20, 30, 0.48)
[⚙️ assert] So should the smoked material's
✅ got: rgba(40, 50, 60, 0.68)
[⚙️ assert] A sheen of zero should leave a flat strip
✅ got: linear-gradient(180deg, rgba(255, 255, 255, 0.000) 0%, rgba(255, 255, 255, 0.000) 50%, rgba(255, 255, 255, 0.000) 100%)
[⚙️ assert] The hover veil's strength should be a setting
✅ got: rgba(56, 58, 66, 0.3)
[⚙️ assert] So should its corner radius
✅ got: 3px
[⚙️ assert] Extra CSS should be appended to the stylesheet
✅ got: #t
[⚙️ assert] The machine's CSS should be the stylesheet's last word
✅ got: #t
[🧪 test] Keyboard Layout Item
[⚙️ assert] The layout should be the bar's own custom item
✅ got: custom/heks-language
[⚙️ assert] The label should repaint on the bar's layout signal
✅ got: 8
[⚙️ assert] The label is not a poll: the menu pokes it
✅ got: once
[⚙️ assert] The label reads the layouts from the compositor
✅ got: #t
[⚙️ assert] The label bakes in the configured layouts, in the compositor's order
✅ got: #t
[⚙️ assert] The menu switches the layout through the compositor
✅ got: #t
[⚙️ assert] The menu pokes the bar so the label repaints at once
✅ got: #t
[⚙️ assert] The menu is only as tall as the layouts it lists
✅ got: #t
[🧪 test] Rounded Bar Styling
[⚙️ assert] The floating bar should carry the configured corner radius
✅ got: 0px
[⚙️ assert] The bar corner radius should be overridable
✅ got: 0px
[🧪 test] Password Manager Button
[⚙️ assert] The password manager should have a glyph on the bar
✅ got: #t
[⚙️ assert] The button should be the bar's own custom item
✅ got: custom/heks-password
[⚙️ assert] The glyph should be the key, in the solid face that has it
✅ got: <span font_family="Font Awesome 6 Free Solid"></span>
[⚙️ assert] The bar should open the machine's password manager
✅ got: 1password
[⚙️ assert] Clicking it should open that manager
✅ got: #t
[⚙️ assert] An open launcher should be replaced, not left to swallow the click
✅ got: #t
[⚙️ assert] It should ask the compositor to raise the window it opens
✅ got: #t
[⚙️ assert] The bar should be able to choose its own manager
✅ got: keepassxc
[⚙️ assert] A Flatpak install should come through the same setting
✅ got: #t
[⚙️ assert] The glyph itself should be a setting too
✅ got: <span font_family="Font Awesome 6 Free Solid"></span>
[⚙️ assert] The tooltip should name whichever manager the glyph opens
✅ got: #t
[⚙️ assert] The key should say what it opens
✅ got: #t
[⚙️ assert] The key should wear the actions' style
✅ got: ((color . #ffffff) (padding . 0px 8px) (margin . 0px) (font-size . 12pt) (font-style . normal))
[⚙️ assert] So should its hover
✅ got: ((background . rgba(255, 255, 255, 0.12)) (border-radius . 6px))
[🧪 test] System Menu At The Far Left
[⚙️ assert] The system menu should be the first thing on the bar
✅ got: custom/heks-system-menu
[⚙️ assert] The power glyph at the end of the row should be gone
✅ got: #f
[⚙️ assert] Its stylesheet rule should be gone with it
✅ got: #f
[⚙️ assert] The first item should wear the machine's mark
✅ got: <span font_family="Font Awesome 6 Free"></span>
[⚙️ assert] A machine should be able to wear a penguin instead
✅ got: <span font_family="DejaVu Sans">🐧︎</span>
[⚙️ assert] A word is left to the bar's own font, not wrapped in the mark's
✅ got: Heks
[⚙️ assert] The variation selector should not count as a second character
✅ got: 1
[⚙️ assert] A click should open the system menu
✅ got: #t
[⚙️ assert] The right button should still reach the session in one click
✅ got: #t
[⚙️ assert] The machine's own item should be styled by a rule of its own
✅ got: #t
[🧪 test] Wallpaper Button
[⚙️ assert] The wallpaper button should sit beside the palette
✅ got: #t
[⚙️ assert] Clicking it should open the wall chooser
✅ got: #t
[⚙️ assert] The button is a glyph, not a label
✅ got: #t
[⚙️ assert] The glyph should be the picture icon, named in the solid face
✅ got: <span font_family="Font Awesome 6 Free Solid"></span>
[⚙️ assert] The appearance buttons should share one rule
✅ got: #t
[⚙️ assert] The palette and the wall chooser should wear one style
✅ got: ((color . #ffffff) (padding . 0px 8px) (margin . 0px) (font-size . 12pt) (font-style . normal))
[🧪 test] Every Item Explains Itself On Hover
[⚙️ assert] A string in tooltip is a bool waybar ignores
✅ got: #f
[⚙️ assert] The reference says what its two buttons do
✅ got: #t
[⚙️ assert] So does the clipboard
✅ got: #t
[⚙️ assert] So does the system menu's logo
✅ got: #t
[⚙️ assert] So does the launcher
✅ got: #t
[⚙️ assert] So does the wall chooser
✅ got: #t
[⚙️ assert] So does the documentation
✅ got: #t
✅ got: ()
[⚙️ assert] The volume follows the wheel
✅ got: #t
[⚙️ assert] So does the brightness
✅ got: #t
[⚙️ assert] The music glyph can play and pause without a menu
✅ got: #t
[⚙️ assert] The battery reaches the session menu
✅ got: #t
[🧪 test] Keybinding Reference Button
[⚙️ assert] The question-mark button should sit on the bar
✅ got: #t
[⚙️ assert] The bar should carry only the new question mark
✅ got: #t
[⚙️ assert] The button should be a circled question mark glyph, in the solid face
✅ got: <span font_family="Font Awesome 6 Free Solid"></span>
[⚙️ assert] Clicking it should ask the compositor to activate it
✅ got: #t
[⚙️ assert] Clicking it should open the keyboard reference
✅ got: #t
[⚙️ assert] The button should be styled like the rest of the bar
✅ got: #t
[⚙️ assert] A right click should still reach the project page
✅ got: #t
[🧪 test] The Battery Warning Reads On Every Bar
[⚙️ assert] A warning should clear 4.5:1 on every palette's bar
✅ got: ()
[🧪 test] Main Configuration (JSON Source)
[⚙️ assert] Waybar config should be a list (convertible to JSON)
✅ got: #t
[⚙️ assert] Waybar position should be top by default
✅ got: top
[⚙️ assert] Modules should be represented as vectors for JSON arrays
✅ got: #t
[⚙️ assert] The do-not-disturb indicator should sit on the bar
✅ got: #t
[⚙️ assert] Only modules waybar implements should be in the config
✅ got: (#f #f)
ℹ️ info - ran 1 tasks in: 0 seconds, 289653 microseconds
ℹ️ info - counted 1 file, 1 suite, 20 tests and 144 assertions
running unit tests from file: rmpc-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Theme
[🧪 test] The Chrome Comes From The Palette
[⚙️ assert] the accent is the palette's primary
✅ got: #t
[⚙️ assert] no border colour is hardcoded
✅ got: #t
[⚙️ assert] the header carries the volume slider
✅ got: #t
[🧪 test] The Player Settings Are Polished
[⚙️ assert] the lists wrap
✅ got: #t
[⚙️ assert] the selection keeps its context
✅ got: #t
[⚙️ assert] a new song is scrolled into view
✅ got: #t
[⚙️ assert] the hook path is a literal tilde, not a format escape
✅ got: #t
+----------------------------------------------+
[📑 suite] Keymap
[🧪 test] The Emacs Session And File Keys Are Bound
[⚙️ assert] <C-x><C-c> is bound globally
✅ got: #t
[⚙️ assert] <C-x>o is bound globally
✅ got: #t
[⚙️ assert] <A-x> is bound globally
✅ got: #t
[⚙️ assert] <C-h>k is bound globally
✅ got: #t
[⚙️ assert] C-x C-s saves from the lists
✅ got: #t
[⚙️ assert] C-x C-w saves everything
✅ got: #t
[⚙️ assert] C-x k closes the view
✅ got: #t
[⚙️ assert] C-l reveals the playing song
✅ got: #t
[🧪 test] The Cursor And Page Keys Do Not Fight
[⚙️ assert] C-f is forward-char, not a page
✅ got: #t
[⚙️ assert] C-b is backward-char, not a page
✅ got: #t
[⚙️ assert] C-v pages forward, as in Emacs
✅ got: #t
[⚙️ assert] M-v pages back, as in Emacs
✅ got: #t
[🧪 test] The Emacs Movement Keys Are Bound
[⚙️ assert] <C-n> is bound
✅ got: #t
[⚙️ assert] <C-p> is bound
✅ got: #t
[⚙️ assert] <C-f> is bound
✅ got: #t
[⚙️ assert] <C-b> is bound
✅ got: #t
[⚙️ assert] <C-v> is bound
✅ got: #t
[⚙️ assert] <A-v> is bound
✅ got: #t
[⚙️ assert] <C-a> is bound
✅ got: #t
[⚙️ assert] <C-e> is bound
✅ got: #t
[⚙️ assert] <C-Space> is bound
✅ got: #t
[⚙️ assert] <C-k> is bound
✅ got: #t
[⚙️ assert] <C-s> is bound
✅ got: #t
[⚙️ assert] <C-g> is bound
✅ got: #t
[🧪 test] No Scope Binds A Key Twice
[⚙️ assert] global binds every key once
✅ got: 34
[⚙️ assert] navigation binds every key once
✅ got: 54
[⚙️ assert] queue binds every key once
✅ got: 7
ℹ️ info - ran 2 tasks in: 0 seconds, 43412 microseconds
ℹ️ info - counted 1 file, 2 suites, 6 tests and 34 assertions
running unit tests from file: ssh-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] SSH Suite
[🧪 test] Identities Are Declared Per Host
[⚙️ assert] GitHub should use the personal key
✅ got: #t
[⚙️ assert] Codeberg should use its own key
✅ got: #t
[⚙️ assert] A host that pins one key should not offer the rest
✅ got: #t
[🧪 test] Every Host In The Table Is Rendered
[⚙️ assert] There should be exactly one Host line per entry
✅ got: 4
[⚙️ assert] The GitHub alias should be rendered
✅ got: #t
[⚙️ assert] The Codeberg host should be rendered
✅ got: #t
[⚙️ assert] The wolk-jjba host should be rendered
✅ got: #t
[🧪 test] Keys Are Added To The Agent On First Use
[⚙️ assert] The config should hand a used key to the agent
✅ got: #t
[🧪 test] The Plain Agent Unit Is A Detached Agent
[⚙️ assert] The agent should not fork into the background twice
✅ got: #t
[⚙️ assert] The agent should listen on the runtime directory socket
✅ got: #t
[⚙️ assert] The unit should be enabled with the user session
✅ got: #t
[🧪 test] Host Keywords Start In The First Column
[⚙️ assert] Host is a block header, not an option: it must not be indented
✅ got: #t
[⚙️ assert] The options under a Host block stay indented
✅ got: #t
[🧪 test] The Environment File Names The Agent Socket
[⚙️ assert] The exported socket should be the one the agent listens on
✅ got: #t
[🧪 test] Non-Default Ports Are Rendered
[⚙️ assert] The wolk-jjba host listens on 2323
✅ got: #t
[⚙️ assert] The Storage Box listens on 23
✅ got: #t
[🧪 test] The Provider Decides Socket And Unit Together
[⚙️ assert] Without a keyring agent the plain unit is used
✅ got: ssh-agent.service
[⚙️ assert] and the plain socket is exported
✅ got: ${XDG_RUNTIME_DIR}/ssh-agent.socket
[⚙️ assert] With the keyring agent its socket unit is used
✅ got: gcr-ssh-agent.socket
[⚙️ assert] and the keyring socket is exported
✅ got: ${XDG_RUNTIME_DIR}/gcr/ssh
ℹ️ info - ran 1 tasks in: 0 seconds, 42872 microseconds
ℹ️ info - counted 1 file, 1 suite, 8 tests and 20 assertions
running unit tests from file: prelude-spec.scm, entrypoint: spec
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/symlinked
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/symlinked/repo
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/symlinked/conf
[INFO] [2026-11-10 20:49:07 CET] Writing config to file: /tmp/heks-prelude-spec-17783/symlinked/conf/linked.conf
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/installed
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/installed/nested
[INFO] [2026-11-10 20:49:07 CET] Writing config to file: /tmp/heks-prelude-spec-17783/installed/nested/deep.conf
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/a
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/a/b
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/a/b/c
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-prelude-spec-17783/bin
[INFO] [2026-11-10 20:49:07 CET] Writing config to file: /tmp/heks-prelude-spec-17783/bin/script.sh
+----------------------------------------------+
[📑 suite] Prelude Helper Suite
[🧪 test] Config Files Are Written Through Symlinks
[⚙️ assert] A dotfile linked into a repository should stay linked
✅ got: symlink
[⚙️ assert] Reading through the link should give the new contents
✅ got: new
[⚙️ assert] The file the link points at should be the one rewritten
✅ got: new
[🧪 test] Nested Structures Render As Ini Sections
[⚙️ assert] A nested list should become an INI section header
✅ got:
[settings]
port=8080
[🧪 test] Directory Trees Are Created Recursively
[⚙️ assert] Missing parents should be created, not just the leaf
✅ got: #t
[⚙️ assert] The created leaf should really be a directory
✅ got: #t
[🧪 test] Executable Config Files Get Executable Permissions
[⚙️ assert] Passing #o755 should make the file executable
✅ got: 493
[🧪 test] List Flattening
[⚙️ assert] Nested lists should be flattened
✅ got: (1 2 3 4 5)
[⚙️ assert] Flattening the empty list should stay empty
✅ got: ()
[🧪 test] Config Files Install Into Missing Directories
[⚙️ assert] The installer should create its directory tree
✅ got: #t
[⚙️ assert] The installer should write the contents
✅ got: hello
[⚙️ assert] The default permissions should be #o644
✅ got: 420
[🧪 test] Key Value Rendering
[⚙️ assert] Pairs should render with the default template
✅ got: host=localhost
port=80
[⚙️ assert] The template should be overridable
✅ got: host = localhost
[⚙️ assert] CSS pairs should render indented
✅ got: color: black;
ℹ️ info - ran 1 tasks in: 0 seconds, 27406 microseconds
ℹ️ info - counted 1 file, 1 suite, 7 tests and 15 assertions
running unit tests from file: toon-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-toon-spec-17783
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-toon-spec-17783/again
[INFO] [2026-11-10 20:49:07 CET] Retiring the HTML pages heks-toon replaces
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Attempting override resolution for module (heks-linux toon) with profile 'toon-settings'
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/toon-settings.scm
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: No override file found at /tmp/heks-linux/toon-settings.scm. Skipping.
[INFO] [2026-11-10 20:49:07 CET] Removed the retired page launcher: /tmp/heks-toon-spec-17783/again/heks-keybindings
[SUCCESS] [2026-11-10 20:49:07 CET] Installed heks-toon configuration
[INFO] [2026-11-10 20:49:07 CET] Retiring the HTML pages heks-toon replaces
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Attempting override resolution for module (heks-linux toon) with profile 'toon-settings'
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/toon-settings.scm
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: No override file found at /tmp/heks-linux/toon-settings.scm. Skipping.
[SUCCESS] [2026-11-10 20:49:07 CET] Installed heks-toon configuration
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-toon-spec-17783
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-toon-spec-17783/bin
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-toon-spec-17783/config
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-toon-spec-17783/config/heks-linux
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-toon-spec-17783/config/heks-linux/keybindings
[INFO] [2026-11-10 20:49:07 CET] Retiring the HTML pages heks-toon replaces
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Attempting override resolution for module (heks-linux toon) with profile 'toon-settings'
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/toon-settings.scm
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: No override file found at /tmp/heks-linux/toon-settings.scm. Skipping.
[INFO] [2026-11-10 20:49:07 CET] Removed the retired page launcher: /tmp/heks-toon-spec-17783/bin/heks-keybindings
[INFO] [2026-11-10 20:49:07 CET] Removed the retired page launcher: /tmp/heks-toon-spec-17783/bin/heks-wallpaper-gallery
[INFO] [2026-11-10 20:49:07 CET] Removed the retired page launcher: /tmp/heks-toon-spec-17783/bin/heks-palette-gallery
[INFO] [2026-11-10 20:49:07 CET] Removed the retired page: /tmp/heks-toon-spec-17783/config/heks-linux/keybindings/index.html
[INFO] [2026-11-10 20:49:07 CET] Removed the retired page directory: /tmp/heks-toon-spec-17783/config/heks-linux/keybindings
[SUCCESS] [2026-11-10 20:49:07 CET] Installed heks-toon configuration
+----------------------------------------------+
[📑 suite] heks-toon Suite
[🧪 test] The Bar Launches The Views
[⚙️ assert] The question mark opens the reference
✅ got: #t
[⚙️ assert] The palette glyph opens the palette chooser
✅ got: #t
[⚙️ assert] The picture glyph opens the wall chooser
✅ got: #t
[🧪 test] The Views Are One Program
[⚙️ assert] The keyboard reference is the default view
✅ got: heks-toon
[⚙️ assert] The wall chooser names its view
✅ got: heks-toon walls
[⚙️ assert] The palette chooser names its view
✅ got: heks-toon palettes
[⚙️ assert] The documentation view names its view
✅ got: heks-toon docs
[🧪 test] Retiring A Second Time Is Harmless
[⚙️ assert] The launcher should be gone after both runs
✅ got: #t
[🧪 test] The Bar Asks The Compositor To Spawn The Window
[⚙️ assert] The command should go through niri's spawn first
✅ got: #t
[⚙️ assert] It should fall back to running the program
✅ got: #t
[🧪 test] The Pages Are Retired
[⚙️ assert] Every launcher the pages installed should be gone
✅ got: #t
[⚙️ assert] The generated keyboard reference should be gone
✅ got: #t
[⚙️ assert] A launcher this configuration still owns should stay
✅ got: #t
[⚙️ assert] The window is a program, not a generated launcher
✅ got: #t
[🧪 test] The Window Rule Matches The Program
[⚙️ assert] The application id is the program's own
✅ got: org.jointhefreeworld.heks-toon
[⚙️ assert] Niri should match the window by that id
✅ got: #t
[⚙️ assert] The window should be focused the moment it opens
✅ got: #t
[⚙️ assert] The compositor should blur what is behind the glass
✅ got: #t
[⚙️ assert] Every block should serialize as KDL, not as a record
✅ got: #t
[⚙️ assert] The browser window rule the pages needed should be gone
✅ got: #t
[🧪 test] The Command Is A Parameter
[⚙️ assert] An overridden command keeps its view
✅ got: /tmp/heks-toon palettes
[⚙️ assert] An overridden command needs no argument
✅ got: /tmp/heks-toon
ℹ️ info - ran 1 tasks in: 0 seconds, 180468 microseconds
ℹ️ info - counted 1 file, 1 suite, 7 tests and 22 assertions
running unit tests from file: palette-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Palette Registry Suite
[🧪 test] Colour Converters
[⚙️ assert] hex-to-rgba should convert a hex colour
✅ got: rgba(255, 0, 0, 1)
[⚙️ assert] hex-to-rgba should honour the alpha argument
✅ got: rgba(0, 0, 255, 0.5)
[⚙️ assert] hex-to-rgb should convert a hex colour
✅ got: rgb(0, 255, 0)
[⚙️ assert] hex-to-rgba should fall back on bad input
✅ got: rgba(0, 0, 0, 1)
[🧪 test] Unknown Palettes Are Rejected
[⚙️ assert] Looking up an unregistered palette should raise
✅ success catching error: %exception: (#<&message message: "unknown palette selected: definitely-not-a-palette">)
[🧪 test] Registry Is Non Empty And Symbolic
[⚙️ assert] At least one palette should be registered
✅ got: #t
[⚙️ assert] Every palette name should be a symbol
✅ got: #t
[⚙️ assert] Every palette name should be convertible to a string
✅ got: #t
[🧪 test] Golden Gate Is More Transparent
[⚙️ assert] Both Golden Gate variants must be more transparent than every other palette
✅ got: #t
[🧪 test] Contrast Is Measured, Not Assumed
[⚙️ assert] Black on white should be 21:1
✅ got: #t
[⚙️ assert] A colour on itself should be 1:1
✅ got: #t
[⚙️ assert] #767676 is the lightest grey that clears AA on white
✅ got: #t
[⚙️ assert] The first candidate that clears the floor should win
✅ got: #333333
[⚙️ assert] An ink that cannot be read should give way to plain black
✅ got: #000000
[⚙️ assert] On a dark surface the fallback is white, not black
✅ got: #ffffff
[🧪 test] Colours Can Be Mixed
[⚙️ assert] Halfway between black and white should be grey
✅ got: #808080
[⚙️ assert] A weight of zero should leave the base alone
✅ got: #000000
[⚙️ assert] A weight of one should return the other colour
✅ got: #ffffff
[⚙️ assert] A weight past one should clamp, not overflow
✅ got: #ffffff
[⚙️ assert] Each channel should move by its own amount
✅ got: #eee5cd
[⚙️ assert] Malformed input should fall back on the base colour
✅ got: #123456
[🧪 test] Every Palette Exposes A Full Colour Set
[⚙️ assert] Each palette must define primary/text/background colours
✅ got: #t
[🧪 test] Every Palette Exposes App Opacities
[⚙️ assert] Each palette must declare a 0-1 opacity for every app
✅ got: #t
[🧪 test] Dark And Light Classification
[⚙️ assert] catppuccin-mocha should be a dark palette
✅ got: #t
[⚙️ assert] catppuccin-latte should be a light palette
✅ got: #t
[🧪 test] Every Palette Wears A Tela Icon Theme
[⚙️ assert] Every icon theme should be a Tela variant the installer carries
✅ got: #t
[⚙️ assert] The icon theme should follow the palette's accent and brightness
✅ got: #t
[⚙️ assert] GTK's purple accent should map to the light purple artwork
✅ got: Tela-purple-light
[⚙️ assert] A dark palette should take the dark purple artwork
✅ got: Tela-purple-dark
[⚙️ assert] Green should take the green artwork
✅ got: Tela-green-light
[⚙️ assert] Cyan should take the nearest colour Tela ships
✅ got: Tela-blue-light
[⚙️ assert] An accent no Tela variant carries should raise
✅ success catching error: %exception: (#<&message message: "exception ocurred! unknown icon accent selected: chartreuse">)
[🧪 test] Every Palette Exposes Its Downstream Themes
[⚙️ assert] Each palette must map to a GTK, icon, cursor and accent theme
✅ got: #t
[⚙️ assert] Each palette must map to a supported lambdock theme
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 52239 microseconds
ℹ️ info - counted 1 file, 1 suite, 11 tests and 34 assertions
running unit tests from file: wallpaper-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-wallpaper-spec-17783
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-wallpaper-spec-17783/bin
[INFO] [2026-11-10 20:49:07 CET] Installing wallpaper management configuration
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Attempting override resolution for module (heks-linux wallpaper) with profile 'wallpaper-settings'
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Using $XDG_CONFIG_HOME: /tmp
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: Checking for override file at: /tmp/heks-linux/wallpaper-settings.scm
[INFO] [2026-11-10 20:49:07 CET] load-local-overrides: No override file found at /tmp/heks-linux/wallpaper-settings.scm. Skipping.
[INFO] [2026-11-10 20:49:07 CET] Writing config to file: /tmp/heks-wallpaper-spec-17783/bin/heks-wallpaper
[INFO] [2026-11-10 20:49:07 CET] Removed the retired Rofi wallpaper picker: /tmp/heks-wallpaper-spec-17783/bin/heks-wallpaper-chooser
[INFO] [2026-11-10 20:49:07 CET] Creating directory: /tmp/heks-wallpaper-spec-17783/systemd
[INFO] [2026-11-10 20:49:07 CET] Writing config to file: /tmp/heks-wallpaper-spec-17783/systemd/heks-wallpaper.service
[INFO] [2026-11-10 20:49:07 CET] Writing config to file: /tmp/heks-wallpaper-spec-17783/systemd/heks-wallpaper.timer
[SUCCESS] [2026-11-10 20:49:07 CET] Installed wallpaper management configuration
+----------------------------------------------+
[📑 suite] Wallpaper Engine Suite
[🧪 test] Every Palette Resolves To Absolute Paths
[⚙️ assert] No palette may end up without a wallpaper set
✅ got: #t
[🧪 test] The Engine Finds The Compositor Instead Of Guessing It
[⚙️ assert] The engine should read WAYLAND_DISPLAY
✅ got: #t
[⚙️ assert] The engine should discover the socket in XDG_RUNTIME_DIR
✅ got: #t
[⚙️ assert] The old guess at the display name must be gone
✅ got: #t
[⚙️ assert] Waiting for the compositor should fail loudly
✅ got: #t
[🧪 test] Installing Writes Every Artefact
[⚙️ assert] The engine should be installed
✅ got: #t
[⚙️ assert] The engine should be executable
✅ got: #t
[⚙️ assert] The retired Rofi wallpaper picker should not be installed
✅ got: #t
[⚙️ assert] The service should be installed
✅ got: #t
[⚙️ assert] The timer should be installed
✅ got: #t
[🧪 test] The Engine Detaches Its Renderer
[⚙️ assert] The renderer should outlive the service that started it
✅ got: #t
[⚙️ assert] The previous swaybg should be replaced, by exact name
✅ got: #t
[⚙️ assert] A renderer that died on connect must be noticed
✅ got: #t
[⚙️ assert] The layer-shell renderer should be selectable
✅ got: #t
[🧪 test] The Engine Carries The Whole Palette Set
[⚙️ assert] One quoted wallpaper per line, and no more
✅ got: 2
[⚙️ assert] Every palette wallpaper should be reachable from the engine
✅ got: #t
[🧪 test] The Engine Remembers And Restores
[⚙️ assert] The engine should keep the wallpaper it set
✅ got: #t
[⚙️ assert] The compositor should be able to re-apply that wallpaper
✅ got: #t
[⚙️ assert] next and prev need to know where the current image sits
✅ got: #t
[🧪 test] Catalogued Palettes Use Their Own Directories
[⚙️ assert] catppuccin-mocha should use its own artwork
✅ got: #t
[⚙️ assert] ayu-dark should use the space artwork
✅ got: #t
[🧪 test] The Engine Is A POSIX Shell Script
[⚙️ assert] The engine should run under any sh
✅ got: #t
[⚙️ assert] The engine must not use bash test syntax
✅ got: #t
[⚙️ assert] The engine must not read the bash-only RANDOM
✅ got: #t
[🧪 test] Tinted Operandi Reaches The System Set
[⚙️ assert] modus-operandi-tinted must not be swallowed by the generic operandi clause
✅ got: #t
[⚙️ assert] The system wallpaper set should not be empty
✅ got: #t
[🧪 test] Unknown Palettes Are Rejected
[⚙️ assert] An unregistered palette should raise instead of picking nothing
✅ success catching error: %exception: (#<&message message: "unknown palette selected: not-a-real-palette, so there is no wallpaper set">)
[🧪 test] Generic Operandi Uses The Bergen Set
[⚙️ assert] modus-operandi should stay inside the shared wallpaper tree
✅ got: #t
[⚙️ assert] modus-operandi should include the Bergen backgrounds
✅ got: #t
[🧪 test] The Service Finishes So The Timer Can Fire Again
[⚙️ assert] The service should be a unit file
✅ got: #t
[⚙️ assert] A simple unit around a renderer that never exits cannot be re-triggered
✅ got: #t
[⚙️ assert] The detached renderer must survive the oneshot finishing
✅ got: #t
[⚙️ assert] The service should run the installed engine
✅ got: #t
[🧪 test] The Timer Rotates Every Ninety Minutes
[⚙️ assert] The timer needs the first change to be scheduled
✅ got: #t
[⚙️ assert] And every change after it to repeat
✅ got: #t
[⚙️ assert] The schedule should be the configured interval
✅ got: #t
[⚙️ assert] The wallpaper should change every ninety minutes by default
✅ got: 1h30m
[⚙️ assert] A calendar entry cannot say ninety minutes, so there should not be one
✅ got: #f
[⚙️ assert] The timer should name the service it starts
✅ got: #t
[⚙️ assert] The timer should be enable-able
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 76995 microseconds
ℹ️ info - counted 1 file, 1 suite, 13 tests and 40 assertions
running unit tests from file: wezterm-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Generated File
[🧪 test] The Mux Agent Does Not Shadow The Session Agent
[⚙️ assert] The generated file leaves the agent to the session
✅ got: #t
[🧪 test] Settings And Colours Follow The System
[⚙️ assert] Scrollback matches the other terminals
✅ got: #t
[⚙️ assert] Opacity is set
✅ got: #t
[⚙️ assert] The font is a fallback list
✅ got: #t
[⚙️ assert] Padding is applied on every side
✅ got: #t
[⚙️ assert] The shell is bash, as in the other terminals
✅ got: #t
[⚙️ assert] The background follows the selected palette
✅ got: #t
[⚙️ assert] The foreground follows the selected palette
✅ got: #t
[🧪 test] Control+C Stays The Interrupt
[⚙️ assert] Control+C is never taken by the terminal
✅ got: #f
[🧪 test] Title Bar And Resize Border Are Requested
[⚙️ assert] A title bar and a resize border are requested
✅ got: #t
[⚙️ assert] No window is undecorated
✅ got: #f
[⚙️ assert] The title bar is not dropped for the border
✅ got: #f
[⚙️ assert] No window buttons are drawn into the tab bar
✅ got: #f
[⚙️ assert] The decorations do not depend on the platform
✅ got: #f
[⚙️ assert] The tab bar is enabled
✅ got: #t
[⚙️ assert] The tab bar is the one WezTerm paints itself
✅ got: #t
[⚙️ assert] The tab bar stays visible for a single pane, as the title bar
✅ got: #t
[⚙️ assert] The tab bar carries a close button
✅ got: #t
[🧪 test] The File Is Self-Describing
[⚙️ assert] The file carries a generated-file header
✅ got: #t
[⚙️ assert] The header says not to edit the file
✅ got: #t
[⚙️ assert] The header names the source of truth
✅ got: #t
[⚙️ assert] The configuration is built from the builder
✅ got: #t
[⚙️ assert] The file returns the configuration
✅ got: #t
[⚙️ assert] Every section banner is the same width
✅ got: #t
[🧪 test] Meta And The Keyboard Protocol Are Configured
[⚙️ assert] Left Option sends Meta
✅ got: #t
[⚙️ assert] Right Option sends Meta
✅ got: #t
[⚙️ assert] The kitty keyboard protocol is left available to applications
✅ got: #t
+----------------------------------------------+
[📑 suite] Guarded Bindings
[🧪 test] The Bare Defaults Are Re-Registered Through The Guard
[⚙️ assert] Control+Tab still switches tabs
✅ got: #t
[⚙️ assert] Alt+Enter still toggles full screen
✅ got: #t
[⚙️ assert] Control+Insert still copies the selection
✅ got: #t
[⚙️ assert] Every guarded default is registered exactly once
✅ got: 6
[🧪 test] The Emacs Chords Are Registered
[⚙️ assert] Control+Y pastes
✅ got: #t
[⚙️ assert] Alt+W copies
✅ got: #t
[⚙️ assert] Control+= grows the font, as text-scale-increase does
✅ got: #t
[⚙️ assert] Control+- shrinks the font, as text-scale-decrease does
✅ got: #t
[⚙️ assert] Shift+Left moves to the previous tab
✅ got: #t
[⚙️ assert] Shift+Right moves to the next tab
✅ got: #t
[⚙️ assert] Shift+Up also moves to the previous tab
✅ got: #t
[⚙️ assert] Shift+Down also moves to the next tab
✅ got: #t
[⚙️ assert] Shift+PageUp pages the scrollback
✅ got: #t
[🧪 test] Every Chord Is Guarded
[⚙️ assert] Chords are dispatched through a callback
✅ got: #t
[⚙️ assert] The callback asks the pane which process is in front
✅ got: #t
[⚙️ assert] The chord is re-sent to the application
✅ got: #t
[⚙️ assert] The terminal only acts when the keyboard is free
✅ got: #t
[🧪 test] The Emacs Page Keys Are Claimed
[⚙️ assert] Control+V pages the scrollback forward
✅ got: #t
[⚙️ assert] Alt+V pages the scrollback back
✅ got: #t
+----------------------------------------------+
[📑 suite] Emacs Prefix
[🧪 test] Emacs Commands Keep Their Keys
[⚙️ assert] Control+X 2 splits below
✅ got: #t
[⚙️ assert] Control+X 3 splits right
✅ got: #t
[⚙️ assert] Control+X 0 closes the tab
✅ got: #t
[⚙️ assert] Control+X t opens a new tab
✅ got: #t
[⚙️ assert] Control+X 1 leaves one pane
✅ got: #t
[⚙️ assert] Control+X o moves to the other tab
✅ got: #t
[⚙️ assert] Control+X b picks a tab like a buffer
✅ got: #t
[⚙️ assert] Control+X g quits the prefix
✅ got: #t
[⚙️ assert] Control+X <right> moves to the next tab
✅ got: #t
[🧪 test] Control+X Opens The Prefix Table
[⚙️ assert] Control+X activates the table
✅ got: #t
[⚙️ assert] An unknown second key leaves the table
✅ got: #t
[⚙️ assert] An abandoned prefix gives up on its own
✅ got: #t
[🧪 test] A Prefix Matches With Control Held Or Released
[⚙️ assert] Each entry is expanded into both spellings
✅ got: #t
+----------------------------------------------+
[📑 suite] Lua Value Serialization
[🧪 test] Scalars Render As Lua Literals
[⚙️ assert] Booleans render unquoted
✅ got: true
[⚙️ assert] False renders unquoted
✅ got: false
[⚙️ assert] Numbers render unquoted
✅ got: 12
[⚙️ assert] Strings are single-quoted so they need no escapes
✅ got: 'bash'
[🧪 test] Tables Are Laid Out One Entry Per Line
[⚙️ assert] An object becomes an indented table
✅ got: {
foreground = '#ffffff',
background = '#1d2021',
}
[⚙️ assert] An array becomes an indented table
✅ got: {
'bash',
}
[⚙️ assert] A compact table stays on one line
✅ got: { left = 16, top = 4 }
[🧪 test] Table Names Are Bracketed When Lua Needs It
[⚙️ assert] A valid identifier is emitted bare
✅ got: scrollback_lines
[⚙️ assert] A name with a dash is bracketed
✅ got: ['emacs-cx']
[🧪 test] Literal Lua Passes Through
[⚙️ assert] A raw fragment is emitted verbatim
✅ got: act.TogglePaneZoomState
[⚙️ assert] Raw fragments are recognisable
✅ got: #t
+----------------------------------------------+
[📑 suite] Passthrough
[🧪 test] Emacs And The Pager Own The Keyboard
[⚙️ assert] Emacs is declared as an owning application
✅ got: #t
[⚙️ assert] less is declared as an owning application
✅ got: #t
[⚙️ assert] Emacs is in the default application list
✅ got: #t
[⚙️ assert] less is in the default application list
✅ got: #t
[🧪 test] The Application List Is Matched On The Base Name
[⚙️ assert] A full path such as /usr/bin/less still matches
✅ got: #t
[⚙️ assert] The directory part of the process name is dropped
✅ got: #t
[⚙️ assert] A version suffix is allowed, so python3.13 matches python
✅ got: #t
[⚙️ assert] The base name is matched against the compiled patterns
✅ got: #t
+----------------------------------------------+
[📑 suite] Binding Serialization
[🧪 test] Prefix Entries Carry No Modifier
[⚙️ assert] The runtime adds the modifiers a prefix needs
✅ got: { key = '2', action = act.TogglePaneZoomState }
[🧪 test] Bindings Render As Inline Lua Tables
[⚙️ assert] A key assignment is one inline table
✅ got: { key = 'y', mods = 'CTRL', action = act.PasteFrom 'Clipboard' }
[⚙️ assert] A named key keeps its WezTerm spelling
✅ got: { key = 'PageUp', mods = 'SHIFT', action = act.ScrollByPage(-1) }
+----------------------------------------------+
[📑 suite] Modifier Translation
[🧪 test] Short Modifiers Use WezTerm Spelling
[⚙️ assert] Modifiers are joined with a vertical bar
✅ got: CTRL|SHIFT
[⚙️ assert] Alt and Super are spelled out
✅ got: ALT|SUPER
[⚙️ assert] Unknown modifiers pass through
✅ got: CTRL|Custom
ℹ️ info - ran 7 tasks in: 0 seconds, 589980 microseconds
ℹ️ info - counted 1 file, 7 suites, 22 tests and 84 assertions
running unit tests from file: dconf-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] dconf test suite
[🧪 test] mk-nested-dconf-writer-commands
[⚙️ assert] Nested settings should flatten into dconf write commands
✅ got: (echo "/org/gnome/desktop/interface/gtk-key-theme --> 'Emacs'" && dconf write "/org/gnome/desktop/interface/gtk-key-theme" "'Emacs'" echo "/org/gnome/desktop/interface/cursor-size --> 24" && dconf write "/org/gnome/desktop/interface/cursor-size" "24" echo "/org/gnome/desktop/interface/enable-animations --> true" && dconf write "/org/gnome/desktop/interface/enable-animations" "true")
[🧪 test] caps-to-ctrl follows its parameter
[⚙️ assert] Disabling caps-to-ctrl must write false, not a hardcoded true
✅ got: #t
[⚙️ assert] Enabling caps-to-ctrl must write true
✅ got: #t
[🧪 test] Heks settings are namespaced and complete
[⚙️ assert] The language should be written under /heks-linux
✅ got: #t
[⚙️ assert] The palette should be exported to dconf
✅ got: #t
[⚙️ assert] The mono font should be exported to dconf
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 35688 microseconds
ℹ️ info - counted 1 file, 1 suite, 3 tests and 6 assertions
running unit tests from file: icons-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Tela Icon Themes Suite
[🧪 test] Accents Pick The Matching Variant
[⚙️ assert] A light purple palette should take the light purple artwork
✅ got: Tela-purple-light
[⚙️ assert] A dark purple palette should take the dark purple artwork
✅ got: Tela-purple-dark
[⚙️ assert] Green should take the green artwork
✅ got: Tela-green-light
[⚙️ assert] Cyan should take the nearest colour Tela ships
✅ got: Tela-blue-light
[⚙️ assert] Black should take the black artwork
✅ got: Tela-black-dark
[⚙️ assert] An accent no Tela variant carries should raise
✅ success catching error: %exception: (#<&message message: "exception ocurred! unknown icon accent selected: chartreuse">)
[🧪 test] Every Accent Has An Installed Theme
[⚙️ assert] Every accent should name a theme the installer puts in place
✅ got: #t
[🧪 test] The Checkout Is Pinned To A Release
[⚙️ assert] The installer should name its checkout
✅ got: tela-icon-theme
[⚙️ assert] The installer should clone a released tag, not a branch
✅ got: 2026-07-07
[⚙️ assert] The theme should come from its own Git repository
✅ got: #t
[🧪 test] Every Variant Is Installed Whole
[⚙️ assert] Tela 2026-07-07 ships fifteen colour variants
✅ got: 15
[⚙️ assert] Each colour is rendered at three brightnesses
✅ got: 3
[⚙️ assert] Fifteen colours at three brightnesses make forty-five themes
✅ got: 45
[⚙️ assert] No variant should be installed twice
✅ got: 45
[⚙️ assert] Every entry should be a Tela theme
✅ got: #t
[⚙️ assert] The standard colour should be the bare Tela theme
✅ got: #t
[⚙️ assert] A colour and brightness pair should be installed
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 10989 microseconds
ℹ️ info - counted 1 file, 1 suite, 4 tests and 17 assertions
running unit tests from file: eca-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] ECA Suite
[🧪 test] The Asset Follows The Machine
[⚙️ assert] An x86_64 machine takes the amd64 build
✅ got: eca-cli-linux-amd64.tar.gz
[⚙️ assert] An aarch64 machine takes the aarch64 build
✅ got: eca-cli-linux-aarch64.tar.gz
[🧪 test] The Release URL Names The Pinned Version
[⚙️ assert] The URL carries the pinned version
✅ got: #t
[⚙️ assert] The URL carries the asset this machine installs
✅ got: #t
[🧪 test] The Key Is A Command, Not A Secret
[⚙️ assert] The key is decrypted when a request is made
✅ got: #t
[⚙️ assert] No API key is written into the file
✅ got: #t
[🧪 test] The Configuration Holds A Provider And Its Models
[⚙️ assert] The DeepSeek provider is named
✅ got: #t
[⚙️ assert] The provider speaks the OpenAI chat API
✅ got: #t
[⚙️ assert] deepseek-flash is configured with its defaults
✅ got: #t
[⚙️ assert] deepseek-v4-pro is configured with its defaults
✅ got: #t
ℹ️ info - ran 1 tasks in: 0 seconds, 92606 microseconds
ℹ️ info - counted 1 file, 1 suite, 4 tests and 10 assertions
running unit tests from file: rofi-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] Rofi Configuration and Theming
[🧪 test] Every Launcher Surface Reads Under Every Palette
[⚙️ assert] Every ink should clear its floor on every palette
✅ got: ()
[🧪 test] Rofi Theme (AList Structure)
[⚙️ assert] Theme should be a list (AList)
✅ got: #t
[⚙️ assert] Should contain a global wildcard '*' section
✅ got: #t
[⚙️ assert] Global background-color should be transparent
✅ got: transparent
[⚙️ assert] The global ink should be the palette's text colour, via text-color
✅ got: #ffffff
[⚙️ assert] The legacy foreground name should be gone
✅ got: #f
[⚙️ assert] The search panel should be softly rounded
✅ got: 18px
[⚙️ assert] The launcher should carry a one-pixel hairline
✅ got: 1px
[⚙️ assert] The hairline should be the secondary text colour at 15% opacity
✅ got: rgba(152, 152, 152, 0.15)
[🧪 test] Theme Picker Script
[⚙️ assert] The theme picker must be a Bash script
✅ got: #t
[⚙️ assert] Choosing a palette must re-render the palette-dependent configs
✅ got: #t
[⚙️ assert] Choosing a palette must persist itself as a local override
✅ got: #t
[🧪 test] A Launcher Click Replaces An Open Launcher
[⚙️ assert] Rofi's own -replace takes the seat in one step
✅ got: rofi -replace -show drun
[⚙️ assert] A script menu asks the open launcher to leave first
✅ got: #t
[⚙️ assert] The command always runs, launcher open or not
✅ got: #t
[🧪 test] Theme Picker Reports Its Progress
[⚙️ assert] The picker should write its stages in the order it does them
✅ got: #t
[⚙️ assert] A switch that fails should say so
✅ got: #t
[⚙️ assert] The stage should be written where the gallery page reads it
✅ got: #t
[⚙️ assert] The picker should keep the id of the notification it opened
✅ got: #t
[⚙️ assert] The picker should edit that notification rather than add another
✅ got: #t
[⚙️ assert] The id prefix fyi prints should be stripped before reuse
✅ got: #t
[⚙️ assert] A palette switch should carry the palette icon
✅ got: #t
[⚙️ assert] A failed switch should carry the error icon
✅ got: #t
[🧪 test] Theme Picker Caches Its Swatches
[⚙️ assert] The swatches should be cached outside the config
✅ got: #t
[⚙️ assert] A palette change should invalidate the cached swatches exactly once
✅ got: #t
[⚙️ assert] ImageMagick should draw the swatches
✅ got: #t
[🧪 test] Rofi Config String Template
[⚙️ assert] Configuration should inject the configured sans font
✅ got: #t
[⚙️ assert] Icons should be enabled by default
✅ got: #t
[⚙️ assert] Config must reference the generated theme file
✅ got: #t
[🧪 test] Power Menu Script
[⚙️ assert] The power menu must be a Bash script
✅ got: #t
[⚙️ assert] The first entry must use the rofi \0icon\x1f separator
✅ got: #t
[⚙️ assert] The power menu should expose a shutdown action
✅ got: #t
[🧪 test] The Config Names No Keys Rofi Ignores
[⚙️ assert] A key that reaches no widget should not be in the config
✅ got: (#f #f)
[🧪 test] Every Mode Is A Clickable Button
[⚙️ assert] The launcher mode should have a name
✅ got: #t
[⚙️ assert] So should the command-line mode
✅ got: #t
[⚙️ assert] So should the hosts mode
✅ got: #t
[⚙️ assert] So should the window switcher
✅ got: #t
[⚙️ assert] So should the session menu
✅ got: #t
[⚙️ assert] So should the palette picker
✅ got: #t
[⚙️ assert] The mode row should sit under the search field
✅ got: [ inputbar, mode-switcher, message, listview ]
[⚙️ assert] The mode row should have a rule of its own
✅ got: #t
[⚙️ assert] A mode button should say it can be clicked
✅ got: pointer
[⚙️ assert] The mode in use should be told apart from the others
✅ got: #t
[⚙️ assert] The mode pill radius should be a literal, not an oversized one
✅ got: 18px
[⚙️ assert] The pill should have no border for Rofi 2 to draw twice
✅ got: 0px
[⚙️ assert] An unselected pill should be a translucent fill
✅ got: rgba(40, 42, 43, 0.35)
[🧪 test] Theme Picker Offers Every Palette With A Swatch
[⚙️ assert] Every registered palette should get a swatch table row
✅ got: 44
[⚙️ assert] Every registered palette should be listed
✅ got: #t
[⚙️ assert] A swatch should be painted from the palette's own colours
✅ got: #t
[🧪 test] Theme Picker Wears The Right Emacs Theme
[⚙️ assert] A palette should carry the Emacs theme it wears, not a rename of its own name
✅ got: #t
[⚙️ assert] The running Emacs should be told about the theme instead of waiting for a restart
✅ got: #t
[🧪 test] The Inputbar Carries One Button
[⚙️ assert] The inputbar should carry the red close dot
✅ got: #t
[⚙️ assert] The yellow clear dot should be gone
✅ got: #f
[⚙️ assert] The green mode dot should be gone
✅ got: #f
[⚙️ assert] The clear dot's rule should be gone too
✅ got: #f
[⚙️ assert] The mode dot's rule should be gone too
✅ got: #f
[⚙️ assert] The close dot should still be a real button
✅ got: #t
[🧪 test] Theme Picker Knows Which Palette Is Running
[⚙️ assert] The picker should know which palette is currently active
✅ got: #t
[🧪 test] The Selected Row Keeps Its Ink
[⚙️ assert] The selection's text takes the ink that reads on the accent
✅ got: #1d2021
[⚙️ assert] So does the mode pill in use
✅ got: #1d2021
[⚙️ assert] Row text inherits the selection's ink rather than overriding it
✅ got: #f
[🧪 test] Rofi Script Modes Registered
[⚙️ assert] The launcher, command line, hosts, window switcher and power modes should be registered
✅ got: #t
[⚙️ assert] The theme picker mode should be registered
✅ got: #t
[⚙️ assert] The power mode should point at the generated script
✅ got: #t
[🧪 test] The List Has A Slim Scrollbar
[⚙️ assert] The scrollbar should be a hairline, not a cage
✅ got: 5px
[⚙️ assert] The list should show where it ends
✅ got: true
ℹ️ info - ran 1 tasks in: 1 seconds, -15700 microseconds
ℹ️ info - counted 1 file, 1 suite, 17 tests and 66 assertions
running unit tests from file: gtk-spec.scm, entrypoint: spec
ℹ️ info - shuffled with seed 223379907 (replay with VERITAS_SEED=223379907)
+----------------------------------------------+
[📑 suite] GTK Configuration Suite
[🧪 test] dconf Colour Scheme Follows The Palette
[⚙️ assert] Dark palettes should request the dark GTK scheme
✅ got: 'prefer-dark'
[⚙️ assert] Light palettes should request the light GTK scheme
✅ got: 'prefer-light'
[🧪 test] GTK 3 Settings
[⚙️ assert] The GTK 3 settings should be an association list
✅ got: #t
[⚙️ assert] GTK 3 windows should put the window controls on the left
✅ got: close,minimize,maximize:
[⚙️ assert] The sans font should be configured
✅ got: #t
[🧪 test] dconf Theme Names Come From The Palette
[⚙️ assert] The icon theme should be palette derived
✅ got: 'Tela-purple-light'
[⚙️ assert] An accent colour should always be exported
✅ got: #t
[🧪 test] GTK 4 Settings
[⚙️ assert] The GTK 4 settings should be an association list
✅ got: #t
[⚙️ assert] GTK 4 windows should put the window controls on the left
✅ got: close,minimize,maximize:
[🧪 test] dconf Button Layout
[⚙️ assert] The window manager should place the window controls on the left
✅ got: 'close,minimize,maximize:'
ℹ️ info - ran 1 tasks in: 0 seconds, 8269 microseconds
ℹ️ info - counted 1 file, 1 suite, 5 tests and 10 assertions
global totals: 26 files, 46 suites, 250 tests and 957 assertions
finished running tests
--------------------------------------------------------------
Maak 0.14.0: the infinitely extensible command runner
Loading tasks from Maak file: /etc/byggsteg/job-clone/heks-linux/trunk/maak.scm
Executing Maak tasks: ci
--------------------------------------------------------------
=> Running Maak task: ci
Ask the three questions a pipeline asks: formatted, compiling, passing.
`maak test' wraps the suite in `guix shell --container', which is what makes it
hermetic on a machine -- and what makes it impossible where the run is already
sandboxed. A Byggsteg job is itself a container, a second user namespace cannot
be created inside the first, and every pipeline run of this configuration failed
in `call-with-container' before the first test ran because of it.
So this task asks the same three questions with the container left to the
caller: `sift check' over the tree, a compile of every module, and the suite
without the wrapper (with a private HOME, so what the container was protecting
still holds). Coverage is not reported here: nothing in a pipeline reads it, and
`genhtml' failing on a machine that has no lcov is not a fact about the tests.
Executing: guix time-machine --channels=channels.scm -- shell -m manifest.scm -- sh -c 'work=$(mktemp -d)
cache=${XDG_CACHE_HOME:-$HOME/.cache}/guile/ccache
project=$(pwd -P)
project=${project#/}
fail=0
compile_group() {
dir=$1
shift
for file in "$@"; do
XDG_CACHE_HOME="$dir" guild compile -L ./src -W3 "$file" || return 1
done
}
compile_group "$work/1" ./src/heks-linux/bridges.scm ./src/heks-linux/btop.scm ./src/heks-linux/capture.scm ./src/heks-linux/containers.scm ./src/heks-linux/dconf.scm ./src/heks-linux/distrobox.scm ./src/heks-linux/eca.scm ./src/heks-linux/fastfetch.scm ./src/heks-linux/fontconfig.scm ./src/heks-linux/git.scm ./src/heks-linux/gtk.scm ./src/heks-linux/icons.scm ./src/heks-linux/image.scm ./src/heks-linux/lambdock.scm ./src/heks-linux/mako.scm ./src/heks-linux/niri.scm ./src/heks-linux/palette.scm ./src/heks-linux/prelude.scm ./src/heks-linux/rmpc.scm ./src/heks-linux/rofi.scm ./src/heks-linux/ssh.scm ./src/heks-linux/toon.scm ./src/heks-linux/user-settings.scm ./src/heks-linux/wallpaper.scm ./src/heks-linux/waybar.scm ./src/heks-linux/wezterm.scm ./src/heks-linux/zen.scm & pid1=$!
wait $pid1 || fail=1
for dir in "$work"/*/; do
for abi in "$dir"guile/ccache/*/; do
[ -d "$abi$project/src" ] || continue
name=${abi%/}
name=${name##*/}
mkdir -p "$cache/$name/$project/src"
cp -a "$abi$project/src/." "$cache/$name/$project/src/"
done
done
rm -rf "$work"
exit $fail'
Execute command:
guix time-machine --channels=channels.scm -- shell -m manifest.scm -- env HOME=/tmp XDG_CONFIG_HOME=/tmp guile -L ./src -L ./test -L . -c '((@ (veritas runner) run-tests))'
Executing: guix time-machine --channels=channels.scm -- shell -m manifest.scm -- env HOME=/tmp XDG_CONFIG_HOME=/tmp guile -L ./src -L ./test -L . -c '((@ (veritas runner) run-tests))'