Commit Graph
442 Commits
Author SHA1 Message Date
sergioandClaude Opus 5 deee75eca5 docs: SDD 20 — los WMs ligeros pasan a HECHO, y la lección de que «sellado ≠ arranca»
§II.1 decía «medido: no hay ninguno — de toda la familia sólo existen foot y mako». Ya no: 10
recetas selladas, 12 binarios, el perfil escritorio-sway cerrando 121/121 y ARRANCANDO en QEMU
con evidencia. La hipótesis que traía la sección —«son baratos, no hay torre de C debajo»— se
cumplió: KDE y GNOME fueron campañas de semanas, esto salió en una noche.

Y se añade la lección que corrige cómo hay que leer TODO el documento: el grafo prueba que una
imagen SE ARMA, no que ARRANQUE. Entre 121/121 y una pantalla con algo dibujado hubo SEIS
muros y ocho ciclos de imagen —PATH vacío, libz.so.1 ausente del rootfs, un backend de libseat
que nuestra receta no construye, /run de sólo lectura, los datos XKB, y la falta de
tipografías— y ninguno era una dependencia de build, así que ninguno podía salir en el grafo.

Con el método incluido, porque es lo que más se olvida: el veredicto es CONTAR COLORES del
PPM, no leer el log. Hubo un arranque con todo verde (salida activada, modo correcto, «Commit
of 1 outputs succeeded», workspace creado) y la captura 100% negra.

⇒ Corolario escrito en una sección nueva: cuando este documento diga que algo «cierra», hay que
leerlo como «se puede intentar», no como «funciona». Los tres escritorios que aún no se
validaron con pantalla deben esa misma distancia, y no conviene prometer fechas contra el
número del grafo.

waybar queda anotado como fuera-por-medición (gtkmm-3.0 = GTK3 + bindings C++ + 8 recetas), con
yambar en su lugar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 23:01:11 -04:00
sergioandClaude Opus 5 e3403ff20e sway ARRANCA EN QEMU con pantalla — evidencia, y seis muros que el grafo no podía ver
`docs/evidencia/sway-qemu-2026-08-08.png`: 1280×800, **102 colores distintos**, sway con foot a
pantalla completa y un prompt vivo, la barra de título del compositor arriba y el fondo
#1a4b8c asomando en los bordes. Sobre el kernel de hammer con arje-zero como PID1, sin X11 y
sin systemd.

EL VEREDICTO ES CONTAR COLORES, NO LEER EL LOG — y esta campaña lo demuestra sola: hubo un
arranque con TODO verde en el log (salida activada, modo 1280x800, «Commit of 1 outputs
succeeded», workspace creado) y la captura salía **100% negra**. Un compositor puede estar
perfectamente vivo y no pintar nada.

LOS SEIS MUROS, ninguno visible en un grafo de dependencias que decía 121/121:

1. `PATH` vacío — el console-getty no lo exporta y ni `mkdir` se encontraba. «mkdir: not found»
   se lee como «falta busybox» cuando busybox está entero: mismo engaño que el exit 127 de meson.
2. `libz.so.1` AUSENTE del rootfs. El zlib del corpus es sólo estático; la compartida vive en
   `zlib-shared`, en otra cola. Se cazó comparando los NEEDED del ELF contra el rootfs, no
   leyendo logs.
3. `LIBSEAT_BACKEND=builtin` NO EXISTE en nuestro libseat: `recipes/seatd.toml` construye con
   `-Dlibseat-seatd=enabled -Dlibseat-logind=disabled`, o sea UN backend, confirmado con
   `strings`. La receta manda sobre lo que uno cree recordar del proyecto — y la misma receta
   traía la salida: `-Dserver=enabled` construye `seatd-launch`.
4. `/run` de SÓLO LECTURA. La raíz de hammer es inmutable por diseño, y sway moría con «unable
   to open lockfile … check permissions», que suena a permisos de directorio y era un
   filesystem read-only. Se resolvió montando un tmpfs, que es lo que hace cualquier init.
5. `xkeyboard-config` — «failed to add default include path /usr/share/X11/xkb». Es EXACTAMENTE
   lo que dejé anotado en la receta de swaylock: «para que el teclado tenga distribución en una
   imagen real hará falta incluirlo por el lado del perfil». Apareció donde se dijo.
6. SIN TIPOGRAFÍAS no hay terminal. `fcft: failed to match font` → `failed to load primary
   fonts`: foot arrancaba y no dibujaba. `dejavu-fonts` estaba en el catálogo pero en otra cola.
   Va en la lista de §I.5 del SDD 20 («tipografías») y acá se ve por qué no es un detalle.

Y un fallo de MÉTODO que costó dos ciclos: mandé el log de sway a /var/log/sway.log DENTRO de
la VM, así que la primera captura negra vino sin una sola línea que la explicara — el
diagnóstico estaba dentro de la caja que no arranca. Un log que no se puede leer desde fuera no
es un log. Ahora va al serial.

Los `exec` de la config de sway disparan ANTES de que exista el workspace (0,259 s vs 0,305 s)
y mueren con «Failed to create launch context. No workspace». Los clientes se lanzan desde
sway-start esperando el socket de Wayland, que es la condición real.

Andamiaje reutilizable en scripts/wlr/: qemu-sway-image.sh (hermano del de COSMIC, sin logind
ni dbus, que sway no necesita), sway-start.sh y sway-config.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 22:38:51 -04:00
sergio 8325a706b2 estado: cosecha granja 2026-08-08T02:14:09Z — avance del árbol KDE 2026-08-07 22:14:09 -04:00
sergioandClaude Opus 5 55dd36d97a perfil escritorio-sway: 121/121 CERRADO — la cuarta imagen de escritorio, y la más barata
Declarado en targets.toml y verificado con el grafo: **121 nodos, 121 sellados, falta 0**. Es
una imagen construible hoy, no una intención.

Nueve raíces (sway, yambar, fuzzel, swaybg, swaylock, swayidle, grim, slurp, wl-clipboard) más
`hereda = ["cli"]`, porque un WM sin userland debajo no se usa: hacen falta la terminal y las
herramientas. `foot` no se lista porque ya entra por la clausura de `cli`. El resto de la
imagen —wlroots, mesa, wayland, libinput, seatd, cairo, pango, fcft…— lo calcula el grafo
siguiendo las aristas: escribir la clausura a mano es justo lo que targets.toml existe para
evitar.

LA COMPARACIÓN QUE VALE: KDE y GNOME fueron campañas de semanas porque debajo tienen una torre
de C (Qt entero, GTK, la cascada de mesa). Esto es una decena de binarios pequeños sobre
wlroots y salió en una noche. Ya estaba escrito en el SDD 20 como hipótesis —«los WMs ligeros
son la mejor relación esfuerzo/resultado que queda»—; ahora está medido.

