sergio/takana
> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…
wlr: el escritorio DIBUJA — arranque headless en 2 min y 5 piezas que el cierre no traía
1#!/bin/sh
2# sway-headless.sh — arranca el perfil escritorio-sway SIN QEMU, SIN kernel y SIN imagen de disco, y
3# captura la pantalla con grim. Hermano de sway-start.sh (que arranca dentro de la VM); éste corre el
4# cierre hidratado dentro de un `bwrap` sobre la máquina de desarrollo.
5#
6# PARA QUÉ. Validar «el escritorio dibuja» costaba armar un product-rootfs + imagen EFI + arranque en
7# QEMU: ~40 min por vuelta y hace falta un `hammer bootstrap product` que hoy no está en el store.
8# Headless da la misma evidencia —píxeles reales, dibujados por NUESTROS binarios— en ~2 min, así que
9# el ciclo de diagnóstico deja de ser el cuello de botella. NO sustituye al arranque en QEMU: no prueba
10# kernel, ni initramfs, ni DRM, ni el PID1. Prueba el compositor y sus clientes, que es justo lo que
11# el arranque en VM tapa detrás de una pantalla negra.
12#
13# INVOCACIÓN (desde la raíz del repo, con work/sway-rootfs ya hidratado):
14# mkdir -p /tmp/sway-out
15# bwrap --bind work/sway-rootfs / --bind /usr/lib/musl /usr/lib/musl \
16# --bind /tmp/sway-out /salida --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \
17# --unshare-user --uid 0 --gid 0 --setenv PATH /usr/bin:/bin:/usr/sbin:/sbin \
18# /bin/sh /sway-headless.sh
19#
20# ── LO QUE EL CIERRE 121/121 NO TRAE Y HAY QUE INYECTAR ────────────────────────────────────────
21# Medido el 2026-08-26 sobre el perfil COMPLETO. Nada de esto lo aporta la clausura:
22# · libz.so.1 / libexpat.so.1 / libffi.so.8 — sway salió DINÁMICO contra ellas y el corpus sólo
23# produce los `.a`. `libz.so.1` está como artefacto aparte (`zlib-shared`); las otras dos hoy
24# sólo existen en `.dev-fs/alpine`. Sin ellas sway ni arranca: «Error relocating /usr/bin/sway:
25# XML_ParserFree: symbol not found».
26# · xkeyboard-config — «xkbcommon: ERROR: failed to add default include path /usr/share/X11/xkb».
27# Sway sigue vivo pero no completa el seat. HAY receta, en incoming-{kde,gnome,cosmic}; en la
28# cola de wlr no, así que el perfil no la alcanza.
29# · dejavu-fonts — el rootfs no tiene UNA fuente. `foot` muere con «monospace::size=8: failed to
30# match font». Misma historia: la receta existe en incoming-{kde,cosmic} y no en la de wlr.
31# · /etc/passwd y /etc/fonts/fonts.conf — sin el primero yambar hace getpwuid y falla; sin el
32# segundo fontconfig no mira /usr/share/fonts aunque las fuentes estén.
33#
34# ── BASH NO CORRE EN ESTE ROOTFS, Y ASÍ ES COMO SE VE ──────────────────────────────────────────
35# `/bin/bash` está enlazado dinámico contra ncurses y el corpus sólo produce `libncurses.a`:
36# Error relocating /bin/bash: tgetent: symbol not found
37# El síntoma NO fue un error de bash. Fue que `foot` abría, sway registraba «New xdg_shell toplevel»
38# —o sea la ventana EXISTÍA en el árbol— y la captura salía con UN SOLO COLOR, el de swaybg: foot
39# lanzaba el shell, el shell moría al instante y la ventana se cerraba antes del frame. Por eso acá
40# el shell es busybox, que sí es autosuficiente.
41#
42# ── LA EVIDENCIA ES CONTAR COLORES, NO LEER EL LOG ─────────────────────────────────────────────
43# El log entero puede estar en verde con la pantalla vacía. La medida que no se puede falsear:
44# 1 color = sólo el fondo de swaybg ⇒ NINGÚN cliente dibujó (aunque el árbol los liste)
45# ~380 = terminal con texto ⇒ #242424 fondo de foot, #285577/#4c7899 bordes de sway,
46# #d0d0d0 el texto. ESO es un escritorio dibujando.
47
48export XDG_RUNTIME_DIR=/run/user/0
49mkdir -p "$XDG_RUNTIME_DIR"; chmod 700 "$XDG_RUNTIME_DIR"
50export WLR_BACKENDS=headless
51export WLR_HEADLESS_OUTPUTS=1
52export WLR_RENDERER=pixman
53export XDG_CONFIG_HOME=/root/.config
54export SHELL=/bin/bash
55export LANG=C
56export HOME=/root
57
58(
59 i=0
60 while [ ! -S /run/user/0/wayland-1 ] && [ $i -lt 40 ]; do sleep 1; i=$((i+1)); done
61 [ -S /run/user/0/wayland-1 ] || { echo "!! el socket wayland nunca apareció"; exit 1; }
62 export WAYLAND_DISPLAY=wayland-1
63 echo "== socket listo, lanzando clientes"
64 /usr/bin/swaybg -c '#1a4b8c' & sleep 2
65 # bash NO corre en este rootfs: está enlazado dinámico contra ncurses y el corpus sólo produce
66 # libncurses.a ⇒ «Error relocating /bin/bash: tgetent: symbol not found». foot lanzaba el shell,
67 # el shell moría al instante y foot cerraba la ventana: el toplevel APARECÍA en el árbol de sway
68 # y la captura salía 100% del color de swaybg. Se usa busybox, que sí es autosuficiente.
69 /usr/bin/foot -- /bin/busybox sh -c '
70 echo " hammer — distro reproducible desde fuente"
71 echo
72 echo " compositor : sway 1.10 / wlroots 0.18.2"
73 echo " terminal : foot 1.27.0"
74 echo " libc : musl toolchain: zig cc"
75 echo
76 /bin/busybox uname -a
77 echo
78 echo " binarios en /usr/bin: $(/bin/busybox ls /usr/bin | /bin/busybox wc -l)"
79 /bin/busybox sleep 60' >/salida/foot.log 2>&1 & sleep 12
80 echo "== capturando"
81 /usr/bin/grim /salida/captura.png 2>&1 && echo "== grim OK: $(ls -l /tmp/captura.png)"
82 sleep 1
83 /usr/bin/swaymsg exit 2>/dev/null
84) &
85
86exec /usr/bin/sway -d 2>&1