Commit Graph
8 Commits
Author SHA1 Message Date
sergioandClaude Opus 5 a98267468c gnome: gi-foreign-typelibs (b3:a159373c) — un .gir NO es un typelib
Con accountsservice adentro, la capa JS avanzó y murió un paso después:

  JS ERROR: Requiring Atspi, version 2.0: Typelib file for namespace 'DBus', version '1.0' not found

`Atspi-2.0.gir` declara `<include name="DBus" version="1.0"/>`. El `DBus-1.0.gir` YA estaba en
/usr/share/gir-1.0 (lo pone gi-foreign-girs), pero gjs resuelve en runtime contra el TYPELIB
compilado, no contra el XML — el XML le alcanza al scanner, no al cargador.

Receta aparte y no un compile agregado a gi-foreign-girs porque `yupana radio` da **17 sellados
cayendo a deuda** ahí (catorce recetas la declaran para escanear, mutter y gnome-shell entre ellas).
Compilar cuatro typelibs no justifica reconstruir la cima. No se pisan: una instala sólo en gir-1.0
y la otra sólo en girepository-1.0. Mismo criterio que separó udev-pc de libudev-zero.

Se compilan CUATRO nombrados explícitamente —DBus-1.0, DBusGLib-1.0, fontconfig-2.0, freetype2-2.0—
y no un glob: los .gir de X11 y cairo arrastran includes que no tenemos y son justamente los que
hacían SIGSEGV a g-ir-compiler (la razón de nuestro -Dbuild_introspection_data=false).

Además: gnome-start lanza accounts-daemon explícito. Su .service de activación está instalado, pero
la activación por bus de sistema pasa por dbus-daemon-launch-helper, que acá no es setuid root;
correr como root probablemente alcanzaría, pero depender de eso es depender de un accidente.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 12:10:05 -04:00
sergioandClaude Opus 5 08fc1d4b92 gnome: accountsservice SELLA (b3:0328b0d0) — cae la frontera de la C-ABI de logind
Los dos huecos que bloqueaban esta receta estaban medidos desde ayer símbolo por
símbolo, y ninguno era de accountsservice. Los dos cerrados:

1. libelogind pasa de 14 a 22 símbolos (tawasuyu 8d892151b, re-pineado a b56aeff46,
   re-sellado b3:9650ee06). Los ocho nuevos son los que usa accountsservice, con
   `sd_login_monitor_*` implementado sobre inotify en /run/systemd/{sessions,seats,users}.

2. `fgetspent_r` no existe en musl ⇒ accountsservice-fgetspent_r-musl.patch. NO es
   sustituir por `fgetspent()` a secas: daemon.c guarda los buffers en un GHashTable
   y `fgetspent()` devuelve un struct estático que se reescribe en cada llamada —
   todas las entradas de la tabla apuntarían al último usuario leído. El parche copia
   el registro al buffer del llamador, y sigue el patrón que el propio accountsservice
   ya usa para /etc/passwd (`src/fgetpwent.c` bajo `#ifndef HAVE_FGETPWENT`).

Produce `AccountsService-1.0.typelib`, que es exactamente lo que la capa JS pedía.

De paso, dos cosas que este frente enseñó y quedan horneadas:
- libelogind necesitaba `cargo_vendor_dir` (el `vendor/` de smithay entró a la rama
  selfhost con el merge de main; el mismo choque que ya tenía arje-logind-compat).
- `hydrate-gnome.sh` ahora hidrata DOS raíces por defecto. accountsservice no es dep
  de build de nadie: es dep de RUNTIME, resuelta por gjs al arrancar. **El cierre de
  build no es el cierre de runtime**, y lo que el shell carga por `imports.gi.*` hay
  que nombrarlo a mano o no entra al rootfs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 11:54:52 -04:00
sergioandClaude Opus 5 03bdd41b4a gnome: el muro de input NO era libudev-zero — el fd de TakeDevice era bloqueante
Tres cambios de diagnóstico en `gnome-start` que, juntos, dieron el veredicto:

1. SONDA DE INPUT antes de lanzar el shell. `libinput list-devices` hace lo mismo
   que `init_libinput()` de mutter (udev_new + create_context + assign_seat) pero
   abriendo el devnode por su cuenta. Volvió con rc=0 y los tres dispositivos
   listados ⇒ **la hipótesis libudev-zero del runbook queda REFUTADA**: la
   enumeración por /sys funciona.

