# GUI → PKG/QA requests (M1) Filed by lane GUI. These touch PKG/QA-owned files (`tools/bootstrap.sh`, the CI jobs, `docs/agents/AGENT-PKG-QA.md`) and the root `README.md`, so GUI is not making the edits — CLAUDE.md §1. Everything below is apply-ready. --- ## R1 — `libqt6svg6-dev` is not a real package on 26.04 (hard configure failure now) `apt-cache policy libqt6svg6-dev` on a clean Ubuntu 26.04 box gives `Candidate: (none)`. The Qt 6 SVG **dev** package in the 26.04 archive is **`qt6-svg-dev`** (currently `6.10.2-2`). `libqt6svg6` (no `-dev`) exists as the runtime lib but carries no headers or CMake config, so `find_package(Qt6 COMPONENTS Svg)` fails without `qt6-svg-dev`. I checked the other 38 apt names in `bootstrap.sh` against `apt-cache policy` on 26.04 — `libqt6svg6-dev` is the only one with no candidate. Everything else resolves. **This is no longer a latent bug.** `gui/CMakeLists.txt` is now on `main`, so the root `CMakeLists.txt` line ```cmake find_package(Qt6 6.6 REQUIRED COMPONENTS Widgets Svg Network LinguistTools) ``` is live for every build. On a machine without the SVG dev package that is a hard configure failure for the whole project — not a skipped guard, not a GUI-only problem. **Why nothing has gone red yet — and why that's R2's problem too:** * This dev box already has `qt6-svg-dev` (pulled in by a `qt6-base-dev` recommends chain), so `pkg-config --exists Qt6Svg` succeeds and `--check` is green here. * CI runs on `ubuntu-latest`, which is **24.04**, where `libqt6svg6-dev` most likely still resolves. The project *targets* **26.04** (the `ci.yml` env comment says as much). So the one automated place that runs `bootstrap.sh` is on the wrong release to see this, and `--check` wouldn't catch it there anyway (R2). Wrong package name + runner-vs-target release mismatch means the class of bug PKG/QA owns is currently unobservable in CI. ### Fix — three files, same one-line change **`tools/bootstrap.sh`** (in `APT_GUI`, ~line 87): ```diff APT_GUI=( qt6-base-dev qt6-tools-dev qt6-tools-dev-tools # lrelease/lupdate for i18n - libqt6svg6-dev # GUI: SVG icon rendering + qt6-svg-dev # GUI: SVG icon rendering (was libqt6svg6-dev — no such + # package on 26.04; this is the one with headers + + # the Qt6SvgConfig.cmake find_package needs) ) ``` **`docs/agents/AGENT-PKG-QA.md`** (~line 17): ```diff - `libqt6svg6-dev`, `libsecret-1-dev`, `nodejs`/`npm` and (optionally) `clang` are + `qt6-svg-dev`, `libsecret-1-dev`, `nodejs`/`npm` and (optionally) `clang` are ``` **`README.md`** (toolchain table, ~line 106): ```diff sudo apt update && sudo apt install -y \ - libqt6svg6-dev \ # GUI: SVG icon rendering + qt6-svg-dev \ # GUI: SVG icon rendering libsecret-1-dev \ # DAEMON: Secret Service for site logins ``` --- ## R2 — `--check` verifies the outcome, not the thing that can break `--check` today runs the "verify toolchain" block: `command -v` for the binaries, `pkg-config --exists` for the dev libs (`Qt6Core`, `Qt6Widgets`, `Qt6Svg`, `libcurl`, `sqlite3`, `libssl`, `libsecret-1`, `libavformat`), plus the cmake/g++/node version floors. Every one of those checks a *result* on a box that already installed everything. None of them touch the apt package **names** in `APT_*`, which is the only part of the script that can be wrong on a clean machine — as R1 just demonstrated. So `--check` reported green for a script that fails `apt-get install` on its target OS. ### Proposed fix — make `--check` validate the install list it would actually run Add this to the verify block (runs in **both** modes; in `--check` mode it is the point of the exercise). It needs neither root nor network — `apt-cache policy` reads the local package lists that `apt-get update` already populated: ```bash # Every apt name this script would install must be a real, installable package on THIS # release. This is the check that would have caught libqt6svg6-dev before the VM did. log "validating apt package names (${#PKGS[@]})" missing_pkgs=() for pkg in "${PKGS[@]}"; do # `apt-cache policy ` prints "Candidate: (none)" for a name with no installable # version, and exits 0 either way — so grep the candidate line, don't trust $?. cand="$(apt-cache policy "$pkg" 2>/dev/null | sed -n 's/^ Candidate: //p')" if [[ -z "$cand" || "$cand" == "(none)" ]]; then printf ' \033[31m✗\033[0m %-20s no installable candidate on this release\n' "$pkg" missing_pkgs+=("$pkg") fail=1 fi done if (( ${#missing_pkgs[@]} == 0 )); then printf ' \033[32m✓\033[0m %-20s all %d resolve\n' "apt names" "${#PKGS[@]}" fi ``` Notes for whoever applies it: * `PKGS` is already assembled above the `CHECK_ONLY` branch, and it already respects `--with-clang` / `--with-packaging`, so the loop covers exactly what would be installed. * Belt-and-braces alternative: `apt-get install -s --no-install-recommends "${PKGS[@]}"` (`-s` = simulate, no root) also catches an *un-satisfiable dependency*, not just a missing name. Downside: it needs the apt lists reasonably fresh and is noisier to parse. `apt-cache policy` is enough to catch the whole class of bug in R1; pick whichever you want to own. * **The runner mismatch is part of this.** Even with the name-validation loop, the `bootstrap-script` job on a 24.04 runner validates names against the *24.04* archive, not 26.04. So R2 only fully closes the gap if the check also runs where the project ships — a 26.04 container step in that job (`container: ubuntu:26.04`), or a documented decision that 24.04 is close enough and why. Without that, a name that is valid on 24.04 and gone on 26.04 (exactly `libqt6svg6-dev`) still slips through. --- ## R3 — the GUI DoD gates have nowhere to run in CI To be precise about what already works: `VELOX_BUILD_GUI` defaults `ON`, the `ci` preset inherits `dev`, and once `gui/` is on `main` the `build` and `sanitizers` jobs configure and build `velox-gui` and run `ctest --preset ci`, which picks up all three GUI checks (`gui_downloadtablemodel`, `gui_rtl`, `gui_no_download_logic`). That part is covered. What has no home is the part of the GUI M1 definition of done that isn't a unit test: 1. **10 000 rows scroll at 60 fps** (`mockd --tasks 10000`) — needs a frame-timing probe against the offscreen (or Xvfb) view; red when a scroll frame exceeds ~16 ms at the 99th percentile. 2. **Flat memory over 10 minutes of progress events** — needs RSS sampled across a 10-minute `mockd --tasks 10000` run; red when RSS grows more than a small fixed slack (a leak in the progress-patch path is the thing this catches). 3. **Unhappy-path recovery** — `mockd --slow`, `--flaky `, `--drop-connection `: the client must show the banner and recover without a freeze or crash; red on a crash, a hang (watchdog), or the connection state never returning to `Connected`. GUI owns writing that harness (`gui/tests/` + a driver script, headless against `mockd`). Wiring it into `.github/workflows/ci.yml` as its own job — with the 10-minute one likely `nightly` rather than per-PR — is PKG/QA. Say the word and it comes over as a follow-up request with the job stanza pre-written.