atagen

monolith

public
Star0
Watch0
9d1128e3c22797988dafcb931e07cd2a3ea9ad2f
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: design/test-checklist-2026-10-19.md

4c2d7c08e9f7atagen2026-10-19 10:01 UTC1
# Test checklist for the 2026-10-19 session
4c2d7c08e9f7atagen2026-10-19 10:01 UTC2
4c2d7c08e9f7atagen2026-10-19 10:01 UTC3
Everything below landed in one day from parallel agents and was only checked nested, mostly with throwaway clients and synthetic input. Nothing here has run on bare metal. The first part is what to try by hand. The second is what could be automated and how.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC4
4c2d7c08e9f7atagen2026-10-19 10:01 UTC5
Build and run from the repo root in nushell.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC6
4c2d7c08e9f7atagen2026-10-19 10:01 UTC7
```nu
4c2d7c08e9f7atagen2026-10-19 10:01 UTC8
nix develop -c cargo build --release -p monolith
4c2d7c08e9f7atagen2026-10-19 10:01 UTC9
nix develop -c sh -c 'RUST_LOG=monolith=debug target/release/monolith run --backend drm 2> monolith.log'
4c2d7c08e9f7atagen2026-10-19 10:01 UTC10
```
4c2d7c08e9f7atagen2026-10-19 10:01 UTC11
4c2d7c08e9f7atagen2026-10-19 10:01 UTC12
## By hand on bare metal
4c2d7c08e9f7atagen2026-10-19 10:01 UTC13
4c2d7c08e9f7atagen2026-10-19 10:01 UTC14
### Memory and startup
4c2d7c08e9f7atagen2026-10-19 10:01 UTC15
- [ ] Idle RSS with your usual windows, compared with the 180 to 200 MB before the EGL fix and the heap trim.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC16
- [ ] `grep -E 'LLVM|gallium|EGL_mesa' /proc/(pgrep -x monolith)/maps` via sudo finds nothing.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC17
- [ ] Open and close beer 20 times. RSS should not climb.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC18
- [ ] `monolith msg quit` exits cleanly with no coredump (`coredumpctl list | grep monolith`).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC19
- [ ] A config with a TOML typo still loads everything else, and the log names the dropped line.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC20
4c2d7c08e9f7atagen2026-10-19 10:01 UTC21
### Outputs, pacing and power
4c2d7c08e9f7atagen2026-10-19 10:01 UTC22
- [ ] **VRR and the cursor cap.** In a fullscreen VRR game, moving the mouse hard should leave the game's frame rate alone. An idle VRR desktop should stay at 60 Hz or below.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC23
- [ ] **Unplug and replug.** Do this with the bar running. The bar gets closed on unplug. There is no phantom output in its screen list, and exactly one output after replug. Try it again with a replug inside 5 s.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC24
- [ ] **VT switch.** Stay away for 30 s and CPU should be idle. Coming back should redraw with no `frame missed its vblank`. A monitor plugged in while you were away should light on return.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC25
- [ ] **Lost flip.** If `page flip never landed` ever appears, the output should recover by itself.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC26
- [ ] **Idle blank.** With `[idle] blank_after = 30`, the panels go dark and wake on input. A fullscreen video holding an idle inhibitor stops the blank. Check the VRR panel after it wakes.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC27
- [ ] **Power commands.** `monolith msg power off DP-1` and `power on` work. A swayidle or wlopm timeout and resume works too. An explicit off stays off through input.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC28
- [ ] **Lid, if the machine has one.**
4c2d7c08e9f7atagen2026-10-19 10:01 UTC29
  - `systemd-inhibit --list` shows monolith holding `handle-lid-switch`.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC30
  - `close = "ignore"` stays awake.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC31
  - `"suspend"` suspends once.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC32
  - Docked, closing the lid darkens only the panel.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC33