2. El volcado POR HILO corría DESPUÉS del `kill -ABRT`, o sea sobre un
   /proc/<pid>/task que ya no existía: salía vacío. Movido antes. Ahí apareció el
   dato: `tid 201 [Mutter Input Th] wchan=evdev_read syscall=0`. El hilo de input
   dormido en un `read()` de evdev dentro del kernel. (El core no servía: gdb no
   desenrolla a través de musl y devuelve `?? ()` para los 11 hilos no principales.)

3. `MUTTER_DEBUG` es una LISTA DE TÓPICOS (g_parse_debug_string sobre
   meta_debug_keys), no un booleano: con `1` no encendía nada. Ahora
   `backend,input,kms`, y el tópico `backend` imprime la última línea antes del
   cuelgue: «Opening and taking control of device file '/dev/input/event0'».

Más: ping D-Bus a login1 en el diagnóstico (el daemon respondía: no estaba
tildado) y copia de los logs de /tmp —que es tmpfs— a la raíz ext4 para poder
sacarlos con debugfs junto al core.

La causa está arreglada en tawasuyu (3dd88f582): `TakeDevice` abría sin
`O_NONBLOCK`. Receta re-pineada a 2445fa31c y re-sellada b3:7ffa9256.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 11:09:54 -04:00
sergioandClaude Opus 5 8cf9a87dd2 arje-logind-compat: repineado al fix (b3:5e4b8e04) — la cadena vuelve a ser reproducible
Los dos arreglos de arje-logind-compat (sesión eager + object path de Session
escapado como systemd) están commiteados y pusheados en tawasuyu, así que la
imagen ya NO corre un binario compilado a mano: corre el artefacto sellado, y se
verificó que da EXACTAMENTE el mismo resultado (mismo `Added virtual monitor
Meta-0` → `Using Wayland display name 'wayland-0'` → mismo muro en el typelib de
AccountsService).

El pin va a la rama selfhost, no a main: esa rama existe para que hammer pueda
construir con --locked de forma hermética (el monorepo gitignora el Cargo.lock).
Estaba MUY atrás — el artefacto viejo ni siquiera tenía el objeto Session que
mutter necesita —, así que se le mergeó main y se regeneró el Cargo.lock, que con
main al día había quedado viejo y habría hecho fallar el --locked.

Y ahí apareció una colisión ya conocida pero no aplicada acá: el monorepo COMMITEA
su propio `vendor/` (`[patch.crates-io] smithay = { path = "vendor/smithay" }`, la
copia parcheada que mirada usa para el tearing) y `cargo vendor` de hammer escribe
en `vendor/` por defecto, pisándolo. El build moría con
`failed to read /src/vendor/smithay/.cargo-checksum.json`. Se resuelve con el
campo que ya existía para esto: cargo_vendor_dir = ".hammer-cargo-vendor".

De paso, el script de imagen elige el artefacto por `hammer hash` sobre la receta
—el que corresponde a la receta de HOY— en vez de por el más reciente del store:
con dos artefactos del mismo paquete conviviendo, la fecha no dice cuál es el
vigente. Mismo criterio que hydrate-gnome.sh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 06:52:15 -04:00
sergioandClaude Opus 5 f56bab72f5 gnome: el compositor SUBE ENTERO en headless — el muro DRM es libinput, y aparece accountsservice
Experimento decisivo: `gnome-shell --headless --virtual-monitor 1280x800`. El
backend headless crea el seat con META_SEAT_NATIVE_FLAG_NO_LIBINPUT, o sea que
saltea init_libinput() — justo el último paso del hilo de input antes de señalar
`input_thread_initialized` (meta-seat-impl.c:3098). Resultado:

  libmutter-Message: Added virtual monitor Meta-0
  libmutter-Message: Using Wayland display name 'wayland-0'
  == compositor OK (wayland-0) — el shell ES el display server

⇒ **CONFIRMADO: el bloqueo del camino DRM está en libinput/udev, no en el resto
del arranque.** Todo lo demás de mutter funciona. Primer sospechoso libudev-zero.

Y con el compositor arriba aparece el muro siguiente, que es de otra naturaleza:

  Gjs-CRITICAL: JS ERROR: Requiring AccountsService, version 1.0:
                Typelib file for namespace 'AccountsService' not found

LA LECCIÓN DE MÉTODO: gnome-shell selló con su cierre de build COMPLETO (108/108)
y aun así la sesión muere pidiendo este typelib. **El cierre de build no es el
cierre de runtime**: todo lo que el shell carga por `imports.gi.*` desde
JavaScript es invisible al grafo de deps. Se encuentra ARRANCANDO, no compilando.

