Commit Graph
1097 Commits
Author SHA1 Message Date
Sergio 7c4bd40c23 estado: cosecha granja 2026-09-12T19:34:20Z — avance del árbol KDE 2026-09-12 19:34:21 +00:00
Sergio 0949c0895d estado: cosecha granja 2026-09-12T19:01:53Z — avance del árbol KDE 2026-09-12 19:01:53 +00:00
Sergio 4744951980 estado: cosecha granja 2026-09-12T18:32:19Z — avance del árbol KDE 2026-09-12 18:32:19 +00:00
Sergio 86de78c0e5 estado: cosecha granja 2026-09-12T18:02:22Z — avance del árbol KDE 2026-09-12 18:02:22 +00:00
Sergio ab048a9ed8 estado: cosecha granja 2026-09-12T17:32:27Z — avance del árbol KDE 2026-09-12 17:32:27 +00:00
Sergio dad5e14a8e estado: cosecha granja 2026-09-12T17:02:20Z — avance del árbol KDE 2026-09-12 17:02:20 +00:00
Sergio 5a2e504a44 estado: cosecha granja 2026-09-12T16:32:21Z — avance del árbol KDE 2026-09-12 16:32:21 +00:00
Sergio e54a22d2fa estado: cosecha granja 2026-09-12T16:01:59Z — avance del árbol KDE 2026-09-12 16:01:59 +00:00
Sergio fe3d3c1d84 estado: cosecha granja 2026-09-12T15:31:52Z — avance del árbol KDE 2026-09-12 15:31:53 +00:00
Sergio da76749d22 estado: cosecha granja 2026-09-12T15:02:20Z — avance del árbol KDE 2026-09-12 15:02:20 +00:00
Sergio 0fa2083e6c estado: cosecha granja 2026-09-12T14:32:17Z — avance del árbol KDE 2026-09-12 14:32:17 +00:00
Sergio dc71b45eab estado: cosecha granja 2026-09-12T14:02:21Z — avance del árbol KDE 2026-09-12 14:02:21 +00:00
Sergio d8ce87c595 estado: cosecha granja 2026-09-12T13:32:17Z — avance del árbol KDE 2026-09-12 13:32:17 +00:00
Sergio c88b2c96de estado: cosecha granja 2026-09-12T13:02:31Z — avance del árbol KDE 2026-09-12 13:02:31 +00:00
Sergio 16c79f6b2c estado: cosecha granja 2026-09-12T12:32:16Z — avance del árbol KDE 2026-09-12 12:32:16 +00:00
Sergio b476e63156 estado: cosecha granja 2026-09-12T12:02:54Z — avance del árbol KDE 2026-09-12 12:02:54 +00:00
Sergio 1608262a9a estado: cosecha granja 2026-09-12T11:35:29Z — avance del árbol KDE 2026-09-12 11:35:29 +00:00
Sergio a4c33914e8 estado: cosecha granja 2026-09-12T11:32:19Z — avance del árbol KDE 2026-09-12 11:32:19 +00:00
Sergio d4d120a079 brotli y json-c: selladas y rotas a la vez — las dos baratas del censo, arregladas
El barrido con `verificar-repro.sh` sobre las 15 recetas CMake baratas del corpus dio
**5 que no construyen hoy**. Éstas son las dos cuyo arreglo no cuesta nada (radio 0 y 3 rebuilds).

Diagnosticada `json-c` en vez de suponerla: apartando su artefacto y reconstruyendo con la salida
capturada, muere con el mismo `Error running link command: Segmentation fault` que `dwarves` y que
los `protoc-gen-upb*` de protobuf. Un `-DCMAKE_LINK_DEPENDS_USE_LINKER=OFF` en cada una y listo — el
`lld` de zig 0.16.0 segfaultea con el `--dependency-file` que CMake ≥3.27 emite.

⚠ **Lo que importa de este commit no son las dos recetas: es que el fallo no era un caso aislado.**
Cuando apareció en protobuf lo esquivé con `compiler = "gcc"` creyendo que era cosa de esos plugins.
Ya van CINCO proyectos sin relación entre sí con el mismo crash, y otros tres medidos y pendientes.

