evidence · 7.1 KiB

background-video-audit.md

Committed at docs/evidence/omarchy-themes/background-video-audit.md. This is what grounds the requirements that cite it.

Open raw source

Video background audit: tasks 2.2 and 2.3

Base 33cd23aa, branch bg-video, 2026-10-17. Host evidence only. Nothing here was run on the board; task 3.3 is untouched and stays open.

Task 2.2 and 2.3 were written as if background_decode.rs had no video path. That is stale: commit 68badde1 shipped a decoder child process, a visibility signal, status telemetry and transaction-aware slot retention. background_decode.rs is still still-only and is still the right place for nothing in this task. Line numbers below are for this branch after the change.

Already existed (before this branch)

RequirementWhere
Bounded decode: local regular files only, mp4/m4v/mov, at most 128 MiB, no symlink or non-canonical pathnix/rust-shell-client/src/video_wallpaper.rs:21-72 (local_video)
Bounded decode: ffprobe must say h264 and at most 1920x1080, 800 ms probe timeout, 4 KiB outputvideo_wallpaper.rs:74-134 (probe)
Bounded decode: output frame bound, one decoder thread, 8 fps, scaled and cropped to the surface, first-frame timeout 1.3 svideo_wallpaper.rs:21-24,141-246
Mutedffmpeg run with -an -sn -dn and a single -map 0:v:0, video_wallpaper.rs:164-180; no audio path exists
Named failure categories instead of a crash (unsupported-format, source-unavailable, source-bound, source-path, unsupported-codec, probe-*, output-bound, decoder-*, first-frame-timeout)video_wallpaper.rs:50-246, delivered as VideoEvent::Error and failure()
Pause = stop decoder child, keep last frame; resume = new childmain.rs VideoPlayback::pause/resume (main.rs:454-490)
Visibility pause on a certified, fresh, correctly sized, opaque-coverage signal; missing or stale means visiblevideo_visibility.rs:20-51; polled every 500 ms at main.rs:7050; compositor producer nix/card-shell/adapter.c
Reduced motion: no decoder is started and a running one is pausedstartup flag main.rs:6814 via reduced_motion_enabled (main.rs:659); start/pause/resume gates at main.rs:2332,7070,7082,7098,7140
Still fallback on decode failure: the failing decoder is dropped, video_display = None, the wallpaper draws the paired stillmain.rs:7110-7125, wallpaper_path = fallback_still(..) at main.rs:2171,6674,7265,7627; the still is drawn with the generation’s fit mode (default crop)
Status record reports error + category, paused-covered, paused-reduced-motion, still, unsupported, playingmain.rs:7660-7685, video_status.rs
Rollback retention and slot selectionmain.rs:283 (resolve_video_slot), main.rs:2301, unit-tested

Missing (found) and what this branch did

GapResolution
No handheld-wallpaper flake outputAdded nix/handheld-wallpaper.nix and packages.<system>.handheld-wallpaper. See “Why not a separate decode crate” below.
No compatibility-report entry for a recognised-suffix-but-undecodable video. tools/theme_activate.py accepted .webm/.mkv/.avi/garbage.mp4 silently as a background, and the user only found out at play timetheme_activate.py video_diagnostic() / video_report_line(): a line in the report’s unavailable list, named with the decoder’s own category, for theme assets and user overlays. Never fatal.
Pause and reduced-motion decisions were five hand-copied boolean expressions in the binary, untestableOne predicate, video_visibility::should_decode(reduced_motion, covered), used at all five sites; unit-tested.
fallback_still lived in the binary, untestedMoved to appearance::fallback_still; test video_selection_falls_back_to_the_first_still_and_never_to_a_video.
Decoder failure categories and the stop/restart lifecycle had no test (only a fixture-gated happy path that silently returns when its env is unset)nix/rust-shell-client/tests/video_wallpaper_module.rs: five tests against stand-in ffmpeg/ffprobe scripts driving the real decode_loop.
tests/test_handheld_theme_backgrounds.py named by the parent task but never createdCreated, with --video.

Not closed, by design

Why not a separate decode crate

The task asked for “its own isolated flake output” for decode in background_decode.rs. The decode logic is video_wallpaper.rs, a module of the shell client crate that shares frame_bytes and the appearance types, and the only costly dependency is the minimal ffmpeg (nix/video-probe.nix). A second Rust crate would copy code, not isolate it. The closest honest equivalent is handheld-wallpaper: the ffmpeg/ffprobe pair the decoder child runs, plus an environment file naming K230_WALLPAPER_FFMPEG/FFPROBE. It is the same store path nix/shell.nix already uses, so its closure can be built and sized on its own. Building it shows the decoder closure cross-builds; it runs no decode.

Commands run

See the task notes in openspec/changes/the-background-chooser-supports-fill-solid-and-video/tasks.md.

Deployment (2026-10-17)