just ui-test runs Quickshell inside niri inside headless Weston — never niri-session, never the parent compositor.
The agent-facing law lives in the nuguland System (.system/RULES.md); this file is the human overview.
What it provides
Weston headless backend with the Pixman renderer; 1280 × 720 virtual output by default, WIDTHxHEIGHT overrides it.
A disposable source overlay, private runtime directory, private session bus, and bwrap sandbox denying host HOME, system bus, network, and runtime sockets.
Synthetic service doubles, real pointer and keyboard through the child sockets, screenshots from the child compositor, and retained logs for every phase.
A 300-second overall deadline, 30-second command/readiness budgets, and child shutdown escalating from SIGTERM to SIGKILL after two seconds.
Never launch refactor.qml or niri-integration.qml directly: the runner's isolated service substitutions are mandatory.
Requirements
weston, niri, qs, wdotool, wtype, bwrap, dbus-run-session, Node, a C compiler, pkg-config, libsystemd headers, and busctl.
The niri suite additionally needs wayland-scanner, Wayland protocol headers, libweston-15 headers, xkbcommon, wl-paste, and ImageMagick identify.
Suites
just ui-test [fixture] [WIDTHxHEIGHT]; default all.
controls — shared PopupButton, PopupSlider, PopupTextField with real input.
popouts — clock/system panels with isolated service doubles plus production system-resource boundaries.
noko — capture, transcription, and idle states; geometry across bar orientations.
system — production Resources.qml boundaries only.
tasks — real Bar and popup flows with isolated doubles: clipboard, launcher, audio, media, tray, power, connectivity, brightness, noko, vault.
niri — native integration: real Niri subscription, Bar pills, overview, screenshots, hotplug, xdg-shell clients.
Each selection starts from checked-in synthetic state and runs that suite's assertions, not a recorded input stream.
Evidence
Everything lands in a fresh .tmp/ui-test-* directory:
failure.json — original error, phase, latest safe snapshot, capture errors.
replay.json — selected fixture, exact public rerun command, current phase.
failure.png — child-compositor screenshot when capture was possible.
diagnostics.jsonl, refactor.log — snapshot IDs and popup transitions.
commands.log, fixture and compositor logs, versions.txt, outputs.json.
Suite-specific records: assertions.jsonl, resource-dispatch.jsonl, resource-probe-checks.json, niri-*.json, niri-files.jsonl, and the *-*.png screenshots.
Screenshots contain only sandbox fixture data. Revealed nonempty authentication input refuses capture and records the refusal; a missing screenshot is explicit, never a pass.
Approved diagnostic exceptions
Exactly one expected niri::backend::winit DEBUG software-EGL record and one expected niri::niri WARN for the deliberate missing-directory screenshot write, both bound to niri.log and the measured action interval.
The full rule, including what fails it, lives in .system/RULES.md.
Tooling
Follow the official Quickshell language-server setup: create .qmlls.ini and let Quickshell generate it.
Use Qt6 executables, particularly /usr/lib/qt6/bin/qmllint on this host.
Do not patch static metadata to pretend it models runtime-only backend registration.
# Nested UI test harness
`just ui-test` runs Quickshell inside niri inside headless Weston — never `niri-session`, never the parent compositor.
The agent-facing law lives in the nuguland System (`.system/RULES.md`); this file is the human overview.
## What it provides
- Weston headless backend with the Pixman renderer; 1280 × 720 virtual output by default, `WIDTHxHEIGHT` overrides it.
- A disposable source overlay, private runtime directory, private session bus, and bwrap sandbox denying host HOME, system bus, network, and runtime sockets.
- Synthetic service doubles, real pointer and keyboard through the child sockets, screenshots from the child compositor, and retained logs for every phase.
- A 300-second overall deadline, 30-second command/readiness budgets, and child shutdown escalating from SIGTERM to SIGKILL after two seconds.
Never launch `refactor.qml` or `niri-integration.qml` directly: the runner's isolated service substitutions are mandatory.
## Requirements
`weston`, `niri`, `qs`, `wdotool`, `wtype`, `bwrap`, `dbus-run-session`, Node, a C compiler, `pkg-config`, libsystemd headers, and `busctl`.
The `niri` suite additionally needs `wayland-scanner`, Wayland protocol headers, libweston-15 headers, xkbcommon, `wl-paste`, and ImageMagick `identify`.
## Suites
`just ui-test [fixture] [WIDTHxHEIGHT]`; default `all`.
- `controls` — shared `PopupButton`, `PopupSlider`, `PopupTextField` with real input.
- `popouts` — clock/system panels with isolated service doubles plus production system-resource boundaries.
- `privilege` — prompt focus, typing, reveal, cancel, Escape, failure shake.
- `noko` — capture, transcription, and idle states; geometry across bar orientations.
- `system` — production `Resources.qml` boundaries only.
- `tasks` — real Bar and popup flows with isolated doubles: clipboard, launcher, audio, media, tray, power, connectivity, brightness, noko, vault.
- `niri` — native integration: real Niri subscription, Bar pills, overview, screenshots, hotplug, xdg-shell clients.
Each selection starts from checked-in synthetic state and runs that suite's assertions, not a recorded input stream.
## Evidence
Everything lands in a fresh `.tmp/ui-test-*` directory:
- `failure.json` — original error, phase, latest safe snapshot, capture errors.
- `replay.json` — selected fixture, exact public rerun command, current phase.
- `failure.png` — child-compositor screenshot when capture was possible.
- `diagnostics.jsonl`, `refactor.log` — snapshot IDs and popup transitions.
- `commands.log`, fixture and compositor logs, `versions.txt`, `outputs.json`.
- Suite-specific records: `assertions.jsonl`, `resource-dispatch.jsonl`, `resource-probe-checks.json`, `niri-*.json`, `niri-files.jsonl`, and the `*-*.png` screenshots.
Screenshots contain only sandbox fixture data. Revealed nonempty authentication input refuses capture and records the refusal; a missing screenshot is explicit, never a pass.
## Approved diagnostic exceptions
Exactly one expected `niri::backend::winit` DEBUG software-EGL record and one expected `niri::niri` WARN for the deliberate missing-directory screenshot write, both bound to `niri.log` and the measured action interval.
The full rule, including what fails it, lives in `.system/RULES.md`.
## Tooling
Follow the [official Quickshell language-server setup](https://quickshell.org/docs/v0.3.1/guide/install-setup/#language-server): create `.qmlls.ini` and let Quickshell generate it.
Use Qt6 executables, particularly `/usr/lib/qt6/bin/qmllint` on this host.
Do not patch static metadata to pretend it models runtime-only backend registration.