imagen: el navegador arranca en la imagen booteada y NO PINTA VENTANA — medido, con lo descartado

Primera prueba de `atuq` dentro de una imagen de disco arrancada, y el resultado no es el de la
jaula. La cadena previa funcionó, y eso también es medición: el perfil `escritorio-cosmic` hidratado
con el cierre de hoy (275 nodos, 8,4 G) trae `/usr/bin/atuq`, `/usr/bin/llama-server` y el modelo —
declarar en el perfil SÍ pone las cosas en la imagen—, la imagen EFI de 12 G arranca en QEMU y COSMIC
pinta panel y dock en ~2 min.

Y `atuq` arranca —sus extensiones inician, la del foco sondea cada minuto, WebRender inicializa— sin
que la ventana aparezca nunca. Descartado, para que nadie lo repita: no es el sandbox de Gecko
(relanzado con los cinco MOZ_DISABLE_* puestos, idéntico), no es que el proceso muera (sigue
ejecutando el JS de las extensiones), y no es la IA (pasa con about:blank).

La pista: bajo sway headless el MISMO artefacto pinta perfecto y hay capturas del panel contestando.
La diferencia son el compositor (cosmic-comp+llvmpipe contra sway+pixman) y el arranque real contra
bwrap. Es su propia unidad de trabajo, no un parche apurado.

⚠ La lección del método: quince guardianes en verde, `vigia-imagen.py` en ✓, y el navegador igual no
se puede usar en la imagen. «Sella», «hidrata» y «los tests pasan» son tres cosas distintas de
«arranca y se ve».