`--wlr` en build-state.py, con su flag propio por la misma razón que COSMIC: sin él el frente
es INVISIBLE para el khipu, y `yupana radio` sobre una receta compartida (wayland, libinput,
pixman, mesa, libxkbcommon…) no reportaría la imagen sway entre las afectadas — o sea que el
próximo que toque una de ésas mediría de menos y creería que no rompe nada.

Queda lo que no puede decidir el grafo: probarlo en QEMU CON PANTALLA. La regla ya pagada cara
es que las imágenes de escritorio no se validan con `-nographic`, porque el compositor puede
«arrancar» en los logs y no pintar nada.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 22:01:24 -04:00
sergio dd8baa7560 estado: cosecha granja 2026-08-08T01:43:22Z — avance del árbol KDE 2026-08-07 21:43:22 -04:00
sergio 142a8774a6 estado: cosecha granja 2026-08-08T01:12:13Z — avance del árbol KDE 2026-08-07 21:12:13 -04:00
sergio a287091d2a estado: cosecha granja 2026-08-08T00:40:56Z — avance del árbol KDE 2026-08-07 20:40:56 -04:00
sergio bca7164b4e estado: cosecha granja 2026-08-07T22:36:14Z — avance del árbol KDE 2026-08-07 18:36:14 -04:00
sergioandClaude Opus 5 4f265a316f docs: SDD 22 — respuesta verificada al handoff de kernel-config de tawasuyu
El handoff avisa que nada suyo está verificado contra hammer («si un dato de hammer lo
contradice, manda hammer»). Esto es esa verificación: contesta sus seis preguntas del §9 con
evidencia del código, corrige lo que estaba mal y añade dos objeciones que cambian el orden.
NO es aprobación ni plan de implementación.

EL HECHO QUE REORDENA TODO, y que el handoff no podía conocer: las FASES entran en
hash_inputs, y el config del kernel vive en la fase `configure` ⇒ **el config ES la identidad
del artefacto**. Corta en los dos sentidos. A favor: §2.2 (atestar un config por huella de
hardware) sale casi gratis, porque cada config ya es un artefacto direccionado por contenido,
reproducible y firmable — no hay que inventar el mecanismo. En contra: la explosión de builds
no es hipotética, es aritmética visible en el disco, que ya crece 24 G por ciclo. Y una
«perilla» de la UI no es un parámetro de runtime: es una edición de receta.

LAS SEIS RESPUESTAS:
 P1 fragmentos — YA es como §6 prescribe: defconfig + `scripts/config -e/-d` + olddefconfig,
    o sea que la app nunca escribe un .config. Media implementación está en producción. Falta
    el diff-back, sin el cual un símbolo pedido que no sobrevive se pierde EN SILENCIO.
 P2 repro con config variable — sí, por construcción: no hay un kernel cuya reproducibilidad
    dependa de congelar el config; hay N kernels, cada uno congelado. Se pueden PREFIRMAR
    artefactos, no sólo configs.
 P3 tiempo — 35/45/60 min según receta ⇒ la bisección de §5 son ~4,5 h de la máquina que
    acaba de no arrancar. Mata la bisección ingenua.
 P4 harkaq — el patrón sí, el código no: su clausura enumera fichero a fichero sobre
    artefactos del store, semántica de rutas. Kconfig es otro grafo.
 P5 eje huella en el índice — sí y compatible hacia atrás: PackageEntry usa campos serde
    opcionales. Mismo truco que hizo pagable el campo `license` hoy.
 P6 PLAN-KIKIN §4.bis — DADO POR PENDIENTE Y ESTÁ HECHO EN DOS DE TRES: linux-metal y
    linux-generic ya declaran los cuatro símbolos; sólo `linux` deja IO_URING y BPF_SYSCALL
    al azar del defconfig. Y ojo al método: `grep IO_URING` da positivo por un COMENTARIO;
    hay que mirar los -e/-d dentro del bloque configure. Mismo error que infló el conteo de
    licencias hoy y que hace mentir la regla del `.a` no-PIC.

OBJECIÓN a §2.1: «clausura» sobre Kconfig no está definida todavía. Hay tres tipos de arista
(`depends on`, `select`, `imply`) con semánticas incompatibles, y `select` fuerza símbolos
IGNORANDO los `depends on` del destino. «Alcanzable desde CONFIG_WIRELESS» da conjuntos
distintos según la arista y ninguno es la respuesta. No lo invalida: lo convierte en la parte
con contenido técnico real. Y hay con qué validarlo GRATIS: el config actual de linux.toml
YA es un juego de bundles N1 hecho a mano («-d WLAN -d WIRELESS -d CFG80211 -d MAC80211
-d RFKILL» es literalmente «no necesito wifi») sobre un kernel que arranca.

LO QUE AGREGO:
 · Bisección SIN recompilar: kernel «superset» con lo bisecable como módulo ⇒ los bundles de
   hardware se prueban con lista de bloqueo en la línea de arranque. 6 reinicios en vez de 6
   rebuilds. No cubre lo que debe ser =y (buena parte de N2), y el superset es el kernel gordo
   que N1 quiere evitar: es diagnóstico, no el de todos los días.
 · El gate de no-regresión debe ser POR OBJETIVO: linux.toml apaga USB/HID/INPUT a propósito
   (es el kernel de QEMU con consola serie) y un gate global rechazaría una receta sana.
 · «Booteó» no basta para atestar: un kernel arranca y te deja sin red, que es el desastre que
   el propio gate quiere evitar. La atestación debe llevar QUÉ se comprobó — el mismo dato que
   calcula el gate: una implementación, dos usos.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 15:54:18 -04:00
sergioandClaude Opus 5 2c2ee951d6 licencias: resolver -only vs -or-later CON LA CITA — y tres «pruebas» que no probaban nada
Los identificadores obsoletos (`GPL-2.0`, `LGPL-2.1`, `AGPL-3.0`) no dicen si el proyecto
concede «sólo esta versión» o «ésta o cualquier posterior», y eso decide con qué se puede
combinar el paquete y bajo qué términos puede redistribuirlo quien lo reciba.

NO SE PUEDE MIRAR EL COPYING, que es la trampa evidente: el texto de la GPL es IDÉNTICO en
los dos casos —es la licencia, no la concesión— y encima su apéndice «cómo aplicar la
licencia» contiene literalmente «or (at your option) any later version», así que buscarla
ahí da SIEMPRE positivo y parece evidencia siendo plantilla. Misma trampa que la regla del
`.a` no-PIC, donde grep contaba reubicaciones de `.debug_*`. La concesión vive en las
cabeceras de los fuentes y en el README; ahí se busca, excluyendo los ficheros de licencia.