`crun` cayó a deuda (json-c es dep suya) y se reconstruyó: sigue siendo estático con 0 NEEDED y
**vuelve a arrancar un contenedor de verdad** con el busybox del corpus como rootfs. Las tres
REPRODUCEN bit a bit.

Queda planteado con el número delante, sin arrancarlo: los otros tres del censo son
`libtiff-shared` (12 rebuilds), `libjpeg-turbo` (17) y `libjpeg-turbo-shared` (23) — ~52 en total y
tocan los stacks gráficos de los escritorios. Y el censo cubrió 15 de las 23 CMake del corpus y
NINGUNA de las ~130 de las colas: el número real de rotas es mayor que 5.
2026-09-12 11:29:01 +00:00
Sergio eb85c5976e latido: el vigía de servicios entra al cron — 18 demonios se embarcan y nadie los arranca
Contesta la pregunta que ni el grafo ni `vigia-sonames` contestan: no «¿está
sellado?» ni «¿arranca el binario?» sino **«¿hay alguien que lo LEVANTE?»**. Un
demonio puede estar sellado, con contenido, con todos sus sonames resueltos, y
que ninguna imagen lo arranque nunca.

Va al latido por la lección que `vigia-sonames` ya dejó escrita doce líneas más
arriba —un vigía que hay que acordarse de invocar no se distingue de no tenerlo—
y con más motivo: su entrada son DOS ficheros que cambian por separado (las
recetas y `targets.toml`), así que la divergencia entre «declarado» y
«habilitado» aparece sola, sin que nadie toque el vigía.

Corre PRIMERO su propio `--selftest`: si el guardián está roto, su silencio no
es una respuesta.

Primera lectura, ya en el repo: 0 errores y 18 avisos. El más ruidoso es
`dbus-system`, que viaja en SEIS perfiles y sólo GNOME lo arranca.
2026-09-12 11:13:12 +00:00
Sergio 1b56b16402 SDD 30 §4a+§4c: los 9 demonios de GNOME declarados — y aparecieron dos que no estaban en NINGÚN perfil
Lo que el script de sesión lanza con `&` ahora está declarado en las recetas y
habilitado en el perfil. Ninguna receta movió su hash: 9/9 idénticos a los que
los grafos ya registraban.

EL HALLAZGO, y no lo buscaba: la comprobación inversa del resolutor rechazó
`arje-logind-compat` y `arje-polkit-compat` porque están en CERO perfiles — y
sin embargo qemu-desktop-image.sh los copia al rootfs a mano y el de COSMIC hace
`exit 1` si falta logind-compat. Dos binarios imprescindibles, presentes en la
imagen y ausentes del destino declarado: la misma forma del agujero de `foot`,
encontrada por una comprobación en vez de por una imagen inusable. Son raíces de
escritorio-gnome (los dos) y de escritorio-cosmic (sólo logind, verificado que
sus scripts no nombran polkit).

DOS COSAS QUE NO SON TRANSCRIPCIÓN:
- `dbus-daemon --fork` no se traduce tal cual: arje supervisa al HIJO DIRECTO y
  Type=forking no existe, así que un daemon que forkea y sale deja a arje viendo
  morir al padre con éxito y reencarnándolo para siempre. La card usa --nofork.
- `scope = system|session` decide DÓNDE va la card. Las de sesión necesitan
  XDG_RUNTIME_DIR y usuario logueado; en el genesis arrancarían antes de que
  exista ninguno. Y fuera de mirada NADIE entrega cards de sesión todavía, así
  que salen con AVISO: el hueco queda contado, no omitido.

Correcciones propias: la unicidad del label es DENTRO del perfil, no del corpus
(upower vive legítimamente en dos colas); la membresía se lee de los CINCO
grafos, no sólo el del corpus; una RAÍZ manda sobre el grafo, que es derivado y
lo regenera el cron; y la flag nace en inglés (`--services`) como manda la
regla 4, aunque `--lista` sea deuda vieja del mismo fichero.

`--selftest`: 7 casos, el primero es el CONTROL que tiene que pasar en verde.
2026-09-12 11:08:58 +00:00
Sergio 35afe8260d estado: cosecha granja 2026-09-12T11:03:33Z — avance del árbol KDE 2026-09-12 11:03:33 +00:00
Sergio 556fcad5fa SDD 30 §4a: el perfil ya sabe HABILITAR — y avisa del demonio que nadie arranca
`paquetes` decía qué se INSTALA; no había dónde decir qué se LEVANTA. El sshd
del producto arrancaba porque su Card estaba escrita a mano en una constante de
Rust, no porque nadie lo hubiera declarado.