De paso, `metal-iso.sh` acepta ahora STORE y AUG por entorno, porque en esta máquina no funcionaba:
arma el rootfs con `cp -al` desde el store y el store es un BIND-MOUNT del volumen — `linkat` rechaza
cruzar mounts aunque sea el mismo disco, así que hay que nombrar los dos lados dentro del mismo
mount. Es la cuarta vez que aparece el mismo EXDEV hoy.
This commit is contained in:
Sergio
2026-09-14 00:54:47 +00:00
parent 28fcd77cf2
commit 60202bf526
2 changed files with 51 additions and 5 deletions
+33
View File
@@ -1599,6 +1599,39 @@ es una invitación a «simplificarlo» de vuelta al que se cae.
⚠ Lo que NO se midió: si el crash existe también en el `--headless` de una máquina sin jaula. No hace
falta para lo que se decidió acá, y afirmarlo sin medirlo sería justo lo que este documento no hace.
#### 6.10.ter ⚠ En la IMAGEN BOOTEADA con COSMIC, `atuq` corre y NO PINTA VENTANA (2026-09-14)
Primera vez que el navegador se prueba **dentro de una imagen de disco arrancada**, y el resultado no
es el de la jaula. La cadena entera funcionó —y esa parte también es medición—:
1. `escritorio-cosmic` hidratado con el cierre de HOY: **275 nodos**, 8,4 G, y adentro están
`/usr/bin/atuq`, `/usr/bin/llama-server` y `/usr/share/takana/ia/modelo.gguf`. O sea que
**declarar en el perfil sí pone las cosas en la imagen** — la otra mitad de la lección de `foot`;
2. imagen EFI de 12 G construida y **arrancada en QEMU**: COSMIC pinta panel, dock y fondo en ~2 min
(TCG, sin KVM);
3. `atuq` **arranca**: sus extensiones inician y la del §6.5 sondea el foco cada minuto
(`FOCO ESTADO unknown`), WebRender inicializa («Software WebRender», GL 3.2);
4. **y la ventana nunca aparece.** Cinco minutos, dos capturas, y el escritorio sigue vacío.
**Lo que ya se descartó**, para que nadie lo repita:
- **no es el sandbox de Gecko**: relanzado con los cinco `MOZ_DISABLE_*_SANDBOX` puestos, idéntico;
- **no es que el proceso muera**: sigue vivo y ejecutando el JS de las extensiones;
- **no es el modelo ni la IA**: pasa con `about:blank`.
**La pista que vale**: bajo **sway headless** el mismo artefacto pinta perfecto —hay capturas del
panel contestando (§6.7.ter)—. La diferencia entre los dos casos es el compositor (cosmic-comp con
llvmpipe contra sway con pixman) y el arranque real contra `bwrap`. Eso acota dónde mirar, y es
material para su propia unidad de trabajo, no para un parche apurado.
⚠ **Y la lección del método**: sin arrancar la imagen, esto no se veía. Los quince guardianes están
en verde, el `vigia-imagen.py` del perfil da ✓ en iconos, cursores, fuentes, terminal y QML, y el
navegador **igual no se puede usar** en la imagen. «Sella», «hidrata» y «los tests pasan» son tres
cosas distintas de «arranca y se ve».
Artefactos de la corrida, para quien siga: `/mnt/cosecha/takana-cosmic-qemu.img` (12 G) y las
capturas en `work/cosmic-{1..6}.png`.
### 6.11 Y ahora la pregunta que faltaba: ¿REPRODUCE? (2026-09-07)
El §6.10 preguntó «¿qué NO puede hacer?» y contestó leyendo cadenas. Media pregunta. La otra mitad
+18 -5
View File
@@ -17,22 +17,35 @@
set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
# ⚠ STORE se puede apuntar a la ruta REAL del store, y en esta máquina hace falta. Este script arma
# el rootfs con `cp -al` —hardlinks, para no copiar gigabytes— y `linkat` **rechaza cruzar mounts**
# aunque sean el mismo disco. El store está bind-mounteado en `./store` desde el volumen, así que
# con el default nada enlaza: hay que nombrar los dos lados dentro del MISMO mount.
# STORE=/mnt/cosecha/store AUG=/mnt/cosecha/metal-rootfs scripts/metal-iso.sh
STORE="${STORE:-store}"
if [ -n "${PRODUCT:-}" ]; then
PDIR=$(ls -d store/"${PRODUCT#b3:}"*-product-rootfs 2>/dev/null | head -1)
PDIR=$(ls -d "$STORE"/"${PRODUCT#b3:}"*-product-rootfs 2>/dev/null | head -1)
else
PDIR=$(ls -dt store/*-product-rootfs 2>/dev/null | head -1)
PDIR=$(ls -dt "$STORE"/*-product-rootfs 2>/dev/null | head -1)
fi
[ -n "${PDIR:-}" ] && [ -d "$PDIR" ] || { echo "no encuentro product-rootfs (corré 'hammer bootstrap product')" >&2; exit 1; }
KERNEL="${KERNEL:-$(ls -dt store/*-linux-metal/boot/bzImage 2>/dev/null | head -1)}"
KERNEL="${KERNEL:-$(ls -dt "$STORE"/*-linux-metal/boot/bzImage 2>/dev/null | head -1)}"
[ -n "${KERNEL:-}" ] && [ -r "$KERNEL" ] || { echo "no encuentro el kernel metal (build recipes/linux-metal.toml)" >&2; exit 1; }
WPADIR=$(ls -dt store/*-wpa_supplicant/usr/sbin 2>/dev/null | head -1)
WPADIR=$(ls -dt "$STORE"/*-wpa_supplicant/usr/sbin 2>/dev/null | head -1)
[ -n "${WPADIR:-}" ] || { echo "no encuentro wpa_supplicant (build recipes/wpa_supplicant.toml)" >&2; exit 1; }
ISO="${ISO:-work/hammer-metal.iso}"
CMDLINE="${CMDLINE:-console=ttyS0,115200 console=tty0 rdinit=/init}"
AUG="work/metal-rootfs"
# ⚠ AUG se puede mover, y en esta máquina HAY QUE MOVERLO. El rootfs se arma con `cp -al` desde el
# store —hardlinks, para no copiar gigabytes— y el store es un **bind-mount del volumen**: `linkat`
# rechaza cruzar mounts aunque sea el mismo disco, así que con el default en `work/` esto muere con
# `Invalid cross-device link` en el primer fichero. Con AUG en el mismo filesystem que el store,
# los hardlinks vuelven a funcionar y no se copia nada.
# AUG=/mnt/cosecha/metal-rootfs scripts/metal-iso.sh
AUG="${AUG:-work/metal-rootfs}"
echo "==> product-rootfs : $PDIR"
echo "==> kernel metal : $KERNEL"