SE GUARDA LA CITA, no sólo el veredicto: fichero + frase exacta que decidió. Una licencia es
una afirmación legal y quien la revise tiene que poder ver POR QUÉ dice lo que dice sin
repetir el trabajo.

Y eso pagó de inmediato: de las 12 primeras resoluciones, TRES eran evidencia inválida y
sólo se vieron porque estaba la cita. Cada una de una clase distinta:
 · caligula   — la frase salía de `checks/headless/expected.iso`, un FIXTURE DE TEST;
 · libnl      — de `include/linux-private/linux/seg6.h`, una cabecera del KERNEL vendorizada.
                La licencia del kernel no es la de libnl;
 · lm-sensors — declarado GPL-2.0 y la cita decía «version 2.1 of the License», que es la
                LGPL. La frase era real pero no sostenía lo que se le atribuía.

Las tres clases quedan filtradas en el script: ficheros de licencia, rutas de test/fixture, y
código vendorizado; más una comprobación nueva de que **la cita hable de la misma versión que
la licencia declarada**.

Sembradas las 9 auditadas (13 ficheros; algunas viven en varias colas). Ambiguas: 55 → 41.
Las 40 sin evidencia quedan listadas y siguen contadas — la mayoría son Go y la familia
cosmic, donde la frase no aparece fuera del COPYING.

Hashes verificados: 0 movidos.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 15:15:20 -04:00
sergioandClaude Opus 5 97eb1d4af2 docs: SDD 20 — limpiar el empalme de la sección de licencias
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 14:54:22 -04:00
sergioandClaude Opus 5 78ad2e8201 docs: SDD 20 — corregido dónde va el texto de licencia (imágenes, no pack) y estado real 1063/1141
El catálogo decía que el texto de la licencia se inyecta en `hammer pack`. El razonamiento
del coste era correcto pero el sitio estaba mal: pack emite un .swm (receta sobre fuente
pública, sin binarios) e install reproduce construyendo, así que el canal de paquetes no
distribuye binarios. El punto de entrega es la IMAGEN, y ahí está hecho, con veto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 14:53:54 -04:00
sergioandClaude Opus 5 be4e91086c licencias: el texto dentro de la imagen, con veto — y el SDD 19/20 se equivocaba de sitio
═══ LA CORRECCIÓN DE FONDO: no es `pack`, son las IMÁGENES ═══
El SDD 19 y el 20 decían «inyectar el texto de la licencia en `hammer pack`, que es aguas
abajo del ArtifactHash y sale gratis». La conclusión sobre el coste era correcta pero el
SITIO estaba mal, y por una razón que sólo se ve leyendo el código: `pack` produce un
`.swm`, que es una RECETA DE TRANSFORMACIÓN sobre fuente pública y por diseño explícito
«NUNCA transporta binarios cocidos»; e `install` REPRODUCE construyendo, con cache-hit del
corpus, en vez de bajar binarios. O sea que **el canal de paquetes de hammer no distribuye
binarios** y la obligación de acompañar-el-binario ahí casi no aplica.

Donde sí aplica, con toda su fuerza, es en la IMAGEN INSTALABLE: su rootfs se puebla con
`hammer install` sobre un prefix y de ahí sale un USB/ISO lleno de binarios que se le da a
alguien. Ése es el punto de entrega. (La obligación del espejo de FUENTES es otra y sigue
entera: las recetas apuntan a URLs de terceros que se caen.)

═══ LO QUE ENTRA ═══
· `scripts/licencias-textos.sh` + `licenses/`: los 44 textos CANÓNICOS de SPDX
  (spdx/license-list-data), uno por identificador realmente en uso — la lista se saca de las
  recetas, no de un fichero escrito a mano que se desincroniza. 764K.
· `scripts/licencias-rootfs.sh`: escribe /usr/share/licenses/<pkg>/ con el texto de CADA
  licencia de la expresión (`Unlicense OR MIT` ⇒ los DOS textos: en un OR el destinatario
  elige, y entregar uno solo le quita una opción que el autor le concedió), más un
  MANIFEST.tsv. Medido: 1,0 MB para el perfil `cli` de 44 paquetes.

═══ Y SOBRE TODO: ES UN VETO ═══
Sale ≠0 si algún paquete del rootfs no declara licencia. Un informe que no puede bloquear no
cambia lo que ocurre; esto corta el paso. Y se ganó el sueldo al primer intento: reveló que
los perfiles `base` y `cli` —los dos más simples, los que primero se publicarían— llevaban
10 y 12 paquetes con binarios y licencia desconocida. Curados los 10 que se podían afirmar
(doas, iputils, less, mandoc, procps-ng, rsync, strace, sudo, tree, usbutils); ambos perfiles
bajan a 2.

Esos 2 NO se rellenan a propósito, y quedan vetando:
 · lsof   — licencia propia del proyecto, sin identificador SPDX. Toca `LicenseRef-lsof` con
            su texto, que ya viaja en el tarball (la receta instala su COPYING).
 · tzdata — dominio público por declaración de sus autores, y SPDX no tiene identificador
            para eso (es una AUSENCIA de licencia, no una licencia). Toca
            `LicenseRef-PublicDomain` documentado, no forzar uno de la lista.

De paso: normalizado `GPL-3.0+` (sufijo antiguo) a `GPL-3.0-or-later`, misma equivalencia
documentada que la barra de Cargo. Y el caso especial que puse para `Linux-syscall-note`
(«las excepciones viven en exceptions/») era una suposición razonable y FALSA: SPDX las
publica en el mismo `text/`; ese directorio no existe.

1063 de 1141 (93%). Hashes verificados: 0 movidos.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 14:53:20 -04:00
sergioandClaude Opus 5 487e155f74 licencias: leer el LICENSE de verdad cuando GitHub dice «no sé» — 1053 de 1141 (92%)
Último recurso mecánico, `scripts/licencias-texto.sh`: para las 60 recetas donde la API de
GitHub devuelve NOASSERTION (el repo TIENE un LICENSE pero licensee no lo reconoce: texto
retocado, encabezado propio, dos licencias en un fichero), baja el texto y lo clasifica acá.
34 identificadas — 16 MIT, 10 Apache-2.0, 7 BSD-2-Clause, 1 BSD-3-Clause.

SÓLO PERMISIVAS, Y NO ES PEREZA. MIT, Apache-2.0, BSD, ISC, MPL-2.0 y Unlicense se
reconocen por frases inconfundibles y NO tienen variantes -only/-or-later ⇒ reconocer el
texto da el SPDX completo.

La familia GPL se deja al humano A PROPÓSITO, y la razón es sutil: el COPYING de la GPL es
IDÉNTICO tanto si el proyecto es «sólo v3» como «v3 o posterior» — lo que las distingue vive
en las cabeceras de los fuentes. Y encima el propio COPYING incluye, en su apéndice «cómo
aplicar la licencia», la frase «or (at your option) any later version», así que buscarla da
SIEMPRE positivo y parecería evidencia siendo texto de plantilla. Es exactamente la trampa
de la regla del `.a` no-PIC, donde grep contaba reubicaciones de .debug_* y mentía.