`servicios = [...]` por perfil (se hereda como `paquetes`, mismo orden y dedup)
+ `targets.py --servicios <perfil>`, que cruza label → receta → exec contra los
`[[service]]` del corpus y la membresía de perfil de build-state.json.

Lo que vale más es la comprobación INVERSA: avisa de los paquetes que están en
la imagen, TRAEN un demonio y el perfil no arranca. Es la versión servicios de
la lección de `foot` —la métrica mide la clausura de lo DECLARADO y no ve lo que
falta en la declaración— y no es hipotética: antes de escribir `servicios =
["sshd"]` el resolutor ya avisaba «openssh está en la imagen y TRAE este
servicio, pero el perfil no lo arranca».

Probado con roturas A PROPÓSITO, 5/5, y con un control que TIENE que pasar:
habilitado sin declarar (ERROR) · dos recetas con el mismo label (ERROR) · lo
declara una receta que no está en el perfil (ERROR: el card apuntaría a un
binario ausente y arje lo encarnaría con ENOENT en cada backoff) · la inversa
(AVISO, no rompe el cron) · el caso bueno (rc=0). Los 8 perfiles siguen
expandiendo igual y los llamadores de shell no cambian.
2026-09-12 10:59:59 +00:00
Sergio 432a0e2561 estado: cosecha granja 2026-09-12T10:48:45Z — avance del árbol KDE 2026-09-12 10:48:45 +00:00
Sergio c0a25cef22 protobuf/abseil vuelven a zig: la causa raíz quita el escape a gcc — y lo valida en un segundo proyecto
Ayer estas dos huyeron a `compiler = "gcc"` para esquivar un crash del linker en los tres
`protoc-gen-upb*`. **Esquivé el fallo sin conocer su causa, y salió caro:** al mover sólo protobuf, el
link murió con `undefined reference to std::__1::basic_string<…>` —el `__1` de libc++— porque abseil
seguía en zig, así que hubo que arrastrar las dos fuera del toolchain por defecto.

La causa apareció al día siguiente en `dwarves`, bisecando la línea de enlace real:

    tal cual                      → exit 139 (SIGSEGV)
    quitando `-static`            → exit 139     ⇒ no es el enlace estático
    quitando `--dependency-file`  → **exit 0**   ⇒ ES ESO

El `lld` de zig 0.16.0 segfaultea con el `--dependency-file` que CMake ≥3.27 mete en la línea de
enlace. Con `-DCMAKE_LINK_DEPENDS_USE_LINKER=OFF` **los cuatro binarios de protobuf enlazan con zig**,
incluidos los tres plugins que se caían.

Esto es, además, la validación de la causa raíz en un proyecto INDEPENDIENTE de dwarves: dos
proyectos sin relación, mismo síntoma, misma perilla, los dos arreglados.

Con el escape se va también el `-static-libstdc++`, que sólo hacía falta porque g++ enlaza contra la
libstdc++ de GNU. Comprobado sobre el artefacto: el único NEEDED de `protoc` es `libc.so`, que provee
`musl-shared`.

Verificado de punta a punta, no por el código de salida: `protoc --version` → `libprotoc 36.1`, y un
`.proto` compila a `m.pb.h`/`m.pb.cc` **y** a `p/m.pb.go` pasando por `protoc-gen-go` — o sea que la
cadena plugin↔driver que abrí anteayer sigue entera. Las dos REPRODUCEN bit a bit.