- [ ] **Presentation.** `mpv -v --video-sync=display-resample` reports presentation feedback. `weston-presentation-shm` shows HW_CLOCK and VSYNC flags. Check both with VRR on and off.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC34
- [ ] **FIFO.** `vkcube --present_mode 2` runs at the panel rate without stalls. Hiding its tag throttles it, and showing the tag again restores it.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC35
- [ ] **Commit timing.** A Proton game paces smoothly.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC36
- [ ] **Signals.** Logging out or sending `kill -TERM` removes the socket and the X11 lock.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC37
4c2d7c08e9f7atagen2026-10-19 10:01 UTC38
### Scale
4c2d7c08e9f7atagen2026-10-19 10:01 UTC39
- [ ] **Fractional scale on DP-2.** With `scale = 1.5` on DP-2, text is crisp in foot, GTK and Qt (quickshell). Borders and gaps are crisp. X11 apps are upscaled at the right size.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC40
- [ ] **Rotated DP-1 at scale above 1.** Windows, layers, the lock screen and the pointer mapping are all right.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC41
- [ ] **Cursor.** The cursor size follows the scale, its tip sits under the hotspot, and it moves between outputs at different scales cleanly.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC42
- [ ] **Direct scanout.** A fullscreen game at a fractional scale still logs `direct scanout scanout=true`.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC43
- [ ] **Screenshots.** `grim` of an output and of a window at scale 1.5 come out at the right pixel size.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC44
4c2d7c08e9f7atagen2026-10-19 10:01 UTC45
### Windows and layout
4c2d7c08e9f7atagen2026-10-19 10:01 UTC46
- [ ] **Inkscape.** The splash and start screen float at their own size.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC47
- [ ] **Float toggle.** Toggling a tiled window to float sizes it to what it wants and glides once, with no snap.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC48
- [ ] **Hide to tray.** Telegram, Discord and Steam leave no blank tile, and come back through the normal map.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC49
- [ ] **Starting fullscreen.** `mpv --fs`, an SDL game and a Wine game all start fullscreen, on the output they asked for.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC50
- [ ] **Dialogs over fullscreen.** A save dialog from a fullscreen app is shown and focused above it. A new unrelated window doesn't steal focus.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC51
- [ ] **Launch context.** Inkscape run from beer on tag 2 of DP-1 lands on beer's tag and output even while you're viewing elsewhere.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC52
- [ ] **Autotile.** New windows split the focused one along its longer side. `autotile = false` restores the old behaviour after a reload.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC53
- [ ] **Spawn edge.** On an empty output, the first window grows in from the right on landscape and from the bottom on rotated DP-1.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC54
- [ ] **Scratchpads.** They are always centred on the output they're summoned on, including after a resize or a mode change.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC55
- [ ] **Urgency.** An unfocused window that asks for attention (foot's bell, or a chat app) gets the amber border and `urgent` in `monolith get state`.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC56
- [ ] **Window rules.** Try each of size, position, center, min and max size, fullscreen, `focus = false`, opacity (including while the window closes), `idle_inhibit`, `vrr`, and the X11 class and instance matchers.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC57
- [ ] **Locked binds.** A `[locked]` volume bind works on the lock screen, and ordinary binds don't.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC58
- [ ] **Modal dialogs.** Clicking the parent of a GTK4 modal focuses the modal (once the modal work lands).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC59
4c2d7c08e9f7atagen2026-10-19 10:01 UTC60
### Input, popups and selections
4c2d7c08e9f7atagen2026-10-19 10:01 UTC61
- [ ] **Popups.** GTK, Qt and Firefox menus close when you click outside them. Near a screen edge they flip or slide to stay on screen. A menu from a left tile is drawn above the right tile and is clickable there. Quickshell tray menus close too.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC62
- [ ] **Click accuracy.** In a GTK app with shadows, such as mousepad, clicks land exactly where things are drawn.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC63
- [ ] **Drag and drop.** Drag a browser tab or a file from a file manager into another app.
f4b5438d978aatagen2026-10-19 10:43 UTC64
- [ ] **Window screencast.** With `chooser_type=dmenu` in `~/.config/xdg-desktop-portal-wlr/config`, sharing a single window from a browser lists window titles and streams only that window.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC65
- [ ] **Clipboard bridge.** Copy and paste between X11 apps (Steam, Wine) and Wayland apps work in both directions, for the clipboard and the primary selection. Something copied before Xwayland starts reaches X11 apps. With `selection_access = "any"`, a headless `xclip -o` can read.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC66
- [ ] **Client move and resize.** On a floating GTK window, dragging the headerbar moves it. X11 windows do the same.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC67
- [ ] **Border grab.** Hovering a border or gap shows the resize cursor. Dragging resizes, a gap between tiles moves the split, and floats stay on the output.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC68
- [ ] **Meta+RMB.** It resizes from the nearest edge or corner, on tiles and floats.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC69
- [ ] **Resize hold.** During a resize drag the window stretches, and the client gets one configure on release. Check with `WAYLAND_DEBUG=1` on foot.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC70
- [ ] **Pointer lock and confine.** Mouse look works in a Proton or SDL game. A browser pointer-lock demo works and the cursor comes back where expected. A confined pointer stays inside the window.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC71
- [ ] **Shortcuts inhibit.** A VM viewer or remote desktop client gets Super combos. `reload` still works, and so does VT switching.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC72
4c2d7c08e9f7atagen2026-10-19 10:01 UTC73
## Automating these
4c2d7c08e9f7atagen2026-10-19 10:01 UTC74
4c2d7c08e9f7atagen2026-10-19 10:01 UTC75
The fastest wins come from tests that run in `cargo test` with no compositor. The rest need a headless way to run monolith with scripted clients.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC76
4c2d7c08e9f7atagen2026-10-19 10:01 UTC77
### Pure unit tests, cheap
4c2d7c08e9f7atagen2026-10-19 10:01 UTC78
- **Layout** (`crates/layout/src/tests.rs`). Each of these is already partly covered and needs a few more cases.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC79
  - Modal focus redirect and chained modals.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC80
  - `focus_if_covering`, and `focus_dir` never reaching a covered window.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC81
  - Scratchpad centring after `set_output_area` and `send_to_output`.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC82
  - `move_split` at minimum shares.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC83
  - Autotile with mixed visible and hidden siblings, run over the random-commands proptest.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC84
  - Float clamp with outputs smaller than the window.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC85
- **Config** (`crates/config`).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC86
  - Lenient parse of an unclosed multi-line array, a broken `[table` header, a duplicate table, and more than 32 bad lines.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC87
  - Rule matcher precedence.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC88
  - Scale snapping to 1/120.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC89
  - `[locked]` filtering.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC90
- **Pure helpers in monolith.**
4c2d7c08e9f7atagen2026-10-19 10:01 UTC91
  - `timing.rs` release-time computation: VRR, no timeline, a timestamp within 1/8 refresh of a vblank.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC92
  - `fifo.rs` hold sweep.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC93
  - `resized` edge clamping with rule limits.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC94
  - The Latin-1 transcoder (has tests).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC95
  - `Edges` grid selection.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC96
  - `wm::configure` choosing the logical size whose rounding matches the physical size at 1.25, 1.5 and 1.75.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC97
  - Each of these is a pure function, or can be made one by passing time and geometry in.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC98
- **render-vk goldens** (`crates/render-vk/tests/golden.rs`).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC99
  - Blend-off for X formats against alpha formats.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC100
  - The opacity rule through the effect path.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC101
  - Single-pixel solid at alpha 0.5.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC102
  - Y-inverted dmabuf (has a test).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC103
  - Pipeline cache rejecting a foreign header (has a test).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC104
  - A batched upload followed by a draw in the same submit (has a test).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC105
  - Device-lost flag transitions (has a unit test).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC106
4c2d7c08e9f7atagen2026-10-19 10:01 UTC107
### Integration tests needing a headless backend
4c2d7c08e9f7atagen2026-10-19 10:01 UTC108
- **The harness.** Add `--backend headless` to monolith. It would render to an offscreen dmabuf or `Offscreen` image, run its own vblank timer, and expose a test-only virtual input path. That could be wlr-virtual-pointer and virtual-keyboard, which we'd want for wtype anyway, or an IPC `inject` command compiled behind a feature. Put the harness in `crates/testkit` (currently empty), with a client library that spawns monolith, waits for its socket, runs a scripted Wayland client from wayland-client and reads `get state` and screenshots through image-copy-capture.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC109
- **Scenarios** it would make cheap. Each is a throwaway client an agent already wrote today, which could be kept instead of deleted.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC110
  - Popups. A grab plus an outside click gives `popup_done`, an unconstrained position near the edge, and the stacking order over a neighbouring tile.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC111
  - The Space origin. A click on a CSD window with a geometry offset arrives at the right surface coordinates.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC112
  - DnD. Enter, motion and drop between two clients.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC113
  - Clipboard bridge with Xwayland. Needs Xwayland in the test environment, and xclip or xsel.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC114
  - Client move and resize requests, border-grab hover and drag, Meta+RMB, and the resize hold (count configures during a drag).
4c2d7c08e9f7atagen2026-10-19 10:01 UTC115
  - Pointer lock, confine and relative motion, and shortcuts inhibit, with the virtual pointer and keyboard.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC116
  - xdg-foreign and xdg-dialog parenting gives a floating window.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC117
  - Null-buffer unmap and remap, fullscreen before map, and the Inkscape-style late min and max hints.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC118
  - Window rules end to end, including re-evaluation on a title change before first draw.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC119
  - Single-pixel buffer colour and size, from a screenshot pixel count.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC120
  - fifo barrier release and commit-timing landing frame, against the headless vblank timer.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC121
  - Presentation feedback timestamps against that timer.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC122
  - Fractional scale. Screenshot sizes, crisp borders, preferred scale events, and resending them after a reload.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC123
  - Hotplug. Add and remove a headless output, check the `wl_output` global's lifetime, the closed layers and lock surfaces, and how windows are rescued.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC124
  - Idle blank and the power protocol, through the headless power state.
4c2d7c08e9f7atagen2026-10-19 10:01 UTC125
- **What stays manual.** Real DRM and VRR, the NVIDIA driver paths (submit stall, scanout, cursor plane), logind and the lid, and real games and portals.