Comprobado a mano un caso que daba mala espina: el LICENSE de `conftest` empieza
«Conftest — Write tests against your config files / Copyright (C) 2019 …», que es el formato
típico de una cabecera GPL. Leído entero, dice «Licensed under the Apache License, Version
2.0». La clasificación era correcta; la sospecha, barata.

Hashes verificados sobre las 36 tocadas: idénticos.

Quedan 88, ya sin vía mecánica: los repos donde ni la API ni el texto deciden, la familia
GPL sin desambiguar, y tarballs de sitios propios (gmplib, xiph, sr.ht, codeberg…).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 14:06:59 -04:00
sergioandClaude Opus 5 0225aa4e08 licencias: el código propio (tawasuyu) queda en MIT — 1017 de 1141 (89%)
Decisión del usuario: «tawasuyu está en MIT». Es la misma licencia que hammer (LICENSE en
la raíz + Cargo.toml), así que todo lo nuestro queda coherente bajo un solo término. Las 20
recetas con fuente en git.tawasuyu.net: arje-* (el init y sus compat), mirada-* (el
compositor, el greeter y mirada-ctl), netup, agora-cli, cosmos-cli, dominium-cli,
tinkuy-sim, llimphi-counter y libelogind.

⚠ ANOTADO EN LA TABLA porque es una trampa que casi pisé: `libelogind` NO es el elogind de
upstream (que sería LGPL-2.1+). Por el nombre lo parece; su cabecera dice que es una
reimplementación PROPIA de la C-ABI sd-login dentro de arje-compat. Declararla LGPL «porque
se llama así» habría sido exactamente el error que este fichero prohíbe — el tercero del
mismo tipo hoy, después de `knighttime` (parecía Go y es KDE) y de la familia `kube*`
(parecen KDE y son Go). El nombre nunca es evidencia; la fuente sí.

Hashes verificados sobre las 20: idénticos.

Quedan 124 sin declarar, ya todas de terceros.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 14:01:15 -04:00
sergioandClaude Opus 5 c8d1357f06 licencias: la declaración del autor manda — y arreglo 5 recetas que ROMPÍ y commiteé
Dos cosas: una mejora de calidad y un fallo mío que hay que contar entero.

═══ EL FALLO: escribí un error JSON dentro de 5 recetas y las commiteé rotas ═══
En `a6a9d59`, cinco recetas quedaron con
    license = "{"message":"Not Found","documentation_url":"...","status":"404"}"
Causa: cuando el repo da 404 (renombrado, borrado, privado), `gh api` escribe el CUERPO DEL
ERROR en stdout y el filtro `--jq` falla, así que la variable queda valiendo el JSON. Mi
`case` sólo descartaba ""/null/NOASSERTION/other ⇒ el JSON pasó como si fuera una licencia.
Las comillas ROMPEN el TOML, y esas 5 recetas dejaron de parsear y de tener ArtifactHash.

No lo vio nadie leyendo: lo cazó la comparación de hashes, al detectar que `cargo-sort`
había cambiado. Afectadas: cargo-sort, cargo-audit, cargo-binstall, waybackurls, usbutils.

La lección no es «se me pasó un caso», es que **validé los «no sé» conocidos en vez de la
FORMA del dato**. Ahora se acepta sólo lo que tiene forma de expresión SPDX, y la barrera
está en los DOS sitios que escriben (detectar y sembrar), más un GUARDIÁN en el informe que
sale ≠0 si alguna licencia tiene forma imposible. Un fallo aguas arriba disfrazado de dato
hay que verlo sin buscarlo.

Y de paso normalizadas 11 licencias con la barra antigua de Cargo (`MIT/Apache-2.0`), que
no es SPDX válido. Traducir la barra a OR no es inferir: Cargo documentó esa equivalencia.

═══ LA MEJORA: `scripts/licencias-cargo.sh` ═══
Lee la licencia que el AUTOR declara en su Cargo.toml, pidiéndola AL TAG QUE LA RECETA
PINEA (`?ref=v<version>`, con HEAD como último recurso y anotando cuál se usó). 176
obtenidas, 167 al tag exacto. Es la fuente más autoritativa de las que usamos y corrige los
dos defectos de la detección por API de una vez:
 · las licencias DOBLES dejan de colapsar: `fd` pasa de `Apache-2.0` a `MIT OR Apache-2.0`,
   `ripgrep` a `Unlicense OR MIT`, `bat` a `MIT OR Apache-2.0`;
 · los SPDX AMBIGUOS caen de 71 a 55, porque el autor sí escribe -only/-or-later.
66 corregidas, 7 nuevas. Y aparecieron cosas que la detección había perdido: `eza` es
EUPL-1.2, una copyleft europea que se habría empaquetado creyendo otra cosa.

Jerarquía de evidencia, escrita en la cabecera del script: nombre (prohibido) < familia/URL
de fuente < API de licencias de GitHub < Cargo.toml del autor.

997 de 1141 (87%). Verificación COMPLETA sobre las 77 recetas tocadas —no una muestra—:
0 hashes cambiados, y 5 que ahora parsean y en HEAD no.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:51:09 -04:00
sergioandClaude Opus 5 fe474dab63 licencias: 994 de 1141 (87%) — cerradas las familias Qt, freedesktop, kernel.org y PyPI
Tercera tanda curada, agrupada por la URL DE FUENTE de cada receta (que es la evidencia que
el nombre no da): los once módulos Qt sin prefijo, freedesktop (dbus, libinput, libevdev,
libdisplay-info, poppler, pulseaudio, upower, NetworkManager, ModemManager, polkit),
kernel.org (los tres kernels, linux-headers, git, iproute2, libuuid) y PyPI.

Los kernels llevan `GPL-2.0-only WITH Linux-syscall-note` explícita. No es adorno: sin esa
excepción, todo binario de espacio de usuario que hace un syscall sería obra derivada del
kernel. Es exactamente el tipo de dato que un campo de licencia existe para no perder.

Quedan 147 sin declarar: 69 de GitHub donde la propia API dice NOASSERTION (hay que abrir
el fuente), 20 de tawasuyu —que son nuestras o del otro agente, así que la licencia la
decide el usuario, no yo— y el resto repartido en GNOME, gitlab.freedesktop y sueltos.
Más 71 con SPDX ambiguo pendientes de desambiguar (`licencias.sh --revisar`).

