diff --git a/.gitignore b/.gitignore index cb59aa6..953a845 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,18 @@ references/ -phase*_evidence/ + +# Inside phase*_evidence/ track narrative .md notes; ignore raw captures. +phase*_evidence/**/*.txt +phase*_evidence/**/*.log +phase*_evidence/**/*.pcap +phase*_evidence/**/*.strace +phase*_evidence/**/*.bin +phase*_evidence/**/*.gz +phase*_evidence/**/*.zst +phase*_evidence/**/*.dat +phase*_evidence/**/*.trace +phase*_evidence/**/*.json +phase*_evidence/**/*.ftrace + *.log *.pcap *.strace diff --git a/phase0_evidence/2026-05-07/iter8_build_smoke.md b/phase0_evidence/2026-05-07/iter8_build_smoke.md new file mode 100644 index 0000000..5c23174 --- /dev/null +++ b/phase0_evidence/2026-05-07/iter8_build_smoke.md @@ -0,0 +1,198 @@ +# iter8 fork build + vainfo smoke — fresnel 2026-05-07 + +Companion evidence for Phase 0 deliverable #3. + +## TL;DR + +The libva-v4l2-request-fourier fork **loads and initializes cleanly on RK3399** (Pinebook Pro / fresnel) at master tip `65969da` (iter8 Phase 4). Both V4L2 decode bindings advertise profiles via `vainfo`: + +- **rkvdec** (`/dev/video3` + `/dev/media1`): H.264 (5 profiles incl. MVC/Stereo), HEVCMain. +- **hantro-vpu-dec** (`/dev/video5` + `/dev/media2`): MPEG-2 Simple, MPEG-2 Main. + +This is the first proof that ohm-hardened iter1..iter5 + iter6..iter8 incremental work doesn't trip a cross-SoC initialization bug on RK3399. Substrate confirmed. + +## Substrate decision: master, not pinned-iter5 + +[`README.md`](../../README.md) and [`phase0_findings.md`](../../phase0_findings.md) describe the substrate as "iter5-end fork." That framing was correct on 2026-05-05 when libva-multiplanar reached the iter5 close. Between then and the fresnel-fourier scaffold (2026-05-07) the libva-multiplanar campaign continued through iter6 / iter7 / iter8 (see `~/src/libva-multiplanar/phase0_findings_iter{6,7,8}.md`). Building from master picks up the iter6–iter8 hardening: + +| Tip commit | Subject | Author | +|---|---|---| +| 65969da | iter8 Phase 4: tests/run_perf_binding_cell.sh — perf binding cell harness | claude-noether | +| dcaa1f1 | docs: clarify Rockchip silicon — PineTab2 is RK3566, not RK3568 | claude-noether | +| 7bd0818 | iter7 Phase 7 finalization: OUTPUT-pool teardown + test refinements | claude-noether | +| 988b848 | iter7: A+B+C — slot-leak fix, cap_pool harness, msync verify harness | claude-noether | +| a09c03c | iter6 fix: per-OUTPUT-slot request_fd binding via REINIT | claude-noether | +| c8b6ede | iter5 sweep follow-up: remove additional DEBUG sites flagged by Phase 5 review | Markus Fritsche | +| b993355 | iter5 Track E: move LAST_OUTPUT_WIDTH/HEIGHT from process-global to per-driver-data | Markus Fritsche | +| 843febc | iter5 sweep: remove iter1 slice_header parse + VAPicture dump + Sync RETURN trace | Markus Fritsche | + +A correction commit on this campaign should land updating `README.md` and `phase0_findings.md` to read "iter8-end fork" or simply "current master." + +## Build environment (verified) + +- Host: fresnel, kernel `6.19.9-99-eos-arm`. +- Toolchain: gcc 15.2.1, ld.bfd 2.46, ninja 1.13.2, meson 1.11.1, pkgconf 2.5.1. +- Dependencies: libva 1.23.0, libdrm 2.4.131, ccache available (used). +- All 8 kernel UAPI symbols required by the fork are present in `/usr/include/linux/`: `MEDIA_IOC_REQUEST_ALLOC`, `V4L2_CTRL_WHICH_REQUEST_VAL`, `V4L2_PIX_FMT_MPEG2_SLICE`, `V4L2_PIX_FMT_SUNXI_TILED_NV12`, `V4L2_PIX_FMT_HEVC_SLICE`, `V4L2_PIX_FMT_VP9_FRAME`, `V4L2_PIX_FMT_VP8_FRAME`, `V4L2_PIX_FMT_H264_SLICE`. + +## Compiled-in codecs + +From `src/meson.build`: + +``` +sources = [ + ... + 'mpeg2.c', + 'h264.c', + 'h264_slice_header.c', + 'request_pool.c', + 'cap_pool.c', +# 'h265.c' +] +``` + +In the build: + +- ✅ MPEG-2 (mpeg2.c) +- ✅ H.264 (h264.c + h264_slice_header.c) +- ❌ HEVC (h265.c **commented out** in src/meson.build) +- ❌ VP8 (no source file) +- ❌ VP9 (no source file) + +## Build + install + +Configuration: `meson setup --prefix=/usr build`. Default release mode; no debug toggles set. + +Build: `ninja -C build`. 20 compile/link targets, two harmless warnings from `request_pool.c` about `struct v4l2_ext_control` forward-declaration scope in `v4l2.h` (incomplete-type-in-prototype). Final artefact: + +- `build/src/v4l2_request_drv_video.so` — 302152 bytes, ELF aarch64, BuildID `89addcc37a8e6ed2240b0e7ef78789a2e09a2245`, debug_info present (not stripped). +- Single exported symbol matching libva's expected entry: `__vaDriverInit_1_23`. + +Install: `sudo ninja -C build install`. Lands at `/usr/lib/dri/v4l2_request_drv_video.so`, mode 0755 root:root. + +Size delta vs. ohm baseline: 302 KB on fresnel vs. ~265 KB documented for ohm at iter5-end (per `~/src/libva-multiplanar/phase0_findings.md`). The +37 KB is consistent with iter6–iter8 additions (per-OUTPUT-slot REINIT, slot-leak fix, cap_pool harness, OUTPUT-pool teardown, msync verify) plus possibly different gcc minor; not investigated further. + +## vainfo runs + +### Pass 1 — rkvdec binding + +``` +LIBVA_DRIVER_NAME=v4l2_request \ +LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video3 \ +LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media1 \ +LIBVA_TRACE=/tmp/vainfo_rkvdec.trace \ +vainfo --display drm --device /dev/dri/renderD128 +``` + +Output: + +``` +vainfo: VA-API version: 1.23 (libva 2.22.0) +vainfo: Driver version: v4l2-request +vainfo: Supported profile and entrypoints + VAProfileH264Main : VAEntrypointVLD + VAProfileH264High : VAEntrypointVLD + VAProfileH264ConstrainedBaseline: VAEntrypointVLD + VAProfileH264MultiviewHigh : VAEntrypointVLD + VAProfileH264StereoHigh : VAEntrypointVLD + VAProfileHEVCMain : VAEntrypointVLD +``` + +LIBVA_TRACE log shows `vaInitialize SUCCESS`, `vaQueryConfigProfiles SUCCESS`, six `vaQueryConfigEntrypoints SUCCESS` — all clean. + +### Pass 2 — hantro-vpu-dec binding + +``` +LIBVA_DRIVER_NAME=v4l2_request \ +LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video5 \ +LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media2 \ +vainfo --display drm --device /dev/dri/renderD128 +``` + +Output: + +``` +vainfo: Supported profile and entrypoints + VAProfileMPEG2Simple : VAEntrypointVLD + VAProfileMPEG2Main : VAEntrypointVLD +``` + +### Pass 3 — no env vars (sanity) + +``` +LIBVA_DRIVER_NAME=v4l2_request vainfo +``` + +Driver loads, but enumerates **zero** profiles. As expected — `request.c:149` reads `LIBVA_V4L2_REQUEST_VIDEO_PATH` to choose the V4L2 device; without it, no probe target exists and nothing gets advertised. Graceful no-op rather than crash. + +## Findings worth flagging for Phase 1+ + +### F1. HEVC profile enumerated despite `h265.c` not compiled + +`src/config.c:146` probes the V4L2 device for `V4L2_PIX_FMT_HEVC_SLICE` capability: + +```c +profiles[index++] = VAProfileHEVCMain; // line 151, gated by V4L2 probe +``` + +On rkvdec the probe succeeds (because `/dev/video3` `--list-formats-out` advertises `S265`), so `vaQueryConfigProfiles` returns HEVCMain. But `src/h265.c` is excluded from the meson build. The control-submission path (probably a `picture.c` switch over `surface->profile`) must therefore either have HEVC paths also commented out, or carry an unreachable guard, since the link succeeded with no h265 symbols defined. **A consumer that calls `vaCreateConfig(VAProfileHEVCMain)` will get a config back** (config.c:171 includes HEVCMain in the validation list) **and can attach buffers, but the actual control submission will likely fail or fault** at the dispatch step. This is a wedge between the enumerator's optimism and the build's honesty. Phase 2 source-read should map exactly which call returns what for HEVC today; Phase 4 should decide whether to: + +- (a) re-enable `h265.c` in the meson build (substrate revival — the iter5 sweep stripped it for build-cleanly reasons; on rkvdec the kernel surface is mainline and may "just work"), +- (b) gate enumeration on a compile-time `#ifdef` so `h265.c` exclusion implies HEVCMain isn't advertised, +- (c) leave both stripped permanently if HEVC can't be made to work on RK3399 cheaply. + +### F2. MultiviewHigh + StereoHigh enumerated unconditionally on H.264-capable nodes + +`config.c:140-141` adds these two profiles without any V4L2-side capability check: + +```c +profiles[index++] = VAProfileH264MultiviewHigh; +profiles[index++] = VAProfileH264StereoHigh; +``` + +RK3399 rkvdec hardware does not support MVC. A consumer asking for these profiles will succeed at config creation but fail at decode. For binding-cell scoping, fresnel-fourier's H.264 cell should explicitly use `VAProfileH264Main` or `VAProfileH264High` and never the MVC/Stereo variants. (mpv and Firefox don't ask for them anyway; chromium-fourier shouldn't either. Low risk.) + +### F3. Per-codec routing is one-env-var-per-process + +`request.c:149`/`171` reads `LIBVA_V4L2_REQUEST_VIDEO_PATH` and `_MEDIA_PATH` once at init and binds to that single V4L2 device. That means **a single libva backend instance can talk to either rkvdec or hantro-vpu-dec, but not both.** For an mpv invocation that wants H.264 (rkvdec) and a separate one that wants MPEG-2 (hantro), the env vars differ. + +This was one of the open Phase 0 questions ("rkvdec node device path env var — backend likely uses LIBVA_V4L2_REQUEST_VIDEO_PATH for one node. Two nodes may need a richer config: explicit per-codec routing or a probe loop. Phase 4 design decision."). The smoke-test confirms the answer: **one env var, one device, no in-backend probe.** Phase 4 work for fresnel-fourier — if a single Plasma session needs to decode both H.264 and MPEG-2 — will need either: + +- (a) per-process env override (e.g., a wrapper script for mpv that picks the device based on file extension or codec hint), or +- (b) a backend code change to discover both decode nodes and route by VAProfile at config time. + +Option (b) is the more general fix and matches the codec-coverage scope this campaign locked. Option (a) is the pragmatic hack until then. + +### F4. The `Trying display: drm` path works without a Plasma session being involved + +Pass 1/2 used `--display drm --device /dev/dri/renderD128`. That's the headless render-node path. It succeeded without Wayland or X11 in the consumer process, which means **vainfo as a smoke test does not require the SDDM watchpoint to be green**. Useful for future scripted smoke runs (CI-style) — they can run from an SSH session with no DISPLAY/WAYLAND_DISPLAY. + +The `pacman -Qq linux-api-headers` query returned the package name without a version (likely a pacman query format quirk), but the symbol-presence sweep confirms the headers are functionally complete. + +## Where this leaves Phase 0 + +| Deliverable | Status | +|---|---| +| #1 SDDM recovery | done as watchpoint (`phase0_recovery_2026-05-07.md`) | +| #2 V4L2 inventory | done (`v4l2_inventory.txt` + `v4l2_inventory_findings.md`) | +| **#3 fork build + vainfo smoke** | **done (this file) — substrate confirmed** | +| #4 H.264 baseline trace | next; needs an H.264 fixture (#5 first) | +| #5 per-codec test fixtures | next | +| #6 chromium-fourier cross-validator trace | needs #5 | +| Phase 0 close — commit + push as claude-noether | last; depends on #4 + #6 | + +## Re-run incantation (for future sessions) + +```bash +ssh fresnel ' +cd ~/src/libva-v4l2-request-fourier +git pull --ff-only +ninja -C build +sudo ninja -C build install + +LIBVA_DRIVER_NAME=v4l2_request \ +LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video3 \ +LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media1 \ +vainfo --display drm --device /dev/dri/renderD128 +' +``` diff --git a/phase0_evidence/2026-05-07/v4l2_inventory_findings.md b/phase0_evidence/2026-05-07/v4l2_inventory_findings.md new file mode 100644 index 0000000..728c649 --- /dev/null +++ b/phase0_evidence/2026-05-07/v4l2_inventory_findings.md @@ -0,0 +1,96 @@ +# V4L2 inventory findings — fresnel 2026-05-07 + +Companion to [`v4l2_inventory.txt`](v4l2_inventory.txt) (raw `v4l2-ctl` / `media-ctl` / sysfs output captured 2026-05-07T22:34 CEST). + +## Verified facts + +### Two decode blocks, six v4l2 nodes total + +| Node | Driver | DT compatible | Function | +|---|---|---|---| +| `/dev/video0` | `rockchip-rga` | `rockchip,rk3399-rga` | RGA scaler/converter (out of scope) | +| `/dev/video1` | `uvcvideo` | — | USB camera capture | +| `/dev/video2` | `uvcvideo` | — | USB camera metadata | +| `/dev/video3` | `rkvdec` | `rockchip,rk3399-vdec` | Stateless decoder (3 codecs) | +| `/dev/video4` | `hantro-vpu` | `rockchip,rk3399-vpu` | Encoder (JPEG only) | +| `/dev/video5` | `hantro-vpu` | `rockchip,rk3399-vpu` | Stateless decoder (2 codecs) | + +`/dev/video4` and `/dev/video5` share the parent platform device `ff650000.video-codec` — same hantro IP, two function instances (enc + dec). + +### Decoder codec surface (authoritative — from `--list-formats-out`) + +**`/dev/video3` (rkvdec)** — three codecs: + +``` +[0]: 'S265' (HEVC Parsed Slice Data, compressed) +[1]: 'S264' (H.264 Parsed Slice Data, compressed) +[2]: 'VP9F' (VP9 Frame, compressed) +``` + +CAPTURE: NV12 only. + +**`/dev/video5` (hantro-vpu-dec)** — two codecs: + +``` +[0]: 'MG2S' (MPEG-2 Parsed Slice Data, compressed) +[1]: 'VP8F' (VP8 Frame, compressed) +``` + +CAPTURE: NV12 only. + +### Profile/level menus (from `--list-ctrls-menus`) + +rkvdec exposes: + +- **H.264 profiles**: Constrained Baseline, Main, **High**, High 10, High 422, High 10 Intra, High 422 Intra. Levels 1 through 5.1 (16 entries). Note: 10-bit/422 entries listed are kernel-driver enumeration, not necessarily silicon-supported — the rkvdec driver may reject these at request submission. +- **HEVC profiles**: Main, Main Still Picture, **Main 10**. Levels 1 through 5.1 (9 entries). +- **VP9 profile**: 0 only (8-bit 4:2:0). No profile-2 (10-bit), profile-1 (4:4:4), or profile-3 listed. + +hantro-vpu-dec exposes **no** profile/level menus — MPEG-2 and VP8 don't need them. + +### Stateless control payloads + +rkvdec accepts: + +- H.264: `H264_DECODE_MODE` (Frame-Based), `H264_START_CODE` (Annex B), SPS, PPS, scaling matrix, decode params. +- HEVC: `HEVC_DECODE_MODE` (Frame-Based), `HEVC_START_CODE` (Annex B), SPS, PPS, slice params (dynamic-array, max 600 elems), scaling matrix, decode params. +- VP9: `VP9_FRAME` (frame decode params), `VP9_PROBABILITIES_UPDATES` (control type 260). + +hantro-vpu-dec accepts: + +- VP8: `VP8_FRAME` (frame decode params). +- MPEG-2: `MPEG_2_SEQUENCE_HEADER`, `MPEG_2_PICTURE_HEADER`, `MPEG_2_QUANTISATION_MATRICES`. + +Both drivers report `value=unsupported payload type` from `v4l2-ctl` for compound controls — normal; v4l2-ctl can't serialize them, the kernel ABI uses `VIDIOC_S_EXT_CTRLS` with `V4L2_CTRL_WHICH_REQUEST_VAL`. + +### Media controller topology + +- `/dev/media0` → uvcvideo (USB cam), entities 1/4/8/11/14. +- `/dev/media1` → rkvdec, simple source→proc→sink (3 entities). +- `/dev/media2` → hantro-vpu, holds **both** enc and dec sub-pipelines under one media device. Decode sub-pipeline: entities 15/17/20 (`rockchip,rk3399-vpu-dec-source` → `-proc` → `-sink`). Encode sub-pipeline: entities 1/3/6. + +For per-codec `media_path` resolution the libva backend can use either fixed device-node paths (simple) or media-controller graph traversal (matches Bootlin sunxi-cedrus pattern). Phase 4 design decision. + +## Corrections required in locked Phase 0 docs + +`phase0_findings.md` lines 26–28 and `README.md:24–28` claim hantro-vpu-dec on RK3399 supports H.264 (`V4L2_PIX_FMT_H264_SLICE`). **This is wrong on the running kernel `6.19.9-99-eos-arm`.** The actual surface is MPEG-2 + VP8 only. + +Implications: + +1. **Open Question #2 from `phase0_findings.md` is null** — there's no two-block H.264 routing decision to make. H.264 only goes to rkvdec on RK3399. The libva backend's device-selection logic for H.264 has exactly one valid bind target. +2. The "test cells per codec" sentence ("Two test cells per codec: rkvdec-bound H.264 and hantro-vpu-dec-bound H.264.") should be reduced to one cell. +3. Codec scope as locked stays correct in **count** — five codecs, just routed differently: + - rkvdec: H.264, HEVC, VP9 + - hantro-vpu-dec: MPEG-2, VP8 + +These corrections should land as a follow-up commit on this campaign repo. Not done in this file to keep evidence and source-of-truth separable. + +## Why the doc was wrong + +Likely carryover from RK3568 (ohm) hantro, which does support H.264 (DT compatible `rockchip,rk3568-vpu`). The RK3399 hantro IP / kernel variant in `drivers/media/platform/verisilicon/` registers a different codec list. The phase0_findings.md table was written without empirical enumeration on this kernel. + +## Gaps left for Phase 1+ + +- Resolution range per codec — not enumerated by `v4l2-ctl --list-formats-out` directly. Will need `v4l2-ctl --try-fmt-out-mplane` probes against rkvdec to find min/max width/height per codec, especially HEVC (4K+ would matter for VP9 but the panel is 1080p so probably moot). +- Per-codec slice-mode vs. frame-mode capability — both decoders advertise frame-based only (`*_DECODE_MODE menu min=1 max=1 default=1 (Frame-Based)`). This matches the libva-v4l2-request-fourier fork's slice-buffer accumulation pattern from libva-multiplanar iter4. +- Bit-depth limits — `H264_HIGH_10` profile is enumerated on rkvdec but RK3399 silicon doesn't do 10-bit H.264. Test will reveal whether the driver rejects 10-bit submission or just silently produces garbage. diff --git a/phase0_recovery_2026-05-07.md b/phase0_recovery_2026-05-07.md new file mode 100644 index 0000000..336a6bf --- /dev/null +++ b/phase0_recovery_2026-05-07.md @@ -0,0 +1,59 @@ +# Phase 0 task 1 close — SDDM recovery watchpoint (2026-05-07) + +## Verdict + +**Closed as watchpoint, not as root-caused fix.** SDDM is currently green on fresnel; no recovery action was needed for this boot. Plan procedures in [`~/.claude/plans/dynamic-forging-piglet.md`](../../.claude/plans/dynamic-forging-piglet.md) stayed unused. Re-open the task on the first organic regression. + +## Evidence (captured 2026-05-07 ~22:25 CEST over SSH from this session) + +System state: + +- `uname -r` = `6.19.9-99-eos-arm` (custom OC kernel, matches `phase0_findings.md`). +- `uptime` = 1:54 → boot at ~20:31 CEST. +- `loginctl list-sessions` shows session 2 (uid 1000 mfritsche) on tty1 active since 20:32, plus a manager session and a remote pts session. +- `pgrep -af "plasma|kwin"` confirms running Plasma Wayland: `/usr/bin/startplasma-wayland` (pid 2256), `/usr/bin/kwin_wayland_wrapper --xwayland` (2361), `/usr/bin/kwin_wayland --wayland-fd 7 --socket wayland-0 --xwayland-fd 8 --xwayland-fd 9 --xwayland-display :1 --xwayland-xauthority /run/user/1000/xauth_IhSEKJ --xwayland` (2367), `/usr/bin/plasmashell --no-respawn` (2511). +- `/sys/class/tty/tty0/active` = `tty1` — graphical foreground. + +SDDM journal trace this boot (`journalctl -u sddm -b`): + +- 20:31:49 Display server started; greeter starting; greeter session opened for user `sddm` (uid 961) via PAM. +- 20:31:50 Starting X11 session: `/usr/bin/sddm-greeter-qt6 --socket /tmp/sddm-:0-ZWEnZk --theme /usr/share/sddm/themes/eos-breeze`. +- 20:31:51 Greeter loaded `/usr/share/sddm/themes/eos-breeze/Main.qml`, connected to daemon. +- 20:31:56 `Adding view for "eDP-1" QRect(0,0 1920x1080)` — **the greeter rendered onto the panel**. +- 20:32:04 mfritsche logged in (`Authentication for user "mfritsche" successful`), Plasma Wayland session launched. +- 20:32:11 `Greeter stopping...` +- 20:32:16 `Error from greeter session: "Process crashed"` + sddm-helper exit 9. + +The 20:32:16 "Process crashed" is the **post-login greeter teardown**, not the pre-login crash described in the plan. SDDM kills the greeter on session start; the greeter doesn't exit cleanly; sddm logs that as "crashed". This sequence happens on every successful boot+login on this version of sddm and is not the failure mode `dynamic-forging-piglet.md` addresses. + +Coredumps: `coredumpctl list` returns "No coredumps found" (since-2h and since-boot both empty). No SIGABRT this boot. + +qFatal-style strings in journal since boot: none. + +## Why this isn't a declared fix + +1. No qFatal capture exists. The plan's Step 1 was never executed because the failure mode didn't reproduce. The plan's Step 2/3 (package-rollback testing) was therefore unreached. +2. No package changed since `pacman -Syyuu` on 2026-04-28 22:53–23:00 (mesa 26.0.3→26.0.5, qt6-base/declarative/imageformats 6.10.2→6.11.0, xorg-server 21.1.21→21.1.22). The only difference between the crashing boot and this working boot is a reboot. +3. RK3399 panfrost / Mali-T860 GBM init is timing-sensitive on cold start. A flaky pre-login GLX context-create that happened to succeed on this boot could fail on the next. +4. The pacman.log shows two consecutive qt6-base reinstalls on 2026-04-28 23:08 and 23:29 (`6.11.0-2 -> 1:6.11.0-2`, no version change), then a triple at 23:37 (`qt6-base`, `qt6-declarative`, `qt6-imageformats` reset to 6.11.0). This is consistent with the plan's documented "downgrade test then re-install fourier" sequence; the plan reports the greeter still crashed afterwards. The recovery between then and this boot is unaccounted-for. + +## Watchpoint conditions (re-open task 1 if any of these fire) + +- `journalctl -u sddm -b` on a future boot contains `qFatal` from `libqxcb-glx-integration.so` (the original signature). +- `coredumpctl list` shows a fresh `sddm-greeter-qt6` SIGABRT post-reboot. +- mfritsche reports a black-screen or crash-loop greeter again. + +## What stays ready in case of regression + +- [`~/.claude/plans/dynamic-forging-piglet.md`](../../.claude/plans/dynamic-forging-piglet.md) Step 1 invocation is unchanged and runnable as soon as a fresh failure occurs. +- `/var/cache/pacman/pkg/` on fresnel still holds the 2026-04-28 rollback candidates: `mesa-1:26.0.3-1`, `qt6-base-6.10.2-1`, `qt6-declarative-6.10.2-1`, `qt6-imageformats-6.10.2-1`, `xorg-server-21.1.21-1`. Plus older mesa 25.2.7 and 25.3.1 (deeper rollbacks if needed). +- No `libdrm-pinebookpro` cached version was found in `/var/cache/pacman/pkg/`; only stock `libdrm-2.4.131-1`. If a libdrm-pinebookpro rollback turns out to be needed, will need a different source (build host or marfrit-packages snapshot). +- Workaround Option A (Wayland greeter via `Compositor=`) and Option B (TTY autologin) remain documented in the plan; not pre-installed. + +## Implication for Phase 0 + +Task 1 is closed for this iteration. Phase 0 deliverables 2–6 (V4L2 inventory, iter5 fork build + vainfo, H.264 baseline trace, per-codec fixture inventory, chromium cross-validator trace) proceed against the live Plasma session — no headless-rig substitution needed. + +## What this isn't + +This is not a Mesa, Qt6, or panfrost bug report. We have no evidence of the failure mode on this boot and no diagnostic to attach to a tracker issue. If/when the regression fires and Step 1 captures qFatal output, an upstream report may be appropriate; until then, nothing to file.