Se autoró recipes/incoming-gnome/accountsservice.toml. El configure pasa entero
—tres seds verificados contra el build real: generate-version.sh (deriva la
versión del nombre del DIRECTORIO, que en el sandbox es /src, y la rama git usa
`date`, o sea no-determinista), la aserción de wtmp (musl no define WTMPX_FILENAME
ni _PATH_WTMPX) y subdir('tests') (arrastra mocklibc, que llama fgetgrent, ausente
en musl)—. Ojo: -Dsystemdsystemunitdir tiene que ser literalmente `no`; con la
cadena vacía el meson interpreta "averiguá el directorio" y aserta pidiendo
systemd.pc.

NO SELLA todavía, y la frontera está contada símbolo por símbolo, no estimada:

  · libelogind exporta 14 símbolos (los que pedía mutter) y accountsservice usa
    OCHO que faltan: sd_get_sessions, sd_seat_can_multi_session,
    sd_session_get_display y los cinco de sd_login_monitor_*. Estos últimos son
    la parte con enjundia: no son getters sino una API de NOTIFICACIÓN (un fd
    poll-able). Sobre el diseño actual el camino natural es inotify sobre
    /run/systemd/{sessions,seats,users}.
  · fgetspent_r no existe en musl (extensión glibc de /etc/shadow, usada en
    src/daemon.c:265): necesita shim o parche a la variante no-reentrante.

Ninguno de los dos es de accountsservice: son huecos de NUESTRA capa de compat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 06:07:42 -04:00
sergioandClaude Opus 5 34c7962b29 gnome: cae el SIGSEGV — el shell toma DRM master e input; muro nuevo en la hebra de input
Dos bugs REALES de arje-logind-compat, encontrados arrancando la imagen y
arreglados (con test) en el árbol de tawasuyu — todavía LOCALES, sin pushear:

  1. La sesión se creaba PEREZOSAMENTE. `ensure_user` sólo corría dentro de un
     método del Manager, y `write_login_state` vive adentro. Pero mutter no
     empieza por D-Bus: lo primero que hace es sd_pid_get_session(), que
     arje-sdlogin-compat resuelve LEYENDO /run/systemd/sessions. Huevo y gallina:
     el estado en disco sólo se escribía después de un pedido que sólo ocurre si
     el estado ya existe. Ahora se crea al arrancar (eager_session).

  2. El object path de la Session estaba MAL ESCAPADO: era `/session/_1`. La
     convención de systemd (bus_label_escape) codifica `_<hex>` todo lo que no sea
     [A-Za-z0-9] **y también el primer carácter si es dígito** ⇒ el id "1" da
     `_31`. Importa porque el cliente calcula el path por su cuenta y NO pregunta:
     mutter reimplementa la misma regla en meta-dbus-utils.c. Con `_1` no había
     nadie sirviendo ahí, la propiedad `Seat` volvía NULL y mutter —que no
     chequea— moría de SIGSEGV en get_seat_proxy. Los objetos User NO usan este
     escapado (systemd hardcodea `_<uid>`), así que user_path() queda igual.

Y ARJE_LOGIN_STATE=1 YA EXISTÍA: el comentario del daemon dice literalmente "en
arje (sin systemd) el launcher de sesión lo prende. Default off" — y el launcher
es gnome-start. El puente que escribía /run/systemd/ a mano era reinventar esa
perilla; queda de fallback inerte.

Resultado: el shell ya no crashea. Corre con 12 hilos, /dev/dri/card0 abierto
tres veces y /dev/input/event0 abierto — el TakeDevice de logind funciona y el
compositor tiene DRM master e input. Queda bloqueado en
meta_seat_impl_initable_init (meta-seat-impl.c:3154): espera en un condvar a que
la "Mutter Input Thread" avise que inicializó, y nunca avisa. Hipótesis principal
libudev-zero, que ya dio un episodio idéntico en el frente de la USB nvidia.

El gnome-start ahora le fuerza un core con SIGABRT al proceso colgado: sin gdb en
la imagen es la única forma de ver dónde está parado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 22:49:46 -04:00
sergioandClaude Opus 5 5295aa35c6 gnome: la cima ARRANCA en QEMU — muere en meta_launcher_new, causa localizada
gnome-shell bootea, compila sus esquemas, toma el DRM de virtio-gpu y se declara
Wayland display server. Después SIGSEGV. El backtrace del core no deja dudas:

  #4 g_variant_get (value=0x0, "(s&o)")     ← GVariant NULO
  #5 get_seat_proxy   src/backends/meta-launcher.c:407
  #6 meta_launcher_new (META_LAUNCHER_FLAG_TAKE_CONTROL)