Hashes verificados otra vez sobre 20 recetas tocadas: 20 idénticos, 0 cambiados.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:29:31 -04:00
sergioandClaude Opus 5 a6a9d59e4f licencias: 936 de 1141 (82%) — detección por evidencia, con sus dos imprecisiones declaradas
Esta mañana eran 0. Tras la tabla curada (228) y este paso, 936. Ninguna receta se
re-hasheó: verificado en 30 de las 708 tocadas, 30 hashes idénticos, 0 cambiados.

DE DÓNDE SALE EL DATO, Y POR QUÉ NO ES ADIVINAR. `scripts/licencias-detectar.sh` consulta
la API /repos/{o}/{r}/license de GitHub para las 673 recetas cuya fuente vive allí. Eso
devuelve el resultado de DETECTAR el fichero LICENSE que el repo tiene de verdad
(licensee), no una etiqueta escrita a mano en una web: es la misma evidencia que veríamos
abriendo el tarball, obtenida sin bajar 673 tarballs por un enlace de 8 Mbps. 610 con SPDX
definido; las 63 que GitHub marca NOASSERTION/other se DESCARTAN — un «no sé» de la fuente
se propaga como hueco, no se redondea a una licencia plausible.

Las familias no-GitHub van curadas por la URL DE FUENTE, que es la evidencia que el nombre
no da. Y ahí cometí el error simétrico al que este mismo fichero advertía: había puesto
`knighttime` entre las «herramientas Go» POR SU NOMBRE, y su tarball sale de
download.kde.org — es un Framework de KDE, LGPL. Descartar por nombre falla igual que
aceptar por nombre. Corregido en la cabecera.

LAS DOS IMPRECISIONES, contables con `licencias.sh --revisar` en vez de escondidas:

 1. SPDX OBSOLETOS Y AMBIGUOS (71 recetas). GitHub devuelve `GPL-3.0`, `LGPL-2.1`,
    `AGPL-3.0`… identificadores que SPDX declaró obsoletos PRECISAMENTE porque no
    distinguen `-only` de `-or-later`, y esa diferencia decide con qué se puede combinar el
    paquete. NO se normalizan a ciegas: mapear GPL-3.0 → GPL-3.0-or-later sería inventar el
    dato que falta. Quedan marcadas para resolver mirando el fuente.

 2. LICENCIAS DOBLES COLAPSADAS. La API devuelve UNA sola licencia y muchos proyectos Rust
    son «MIT OR Apache-2.0» (p.ej. `fd` quedó como Apache-2.0). No es falso —cumplir una de
    las opciones concedidas basta— pero es incompleto. Lo resuelve el cierre estructural:
    leer el campo `license` del Cargo.toml en la fase de fetch.

Y un fallo que habría escrito basura en silencio: `licencias-detectadas.tsv` tiene TRES
columnas (añade el owner/repo consultado, para poder auditar) y el sembrador leía dos, así
que la licencia se habría llevado pegado el slug — `license = "MIT<TAB>owner/repo"`, sin
que nada lo validara. Arreglado antes de sembrar.

Quedan 205 sin licencia y 71 por desambiguar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:26:22 -04:00
sergio 6060b9bbcd estado: cosecha granja 2026-08-07T16:49:23Z — avance del árbol KDE 2026-08-07 12:49:23 -04:00
sergioandClaude Opus 5 7b2489a03c deuda del corpus: las 12 no eran un problema, eran cuatro — medido en el worker
Fui a destrabar «las 12 recetas en deuda» con el diagnóstico heredado (fallan por el rootfs
del worker: python OSError en meson, find_package en cmake). Lo probé construyéndolas de
verdad y **el diagnóstico es falso**: cmake y meson corren perfectamente ahí. Son cuatro
situaciones distintas y ninguna es el rootfs.

(a) SEIS ESTÁN SUPERADAS, NO EN DEUDA. `gtk4` del corpus es link=static y enlaza
    libfontconfig.a, que tiene 1122 reubicaciones no-PIC ⇒ 13.032 errores
    `R_X86_64_64 cannot be used against local symbol`. No es una receta rota: es imposible.
    Y mientras tanto recipes/incoming-gnome/gtk4.toml (link=dynamic, deps -shared) YA ESTÁ
    SELLADA, con libadwaita y fontconfig-shared. O sea que la cadena estática del corpus
    —gtk4, libadwaita, gtksourceview y los tres hello/edit que cuelgan— es un DUPLICADO
    superado de la cadena dinámica de GNOME.
    Cerrarla no es construirla: es decidir si se promueven las sombras -shared al corpus,
    porque la resolución de deps es hermano→padre. Es una decisión de arquitectura, y hay
    aviso registrado de que promover a ciegas hace que variantes homónimas pisen recetas
    canónicas. NO la tomo yo.

(b) wlr-randr: cerrada en el commit anterior.

(c) dwarves: frente propio con muro identificado, no deuda. Nuestro elfutils entrega SÓLO
    libelf a propósito (libdw arrastra argp/obstack/fts, lo difícil en musl). No se arregla
    ampliando elfutils: de él cuelga el kernel que ya reproduce bit a bit. El camino es una
    receta aparte `elfutils-libdw`, con el patrón de las sombras -shared. Sin urgencia:
    ningún perfil pide dwarves y el kernel desactiva DEBUG_INFO_BTF justamente por su
    ausencia. Queda escrito en la cabecera de la receta, que es donde se va a leer.

(d) mirada-compositor, mirada-greeter, llimphi-counter: source por SSH a
    git.tawasuyu.net y el worker es SIN SECRETOS por diseño ⇒ HUB-ONLY estructural, no
    fallo. llimphi-counter ni siquiera llega a construir: su commit son ceros con el
    comentario «fijar al commit real». Receta sin terminar, y es de tawasuyu.

EL HALLAZGO DE FONDO: el bucle del worker sólo recorre las colas incoming-*; el corpus
(recipes/) NO está en QUEUES. Las 12 nunca se habían intentado allí. Buena parte de «la
deuda» era de ENCOLADO, no técnica — y por eso el diagnóstico heredado nunca se verificó.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 12:27:03 -04:00
sergioandClaude Opus 5 e79b26970a docs: SDD 20 (catálogo hasta publicable y hasta completa) + SDD 21 (manual del piloto)
Pedido del usuario: «el catálogo de todo lo que falta hasta decir la distro está
publicable, y lo de más hasta la distro está completa. Y un tipo manual, todos los pasos
que tengo que ir haciendo en las tres etapas que marcan esos dos codos.»

SDD 20 = el inventario, medido contra el repo (grafo, no recuento a mano). SDD 21 = el
manual de a pie, un comando por vez, marcando qué puede hacer el agente y qué es del
usuario.

LO QUE APARECIÓ AL MEDIR, y que no se sabía:

· La deuda de construcción NO son 12+12+13+12 recetas: es UNA lista de 12 vista desde
  cuatro grafos (la cadena GUI de la cascada de mesa). Un solo arreglo —declarar python3 y
  cmake en `[deps]`, no engordar el rootfs del worker— las destraba todas. `base` y `cli`
  ya están al 100%, KDE cierra 162/162.

