# 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.