kde/Plasma: mesa-swrast (GL software) + lanzador Plasma headless + handoff nocturno
- run-plasma-headless.sh: lanzador de sesión Plasma headless (software EGL/softpipe sobre KMS). - mesa-swrast construido (softpipe, sin LLVM, sello c59738eb): swrast_dri/kms_swrast_dri. - HANDOFF-noche-kde: kwin_wayland linkea+carga QPA pero create() del compositor crashea headless (virtio-gpu/EGL-sw/seat en musl, opaco sin gdb). El rootfs es para GPU Intel real (iris) → camino recomendado = imagen booteable para metal (laptop TigerLake). Estado + próximos pasos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
2 archivos · +112 −0
diff --git a/docs/HANDOFF-noche-kde-2026-07-14.md b/docs/HANDOFF-noche-kde-2026-07-14.md
new file mode 100644
index 00000000..62a8cfb8
--- /dev/null
+++ b/docs/HANDOFF-noche-kde-2026-07-14.md
@@ -0,0 +1,67 @@
+# HANDOFF — sesión nocturna autónoma KDE (2026-07-13→14)
+
+Trabajo desatendido continuando la campaña KDE Plasma 6 tras cerrar H-QML. Estado y próximos pasos.
+
+## Lo logrado esta noche (todo committeado+pusheado a main)
+
+1. **Hidratación FHS del escritorio COMPLETO, rebuild-free** (commit d6944b2). `hammer hydrate <hash>
+ --into` proyecta artefactos SELLADOS del store sin reproduce (el `install`-reproduce rebuildеa qtbase
+ por consumidor — hashing frágil bajo régimen dinámico). `scripts/kde/hydrate-from-store.sh` →
+ `work/kde-store-rootfs`: 137 pkgs, hashes = los sellados de la campaña (kwin 3a674cb6, plasma-workspace
+ 284c862f, libplasma 963403fe, etc.).
+
+2. **Cierre runtime COMPLETO + zlib soberano shared** (commit a7449a0).
+ - `scripts/kde/complete-closure.sh`: escanea DT_NEEDED de todos los ELF del rootfs y proyecta del store
+ lo que falte (libmount.so.1/util-linux, libltdl, libzstd, libQt6UiTools). **1269 .so, 0 faltantes.**
+ - `recipes/incoming-kde/zlib-shared.toml` (bd559f41): el stack GUI NEEDED `libz.so.1` por soname y
+ ningún artefacto lo proveía → caía al de Alpine (fuga de soberanía). `.so` fabricado del `libz.a`
+ PIC vía `--whole-archive`.
+ - **kwin_wayland ahora resuelve TODAS sus libs** y carga su plugin QPA (antes fallaba por libs faltantes).
+
+3. **mesa-swrast construido** (softpipe/swrast, GL por software SIN LLVM, sello c59738eb; la receta
+ `recipes/mesa-swrast.toml` ya existía). Provee `swrast_dri.so` + `kms_swrast_dri.so` + libEGL/GLESv2
+ software, para render sin GPU.
+
+4. **`scripts/kde/run-plasma-headless.sh`**: lanzador de la sesión Plasma headless (software EGL/softpipe
+ sobre el KMS del worker). NO funciona aún (ver abajo).
+
+## Bloqueo del "escritorio VIVO headless" (el muro de la noche)
+
+El worker (VM cloud Hetzner, host Ubuntu/glibc) TIENE `/dev/dri/card1`+`renderD128` (virtio-gpu). Con
+mesa-swrast (kms_swrast_dri) intenté levantar `kwin_wayland` con render por software + `LIBSEAT_BACKEND=
+builtin` (DRM directo como root). **kwin_wayland linkea perfecto y encuentra su QPA `wayland-org.kde.
+kwin.qpa`, pero `create()` del plugin CRASHEA (core dump)** — sin símbolo faltante ni error legible; es un
+fallo interno del backend compositor (probable interacción virtio-gpu/EGL-software/seat en musl). Opaco
+sin gdb/backtrace. Igual con backend `--virtual`. **No cierra sin depuración interactiva** — por eso paré.
+
+## Camino recomendado: METAL (tu laptop TigerLake/Intel)
+
+El rootfs está hecho para **GPU Intel real (`iris_dri.so`)**, no software. Donde kwin renderiza de verdad
+es tu laptop. Para probar H-shell mañana:
+
+1. **Regenerar el rootfs de producto con Mesa IRIS** (NO swrast — esta noche se le hizo swap a swrast para
+ el intento headless; revertir):
+ ```
+ # en el worker (o local con el store):
+ RFS=work/kde-metal-rootfs TARGETS="plasma-workspace kwin kscreenlocker breeze frameworkintegration \
+ qqc2-desktop-style plasma-integration" scripts/kde/hydrate-from-store.sh
+ RFS=work/kde-metal-rootfs scripts/kde/complete-closure.sh # cierra libmount/libz/etc.
+ # asegurar iris (mesa canónico) hidratado, NO mesa-swrast
+ ```
+2. **Fuentes**: falta desplegar TTFs (dejavu) — Qt ya no las trae (`QFontDatabase: Cannot find font
+ directory`). Cosmético pero necesario para texto. (Pendiente: receta dejavu-fonts.)
+3. **Empaquetar como imagen booteable EFI** (`scripts/install-image-efi.sh` / `disk-image.sh`) con
+ kernel-metal ([[etapa-metal-usb]]) + un init que lance `startplasma-wayland`, y bootear en el laptop
+ (Secure Boot OFF).
+
+## Alternativa productiva (si se prefiere seguir en el worker)
+
+- **Capa 2 KF6 / apps núcleo**: importar+construir `konsole`/`dolphin`/`kate` vía granja (extiende el
+ escritorio usable). Verificable (sellan o no).
+- **Seguir debug headless**: correr kwin bajo gdb en el worker para el backtrace del core dump del QPA;
+ probar `KWIN_DRM_NO_AMS=1`, `WLR_RENDERER=pixman`-equivalentes, o el backend `--virtual` con distinto
+ EGL (`EGL_PLATFORM=surfaceless`).
+
+## Comandos útiles
+- Worker: `ssh -i ~/.ssh/github5 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@95.217.179.242` (cd /opt/hammer). zsh: `${=VAR}` para splitear.
+- Rootfs actual: `work/kde-store-rootfs` (con mesa-swrast swapped). Rehidratar limpio con los scripts de arriba.
diff --git a/scripts/kde/run-plasma-headless.sh b/scripts/kde/run-plasma-headless.sh
new file mode 100644
index 00000000..194f74a3
--- /dev/null
+++ b/scripts/kde/run-plasma-headless.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+# run-plasma-headless.sh — intenta levantar la sesión Plasma (kwin_wayland + plasmashell) HEADLESS con
+# render por SOFTWARE (mesa-swrast/softpipe) sobre el KMS del worker (/dev/dri/card1), dentro del rootfs
+# musl soberano. Objetivo: hito H-shell ("escritorio prende") sin GPU real ni metal.
+#
+# Requiere: work/kde-store-rootfs hidratado + cierre completo (hydrate-from-store.sh + complete-closure.sh)
+# + mesa-swrast hidratado (kms_swrast_dri.so / softpipe).
+# Corre EN el worker (host glibc): binarios musl vía loader del .dev-fs + LD path del rootfs.
+set -uo pipefail
+ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
+R="${RFS:-$ROOT/work/kde-store-rootfs}"; A="$ROOT/.dev-fs/alpine"
+LOADER="$A/lib/ld-musl-x86_64.so.1"
+SECS="${SECS:-20}"
+export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/tmp/plasma-xdg}"; mkdir -p "$XDG_RUNTIME_DIR"; chmod 700 "$XDG_RUNTIME_DIR"
+
+# LD path = todos los dirs con .so del rootfs + sysroot
+LIBS=$(find "$R" "$A" -name "*.so*" -printf '%h\n' 2>/dev/null | sort -u | tr '\n' ':')
+# rutas de plugins/qml/datos del rootfs (lib64 y lib)
+export QT_PLUGIN_PATH="$R/usr/lib64/qt6/plugins:$R/usr/lib/qt6/plugins"
+export QML2_IMPORT_PATH="$R/usr/lib64/qt6/qml:$R/usr/lib/qt6/qml"
+export QML_IMPORT_PATH="$QML2_IMPORT_PATH"
+export XDG_DATA_DIRS="$R/usr/share"
+export XDG_CONFIG_HOME="$XDG_RUNTIME_DIR/config"; mkdir -p "$XDG_CONFIG_HOME"
+export QT_QPA_PLATFORM_PLUGIN_PATH="$QT_PLUGIN_PATH/platforms"
+# software render: softpipe (mesa-swrast), sin aceleración
+export LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=softpipe
+export LIBGL_DRIVERS_PATH="$R/usr/lib/dri:$R/usr/lib64/dri"
+export __EGL_VENDOR_LIBRARY_DIRS="$R/usr/share/glvnd/egl_vendor.d"
+export QT_QUICK_BACKEND=software # QtQuick por software (plasmashell)
+export KWIN_COMPOSE="${KWIN_COMPOSE:-Q}" # Q = QPainter (compositing por software, sin GL) si aplica
+export QT_LOGGING_RULES="kwin_*.debug=false"
+
+run() { "$LOADER" --library-path "$LIBS" "$@"; }
+
+echo "==> lanzando kwin_wayland (drm sw / softpipe) ${SECS}s"
+KW=$(find "$R" -name kwin_wayland -type f | head -1)
+# --drm sobre el KMS del worker; sin lockscreen; salida virtual si drm falla
+run "$KW" --no-lockscreen --width 1280 --height 800 \
+ -- "$LOADER" --library-path "$LIBS" "$(find "$R" -name plasmashell -type f|head -1)" \
+ >"$ROOT/work/plasma-headless.log" 2>&1 &
+KPID=$!
+sleep "$SECS"
+echo "==> log (kwin+plasmashell):"; tail -40 "$ROOT/work/plasma-headless.log"
+echo "==> sockets wayland en XDG_RUNTIME_DIR:"; ls -la "$XDG_RUNTIME_DIR"/wayland-* 2>/dev/null || echo " (ninguno)"
+kill "$KPID" 2>/dev/null; pkill -f kwin_wayland 2>/dev/null; pkill -f plasmashell 2>/dev/null