· De WMs Wayland ligeros no hay NINGUNO: sólo `foot` y `mako`. Falta wlroots entero, los
  compositores y todos los accesorios (waybar, fuzzel, swaybg, grim, slurp, wl-clipboard).

· De aplicaciones gráficas de terceros hay CERO. Ni visor de imágenes ni lector de PDF.

· Firefox no es «una receta más»: su cadena de `*-sys` con C++ es justo la frontera que el
  techo MSRV del sandbox (1.96) no cruza. Antes de Firefox hay que subir el techo; empezar
  por la receta es empezar por el final.

· El texto de la licencia va inyectado en `hammer pack`, NO en la fase install: las fases
  entran al ArtifactHash, así que hacerlo en la receta re-hashearía las 1141. Pack es aguas
  abajo y sale gratis. Misma lógica que hizo pagable el campo `license`.

Dos correcciones al SDD 19, que escribí yo ayer y tenía mal:
· «5 de 771 recetas declaran licencia» — falso por partida doble. El número real era 0 de
  1141; los «5» eran falsos positivos de `grep license` (nombres de paquete, una línea de
  install, un comentario) y 771 son los nodos del grafo del corpus, no las recetas.
· «El repo no declara licencia» — falso: hay LICENSE (MIT) en la raíz y en Cargo.toml. No
  lo miré antes de escribirlo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 10:28:37 -04:00
sergioandClaude Opus 5 346cd59706 licencias: campo license en la receta — de 0 a 228 de 1141, sin re-hashear nada
La deuda legal bloqueante del SDD 19 §2.1. Medido hoy: **0 de 1141 recetas** declaraban
licencia, no «5 de 771» como decía el informe anterior. Los dos números estaban mal: los
«5» eran falsos positivos de `grep license` (el paquete `addlicense`, el paquete
`cargo-bundle-licenses`, una línea `install .../share/licenses/` y un comentario), y las
recetas son 1141. Contar con `grep -l <palabra>` sobre TOML cuenta comentarios y nombres,
no campos; `scripts/licencias.sh` cuenta el campo de verdad (clave en la raíz, antes del
primer `[table]`).

LO QUE HACE LA DEUDA PAGABLE: `Recipe::hash_inputs` es una LISTA BLANCA — sólo entran
source, compiler, target, link, patches, flags, phases y deps. `license` no entra, igual
que `evidence` y `slots`. Por eso se puede poblar en las recetas YA SELLADAS sin mover un
solo ArtifactHash. Verificado, no supuesto: en 40 recetas modificadas se comparó el hash
con y sin la línea — 40 idénticos, 0 cambiados. Si el campo entrara al hash, declarar la
licencia costaría reconstruir el corpus entero y no se haría nunca. Clavado con el test
`licencia_round_trip_y_no_afecta_el_hash`.

TRAMPA DE TOML: una clave suelta después de un `[table]` pertenece a esa tabla. Puesta al
final del fichero, `license` acaba dentro de `[deps]` y se pierde EN SILENCIO, porque serde
ignora los campos que no conoce — no hay error, simplemente no está. Va arriba, junto a
`name` y `version`; el sembrador la inserta tras `version`.

NO SE ADIVINA. Declarar mal una licencia es peor que dejarla vacía: convierte un hueco
visible en una afirmación falsa. Sólo se puebla desde una tabla curada entrada por entrada
(`docs/licencias-conocidas.tsv`); lo que no tiene evidencia queda vacío y se CUENTA.
Concretamente se descartó el atajo «k* = KDE ⇒ LGPL»: en este catálogo `kail`, `kind`,
`ko`, `kopia`, `krew`, `kustomize`, `kyverno`, `katana`, `kibi`, `kmon` y toda la familia
`kube*` son herramientas Go sin relación con KDE. El nombre no es evidencia.

Quedan 913, casi todas CLIs Go/Rust importados en masa — y ésas sí son automatizables con
evidencia real: Cargo.toml trae el campo `license` y los módulos Go traen su LICENSE en el
árbol. El cierre estructural es capturarlo en la fase de fetch, que ya descarga y extrae
cada tarball, y inyectar el texto en `hammer pack` (aguas abajo del ArtifactHash) en vez de
en la fase install (que sí re-hashearía).

De paso, respaldo-storagebox.sh reordenado por valor irreemplazable y con zstd: medido en
la oficina, el uplink da 8 Mbps iguales por cable y por wifi ⇒ 128 G no caben en una
sentada, así que sube primero el cerebro (estado + repo) y `--partial-dir` hace que cortar
a mitad de un artefacto no tire lo ya subido.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 10:24:11 -04:00
sergioandClaude Opus 5 b12ea3ac9d docs: SDD 19 — qué falta de verdad para lanzar la distro al público
Lo que falta para TERMINAR de construir no es lo mismo que lo que falta para
PUBLICAR. Lo primero es trabajo conocido (16 recetas, WMs Wayland ligeros,
apps de terceros — con el navegador como frente propio). Lo segundo tiene dos
bloqueantes que hoy no existen y no se improvisan el día del anuncio:

1. METADATOS DE LICENCIA: sólo 5 de 771 recetas los declaran. La distro no sabe
   bajo qué términos redistribuye el 99% de lo que empaqueta. Hace falta campo
   obligatorio validado por hammer + el texto dentro del artefacto.
2. ESPEJO DE FUENTES: la GPL no pide que el código exista en internet, pide que
   quien recibe el binario pueda obtener la fuente correspondiente DE VOS. Acá
   estamos bien parados —cada receta pinea tarball+sha256— pero hay que hacerlo.

Más: gestión de claves (firma sin eso es teatro), evidencia de reproducibilidad
publicada como diferenciador comprobable, imagen validada en METAL, y ciclo de
actualización ensayado antes de publicar.