Se deja escrito el camino completo en las recetas, diagnóstico corto incluido, porque la lección no
es la perilla: es que **un escape que funciona sin explicar el fallo se paga después**, y acá se pagó
con dos recetas fuera del toolchain por defecto y un choque de runtimes de C++ que sólo apareció
porque el escape era parcial.
2026-09-12 10:46:19 +00:00
Sergio a8876c6d19 estado: cosecha granja 2026-09-12T10:33:33Z — avance del árbol KDE 2026-09-12 10:33:33 +00:00
Sergio f927d40e70 estado: cosecha granja 2026-09-12T10:01:53Z — avance del árbol KDE 2026-09-12 10:01:53 +00:00
Sergio 9332f8becc estado: cosecha granja 2026-09-12T09:31:35Z — avance del árbol KDE 2026-09-12 09:31:35 +00:00
Sergio b1774b6799 estado: cosecha granja 2026-09-12T09:01:52Z — avance del árbol KDE 2026-09-12 09:01:52 +00:00
Sergio dc5a487839 estado: cosecha granja 2026-09-12T08:31:53Z — avance del árbol KDE 2026-09-12 08:31:53 +00:00
Sergio 720d95e21f estado: cosecha granja 2026-09-12T08:02:15Z — avance del árbol KDE 2026-09-12 08:02:15 +00:00
Sergio 1c7cf6b7bc estado: cosecha granja 2026-09-12T07:31:35Z — avance del árbol KDE 2026-09-12 07:31:35 +00:00
Sergio 3462b0c78e estado: cosecha granja 2026-09-12T07:01:55Z — avance del árbol KDE 2026-09-12 07:01:55 +00:00
Sergio 4cc8ad94c0 estado: cosecha granja 2026-09-12T06:31:36Z — avance del árbol KDE 2026-09-12 06:31:36 +00:00
Sergio e9b71b5c7b estado: cosecha granja 2026-09-12T06:01:54Z — avance del árbol KDE 2026-09-12 06:01:54 +00:00
Sergio 95fc099e36 estado: cosecha granja 2026-09-12T05:31:58Z — avance del árbol KDE 2026-09-12 05:31:58 +00:00
Sergio ff4c23a858 estado: firefox-pgo-profile verificada — el arreglo del mirror destraba las tres recetas de URL .invalid 2026-09-12 05:05:23 +00:00
Sergio 76fc142244 verificar-repro: activar el mirror — el veredicto dependía de la suerte del caché
Medido hoy: `ia-modelo-embeddings` dio REPRODUCE y `ia-modelo-chat` «no construyó», y la ÚNICA
diferencia entre las dos era que el tar de la primera seguía en `work/tarballs` y el de la segunda lo
había borrado yo liberando disco. Sin caché, el build sale a buscar la fuente a una URL `.invalid`
—que es lo que el ADR 0013 pone a propósito cuando el objeto vive sólo en nuestro mirror— y muere con
`Could not resolve host`.

O sea que el gate informaba «no construyó» para `firefox-pgo-profile` y los dos modelos de IA según
qué hubiera en el caché local. Un guardián cuyo veredicto depende de eso no es un guardián.

Ahora hace `source` de `scripts/fuentes/mirror-env.sh` si existe. Aditivo, como manda el ADR 0013: si
el fichero no está, todo sigue igual que antes.

Con eso, ia-modelo-chat: REPRODUCE.
2026-09-12 05:04:43 +00:00
Sergio b5924e6db9 estado: cosecha granja 2026-09-12T05:03:03Z — avance del árbol KDE 2026-09-12 05:03:03 +00:00
Sergio 0b9055f52a estado: ia-modelo-embeddings verificada — REPRODUCE (cuantización y copia deterministas) 2026-09-12 05:02:06 +00:00
Sergio 74b1a0580c estado: cosecha granja 2026-09-12T04:33:25Z — avance del árbol KDE 2026-09-12 04:33:25 +00:00
Sergio 097579546f dwarves: el linker de zig se caía con --dependency-file — una línea, y sin escapar a gcc
`dwarves` estaba SELLADA y llevaba tiempo sin construir. Se destapó al arreglar los symlinks de
`bzip2`: su hash se movió, dwarves cayó a deuda, y al reconstruirla el link murió con
`Error running link command: Segmentation fault` — crash del linker, no error de símbolos.

**No lo rompió el cambio de bzip2, y se puede probar**: el `libbz2.a` y el `bzlib.h` nuevos son
byte-idénticos a los viejos (`cmp -s`); lo único que cambió fueron cuatro destinos de symlink. El
artefacto sellado tapaba una rotura que ya existía — el lab rueda desde Alpine edge y zig subió. El
rehash no causó la rotura: la DESTAPÓ.

## La causa, bisecada sobre la línea de enlace real