Mutter pide la propiedad `Seat` del objeto **Session** de logind — `(s&o)` es su
firma estándar (nombre_del_seat, object_path). arje-logind-compat adquiere
org.freedesktop.login1 y sirve el Manager, pero NO expone un objeto Session con
esa propiedad ⇒ la lectura devuelve NULL y mutter desreferencia sin chequear. Que
mutter no valide es fragilidad suya; el hueco es nuestro.

Cinco eslabones hubo que armar antes de llegar a ese muro, ninguno anotado:
  1. gschemas.compiled NO se genera con DESTDIR seteado (meson lo dice en el log
     del build) ⇒ GSettings abortaba en el primer g_settings_new().
  2. GI_TYPELIB_PATH tiene que incluir /usr/lib/gnome-shell: St/Shell/Gvc/Shew se
     instalan aparte por ser privados del shell. Es el env sin análogo en KDE.
  3. /var/run no existía en la base metal; arje-logind-compat busca el bus en la
     ruta legacy y sin el symlink se iba a "modo idle".
  4. La política D-Bus de login1 faltaba (system.conf trae <deny own="*"/> y
     normalmente la instala systemd). PERTENECE al artefacto de arje: está en el
     script de imagen sólo para dejar visible qué falta empaquetar.
  5. /run/systemd/{sessions,seats,users} vacíos — libelogind resuelve la C-ABI
     sd-login LEYÉNDOLOS y nadie los escribe (el Announce de arje-logind-compat al
     bus del fractal falla con "identity mismatch"). gnome-start los escribe A
     MANO y está MARCADO COMO ANDAMIO. Con ese puente desaparece el "Failed to
     find any matching session".

Gotcha que costó una iteración: `kill -0` TIENE ÉXITO sobre un zombi (el padre no
lo cosechó todavía), así que el script reportaba "sin wayland-0 tras 45s" cuando
el shell había muerto en el primer segundo. Mirando State: de /proc/<pid>/status
sale el código real, 139.

Todo el ciclo (hidratar → imagen → bootear → sacar el core con debugfs → gdb) y
la lista de lo que falta quedan en docs/runbooks/gnome-qemu-desktop.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 21:47:11 -04:00
sergioandClaude Opus 5 f6734d6ce6 gnome: hydrate-gnome.sh — el cierre de runtime de la cima CIERRA 108/108
Proyecta al FHS el cierre de una receta GNOME desde artefactos SELLADOS, sin
rebuild. Resultado sobre gnome-shell: **108 recetas, 0 faltantes** — 614
binarios, 455 .so, 49 typelibs.

Diferencia con scripts/kde/hydrate-from-store.sh, y por qué importa: aquél
resuelve el cierre desde un index.json de repo y elige el artefacto por MTIME con
un CUTOFF. Eso es una heurística — si dos artefactos del mismo paquete conviven
en el store, la fecha no dice cuál corresponde a la receta VIGENTE. Acá el cierre
sale del GRAFO REAL de recetas (deps.build, resolución hermano→padre, la misma
que usa hammer) y el artefacto se elige por `hammer hash`. Cero ambigüedad, y si
falta algo el reporte dice qué receta y con qué hash lo buscaba.

Auditado además el cierre DINÁMICO del rootfs (452 ELF, 104 librerías NEEDED).
Sin resolver quedan cuatro, y sólo dos son hallazgos:

  libc.so                 359 consumidores — es el propio musl (en musl el loader
                          ES libc); lo aporta la base metal, no es hueco.
  libc.musl-x86_64.so.1   17 artefactos (nss + spidermonkey) piden ESTE soname en
                          vez de libc.so. Es la MISMA libc: los construidos con el
                          gcc/clang de Alpine emiten un soname distinto al de
                          zig-cc. No rompe si el rootfs trae los dos nombres, pero
                          es una fisura de consistencia a documentar.
  libstdc++.so.6 +        SÓLO libmozjs-128.so y js128 ⇒ **la sesión GNOME arrastra
  libgcc_s.so.1           el runtime C++ de Alpine por la cadena
                          gnome-shell → libgjs → libmozjs**. Es exactamente la
                          "última milla" de matar-gcc que se cerró para cmake con
                          -static-libstdc++ y que spidermonkey no cubrió. Radio
                          medido: 2 sellados (gjs, gnome-shell). Pendiente, y
                          conviene en el worker: el compile de mozjs come ~8GB+.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 21:06:55 -04:00