Recomendación de arranque: el campo de licencia obligatorio, ya. A 771 recetas
es un rato; a 2000 es un proyecto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 08:27:14 -04:00
sergio 809b154586 estado: cosecha granja 2026-08-07T12:15:14Z — avance del árbol KDE 2026-08-07 08:15:14 -04:00
sergio dd0926df24 estado: cosecha granja 2026-08-07T11:32:45Z — avance del árbol KDE 2026-08-07 07:32:45 -04:00
sergio 6f215a12dd estado: cosecha granja 2026-08-07T04:14:38Z — avance del árbol KDE 2026-08-07 00:14:38 -04:00
sergio cd62c82a0c estado: cosecha granja 2026-08-07T03:30:03Z — avance del árbol KDE 2026-08-06 23:30:03 -04:00
sergio db58515226 estado: cosecha granja 2026-08-07T02:57:00Z — avance del árbol KDE 2026-08-06 22:57:00 -04:00
sergio 494e8fe4bb estado: cosecha granja 2026-08-07T02:24:51Z — avance del árbol KDE 2026-08-06 22:24:51 -04:00
sergio 02cc25542d estado: cosecha granja 2026-08-07T01:52:21Z — avance del árbol KDE 2026-08-06 21:52:21 -04:00
sergio 42d465e490 estado: cosecha granja 2026-08-07T01:19:32Z — avance del árbol KDE 2026-08-06 21:19:32 -04:00
sergio a86eb63244 estado: cosecha granja 2026-08-07T00:46:50Z — avance del árbol KDE 2026-08-06 20:46:50 -04:00
sergio 3605bf63b2 estado: cosecha granja 2026-08-07T00:12:22Z — avance del árbol KDE 2026-08-06 20:12:22 -04:00
sergio 63c28ae6e6 estado: cosecha granja 2026-08-06T20:11:33Z — avance del árbol KDE 2026-08-06 16:11:33 -04:00
sergio 55ce763e36 estado: cosecha granja 2026-08-06T19:10:27Z — avance del árbol KDE 2026-08-06 15:10:27 -04:00
sergio ba84fecb26 estado: cosecha granja 2026-08-06T18:10:01Z — avance del árbol KDE 2026-08-06 14:10:01 -04:00
sergio c4a8c09022 estado: cosecha granja 2026-08-06T17:09:27Z — avance del árbol KDE 2026-08-06 13:09:27 -04:00
sergio c5e6edc73e estado: cosecha granja 2026-08-06T16:39:08Z — avance del árbol KDE 2026-08-06 12:39:09 -04:00
sergio c18988f1d5 estado: cosecha granja 2026-08-06T16:07:52Z — avance del árbol KDE 2026-08-06 12:07:52 -04:00
sergio 6e07646c96 estado: cosecha granja 2026-08-06T15:37:22Z — avance del árbol KDE 2026-08-06 11:37:22 -04:00
sergio c8b0093aa8 estado: cosecha granja 2026-08-05T22:00:09Z — avance del árbol KDE 2026-08-05 18:00:09 -04:00
sergio 50242906de estado: cosecha granja 2026-08-05T21:18:06Z — avance del árbol KDE 2026-08-05 17:18:07 -04:00
sergioandClaude Opus 5 1284349ee5 📖 cosmic/metal: el 2º viaje — la imagen no podía ganar, y por qué
Documenta el diagnóstico del OptiPlex 3060: la GPU estaba perfecta (i915 inicializó,
fbcon en el framebuffer) y lo que fallaba era el hardcodeo de software GL, más la
preparación de sesión que la imagen de metal nunca tuvo.

Deja las dos reglas: un artefacto compartido entre QEMU y metal no puede llevar el
entorno hardcodeado (se detecta), y «llega al prompt» no valida NADA del escritorio
— hay que correr cosmic-start en la imagen que se va a quemar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 15:04:33 -04:00
sergioandClaude Opus 5 b5802bc651 📖 cosmic/metal: el 1er viaje físico, la carrera USB y la lección general
Documenta el diagnóstico completo: la AUSENCIA del `EXT4-fs mounted` como prueba de
que el root nunca se montó, la carrera contra la enumeración USB (invisible en QEMU
porque virtio está desde el instante cero), y la ceguera del /dev/console = serial.

La lección que generaliza: CADA capa del arranque tiene que escribir a /dev/tty0. Se
arregló la capa post-switch_root en el viaje de KDE y el initramfs quedó ciego; tapar
una sola capa garantiza que la siguiente vuelva a caer.

Incluye el comando para reproducir metal desde el laptop (qemu-xhci + usb-storage +
-serial null) y la evidencia en pantalla.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 13:55:18 -04:00
sergioandClaude Opus 5 166355d1fb 📖 cosmic/metal: el runbook del viaje físico, escrito ANTES de bootear
Qué correr con el USB en la mano, en orden, y —lo que importa— CUÁL ES EL VEREDICTO:
el `[4/4] OpenPipeWireRemote` con su fd, no que el diálogo aparezca (eso ya pasaba en
QEMU). Y el contrafáctico que hace falsable el diagnóstico de hoy: si vuelve a
colgarse en `Start` pero YA NO aparece `Erroneous EGL call` en el log del compositor,
entonces la causa era otra y lo de hoy estaba incompleto.

`ls /dev/dri` con renderD128 es la señal barata de que hay HW: con swrast no existe.

Gotchas del quemado, todos medidos y todos con su porqué:
 · NUNCA a un NVMe y NUNCA POR NOMBRE — hoy mismo, tras el reboot, nvme0n1 y nvme1n1
   se intercambiaron respecto de lo anotado en julio. Identificar por TRAN=usb.
 · el progreso NO se mide con kill -0 (sudo dd corre como root ⇒ EPERM desde el
   usuario y parece que terminó): se mide por /sys/block/sda/stat campo 7.
 · no correr os-prober sobre el device que estás dd-eando.
 · `pkill -f <patrón>` mata su propio shell si el patrón está en su cmdline. Volvió a
   pasar hoy (exit 144), con el gotcha ya escrito. Usar pgrep -x.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 12:05:49 -04:00
sergioandClaude Opus 5 11e6a3c78c 🔩 cosmic/metal: imagen EFI con iris HW — el viaje que cierra ScreenCast
Hermano de kde/metal-desktop-image-dual.sh, pero con la decisión INVERTIDA y ése es
el motivo de existir. La de KDE va por mesa-llvmpipe a propósito (tenía que aguantar
también una NVIDIA Pascal, cuya mesa HW sólo existe como binario Alpine ⇒ rompería
soberanía).

Acá el objetivo es cerrar ScreenCast, y el diagnóstico de hoy midió que lo que falla
es el COMPOSITOR en una llamada EGL —8 ms antes del `Paused`— porque en QEMU mesa es
kms_swrast: software, SIN exportación dmabuf. El `mesa` del corpus se construye con
-Dgallium-drivers=iris y YA está en el rootfs de COSMIC; en QEMU nunca se usaba, en
un TigerLake es el driver correcto y trae dmabuf de verdad. O sea que este viaje no
es "lo mismo pero en metal": es la única forma de saber si ScreenCast está bien.

⚠ Por eso NO se inyecta llvmpipe: mezclarlos no es aditivo — llvmpipe trae su propio
libgbm/libEGL/libgallium y sobrescribirlos DESACTIVA iris. Si la máquina no tuviera
Intel, la imagen correcta sería la de KDE, no ésta con un parche.