CMake deja la línea literal en `build/CMakeFiles/<target>.dir/link.txt`, y el árbol de post-mortem la
conserva. Rehecha a mano FUERA de takana y del sandbox, sustituyendo el wrapper por el `zig` del lab
y las rutas `/usr/lib/*` por las del store:

    tal cual                      → exit 139 (SIGSEGV)
    quitando `-static`            → exit 139     ⇒ no es el enlace estático
    quitando `--dependency-file`  → **exit 0**   ⇒ ES ESO

`-Xlinker --dependency-file=…` lo emite CMake ≥3.27 para que el LINKER calcule las dependencias de
enlace, y el `lld` de zig 0.16.0 segfaultea procesándolo. `-DCMAKE_LINK_DEPENDS_USE_LINKER=OFF` es la
palanca de upstream (cmake del corpus: 3.31.6).

**Es mejor que `compiler = "gcc"`**, que es como esquivé ayer el MISMO crash en los tres
`protoc-gen-upb*` de protobuf sin conocer la causa: deja la receta en el toolchain por defecto del
proyecto en vez de escapar de él.

⚠ **Y el alcance no son dos recetas: 153 del corpus usan CMake con zig.** Todas selladas, así que hoy
nadie lo ve — pero el crash depende de los inputs (dentro de protobuf caían 3 de ~10 ejecutables), o
sea que no se sabe cuáles fallan hasta que su hash se mueva. Deuda latente pura.

No se arregla poniendo la perilla en el lab: la mayoría de esas 153 traen su `cmake …` EXPLÍCITO en
la receta, así que tocar la fase por defecto no las tocaría **y** re-hashearía a las que sí usan la
heurística. Incompleto y disruptivo a la vez.

Verificado: los 10 ejecutables estáticos con 0 NEEDED —incluidos `codiff` y `dtagnames`, los dos que
segfaulteaban—, `pahole --version` → v1.30, y REPRODUCE bit a bit.
2026-09-12 04:13:53 +00:00
Sergio 86cec38e36 estado: cosecha granja 2026-09-12T04:02:29Z — avance del árbol KDE 2026-09-12 04:02:29 +00:00
Sergio d515ea9fc7 estado: cosecha granja 2026-09-12T03:33:22Z — avance del árbol KDE 2026-09-12 03:33:22 +00:00
Sergio 53de4e259a estado: cosecha granja 2026-09-12T03:03:23Z — avance del árbol KDE 2026-09-12 03:03:23 +00:00
Sergio 6f482edd65 estado: cosecha granja 2026-09-12T02:34:52Z — avance del árbol KDE 2026-09-12 02:34:52 +00:00
Sergio 5f2f502008 estado: cosecha granja 2026-09-12T02:03:24Z — avance del árbol KDE 2026-09-12 02:03:24 +00:00
Sergio 30d6f5e9f3 estado: cosecha granja 2026-09-12T01:33:21Z — avance del árbol KDE 2026-09-12 01:33:21 +00:00
Sergio f22beb1b35 estado: cosecha granja 2026-09-12T01:03:10Z — avance del árbol KDE 2026-09-12 01:03:10 +00:00
Sergio 13ce9b16f1 targets: la IA local entra en las CUATRO imágenes de escritorio
Decisión del usuario (2026-09-12): `llama-cpp` + `ia-modelo-chat` de raíz en escritorio-gnome, -kde,
-cosmic y -sway. El motivo es que el panel de la barra lateral está en las cuatro —viene con `atuq`—
y una función del navegador que sólo existe en una imagen es una trampa: en las otras el usuario ve
el panel y lee «esta imagen no trae modelo».

Cuesta ~1,25 GiB por imagen (199 M el motor + 1,04 GiB el modelo) y está escrito en el comentario,
al lado de las líneas, para que bajarlo sea una decisión y no un descuido.

Verificado como manda la lección de `foot` que este fichero ya aprendió: las dos raíces expanden en
los cuatro perfiles (`scripts/targets.py`), las dos están SELLADAS al hash vigente, y el grafo las
ve con sus cuatro perfiles encima — una raíz que no resuelve quedaría `wanted` y ninguna métrica lo
diría. El grafo CIERRA y el topo-sort sigue OK.
2026-09-12 00:49:47 +00:00