Y lo que NO hace falta inyectar, medido: la de KDE mete libLLVM.so.18 + libgcc_s +
libstdc++ porque el JIT de llvmpipe los NEEDea. Acá NO — iris_dri.so pide sólo
libglapi/libdrm/libz/libzstd/libc (mesa va con -Dllvm=disabled) y cosmic-comp ocho
NEEDED sin C++. CERO binarios ajenos de Alpine. Verificado con clausura ELF completa
del rootfs: 472 objetos escaneados, 42 raíces de runtime, 0 con NEEDED sin proveedor
(los 3 huecos son llvm-*/perl, herramientas de build que el escritorio no arranca).

Se instala EL MISMO cosmic-start validado en QEMU, no una variante: nada de lo que
hace es específico del emulador, y que corra el mismo fichero es lo que hace que
"validado en QEMU" signifique algo para el metal.

VALIDADO EN OVMF CON PANTALLA, que es la regla de oro que costó un USB en el 1er
viaje de KDE (-serial null para simular metal sin puerto serie): arje-zero PID 1, las
4 particiones montadas, el motd VISIBLE y el prompt `/ #` en la pantalla — o sea que
el getty de tty1 hace su trabajo. El shell responde: iris_dri.so presente,
/dev/dri/card0, y cosmic-start/portal-probe/wireplumber en PATH.

Falta quemar el USB, que es destructivo y necesita que el usuario confirme el device.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 11:41:16 -04:00
sergioandClaude Opus 5 b38f54e25c 🧊 ScreenCast: la causa es EGL POR SOFTWARE en el compositor, no el portal
Con RUST_LOG=trace el log del backend tiene CINCO LÍNEAS en total y la última es la
de siempre ('Connecting' -> 'Paused'). Después no escribe nada más: ni error, ni
panic, ni progreso. O sea que el trace no aportó — screencast_thread no tiene más
instrumentación y buscar ahí estaba agotado.

La pieza que faltaba mirar era EL COMPOSITOR, que es quien entrega los frames:

  15:19:02.301568Z WARN smithay::backend::egl::error: Erroneous EGL call didn't set EGLError
  15:19:02.310127Z INFO …screencast_thread: state-changed 'Connecting' -> 'Paused'
                   ↑ OCHO MILISEGUNDOS

Y la correlación no es casual: el contador de "Erroneous EGL" sube DE A DOS por cada
intento de screencast (uno al abrir el diálogo con su miniatura en vivo, otro al
pulsar Share) y no se mueve en ningún otro momento.

`ls /usr/lib/dri/` → iris_dri.so, kms_swrast_dri.so, swrast_dri.so. En QEMU con
virtio-gpu-pci sin virgl carga kms_swrast: mesa por software, SIN exportación dmabuf
real. Que es justo lo que un stream continuo necesita y una captura de una sola toma
no — por eso cosmic-screenshot SÍ funciona (va por shm) y ScreenCast no.

EL FRENTE NO ESTÁ BLOQUEADO POR UNA RECETA SINO POR EL ENTORNO. Esto reencuadra el
día entero: pipewire no era, wireplumber no era, el backend no era. Las tres piezas
están construidas, corriendo y haciendo su trabajo —el nodo `cosmic-screencast` existe
en el grafo— y el que no puede cumplir es el compositor sobre una GPU de software. Es
el MISMO muro que documenta el frente KDE (GBM/EGL de software), llegando por otro
camino.

Y no se puede verificar acá: `qemu-system-x86_64 -display help` da sólo none/gtk/sdl
y no existe virtio-gpu-gl-pci — este binario no se compiló con virgl, aunque
libvirglrenderer.so.1 esté en el host. Las salidas son metal (donde iris_dri.so YA
está en la imagen) o un QEMU con virgl.

Lo honesto: ScreenCast está verificado HASTA DONDE EL ENTORNO PERMITE — la cadena
D-Bus completa funciona, el stream se crea y se negocia, y el último tramo (los
píxeles) depende de una GPU que esta VM no tiene.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 11:26:15 -04:00
sergio dcaed2b066 estado: cosecha granja 2026-08-05T15:00:09Z — avance del árbol KDE 2026-08-05 11:00:09 -04:00
sergioandClaude Opus 5 8d10bccf34 🔇 wireplumber: construido, corriendo… y NO era el bloqueo
b3:b8f3baf0, selló a la primera. Arranca desde cosmic-start ("wireplumber OK (pid
192) — hay gestor de sesión"), se conecta al grafo (dos clientes en wpctl status) y
wpctl pasa a mostrar una sección Video que antes no existía.

Y el Start de ScreenCast SIGUE sin Response a los 60s. Mismo resultado exacto.

LA HIPÓTESIS QUEDA MATADA POR MEDICIÓN. "Falta el gestor de sesión que mueva el nodo
de Paused a Streaming" era mía y era razonable; no era cierta. Queda escrita junto a
su refutación porque una hipótesis descartada CON EVIDENCIA vale más que una lista de
sospechosos: acota el próximo paso a lo que queda, que es el backend mismo.

El dato nuevo, que es por dónde seguir: con wireplumber corriendo, `wpctl status`
lista `Video → Streams` VACÍO durante el handshake. O sea que el nodo
`cosmic-screencast` que SÍ existe en `pw-cli ls Node` no llega a wireplumber como
stream gestionado. Próximo movimiento: RUST_LOG=trace sobre screencast_thread, no
otra dep.

── por qué receta propia y no la de GNOME ──────────────────────────────────────
La de incoming-gnome funciona pero NEEDea libglib/libgobject/libpipewire de la ISLA
DINÁMICA de GNOME: traerla metería una segunda glib y una segunda pipewire en la
imagen. De 19 deps, 14 dan hash idéntico; las que divergen divergen a propósito —
sobre todo `pipewire`, que acá apunta a la de COSMIC (338d1d8c), la que el escritorio
realmente ARRANCA. Un gestor de sesión contra otra pipewire que la que corre no
gestiona nada.

El cambio de fondo es glib → glib-shared. COSMIC usa la glib ESTÁTICA del corpus, que
le alcanza al portal porque es un ejecutable. Acá no: wireplumber produce un .so y 17
módulos, y libglib-2.0.a tiene 44.275 reubicaciones R_X86_64_32/32S ⇒ no es PIC. La
regla del frente GNOME (readelf -r ANTES de gastar el build) ahorró uno.

Y la salida no fue una campaña nueva sino una MEDICIÓN: incoming-kde/glib-shared
copiada a esta cola resuelve al MISMO hash (0584ce1f) y ya estaba sellada ⇒ cero
rebuild. Idem pcre2-shared, lua y libelogind. Las dos glib coexisten sin pisarse (.a
y .so son ficheros distintos) y el portal conserva sus 3 NEEDED.

escritorio-cosmic: 84 → 89 recetas, 0 faltantes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 10:54:54 -04:00
sergio 97bcf0673e estado: cosecha granja 2026-08-05T14:42:37Z — avance del árbol KDE 2026-08-05 10:42:37 -04:00