Commit Graph
178 Commits
Author SHA1 Message Date
SergioandClaude Opus 5 7b38e2ef16 kde: los portales — segundo hueco cerrado, y OBS ya tiene con quién hablar
Medido recorriendo los `.service` de D-Bus de TODO el store: los únicos backends de portal sellados
eran los de COSMIC y GNOME. Ninguno de KDE, y la cola `incoming-kde` no tenía ni el frontend.
Consecuencia concreta: la imagen KDE trae `obs-studio` con su plugin linux-pipewire, que captura
pantalla POR EL PORTAL — o sea que en Plasma no tenía con quién hablar mientras en los otros dos
escritorios ese frente estaba cerrado. Sin portal tampoco hay diálogo de fichero ni compartir
pantalla para nada que los use.

Van los DOS paquetes porque la cadena es de tres:
  cliente → org.freedesktop.portal.Desktop [frontend] → org.freedesktop.impl.portal.* [backend]
El frontend se copia de la cola de COSMIC y **comparte artefacto**: hash idéntico (ecbe13f68eca6)
desde las dos colas ⇒ un solo directorio en el store, cero builds.

El backend es receta NUEVA, 6.7.2 — la MISMA versión que plasma-workspace, kwin y kscreenlocker de
esta cola, porque habla interfaces privadas de kwin para el ScreenCast y desalinear ahí es pedir que
dos mitades del mismo release se entiendan por casualidad. **Cero frontera nueva**: sus 22
dependencias (Qt6, KF6, KWayland, protocolos de Wayland, xkbcommon) ya estaban todas, verificadas
una por una antes de escribir la receta.

⚠ SIN EL PORTAL DE IMPRESIÓN, y la causa es más honda que el error. El build moría en
`src/print.cpp:27` con `'QtPrintSupport/private/qcups_p.h' file not found`, y la cadena está medida
entera: no hay NINGUNA receta de cups en el catálogo ⇒ qtbase 6.11.1 se construyó sin CUPS ⇒ su
`QtPrintSupport/private/` trae qpaintengine_alpha_p.h y qprintengine_pdf_p.h pero NO qcups_p.h.
No falta una cabecera: falta el subsistema. Un portal de impresión sin con qué imprimir no es
funcionalidad que se pierde, es código muerto que no enlaza.

Upstream no expone `option()` para portales —se compilan todos—, así que el parche va en TRES
sitios y no en uno: la fuente, la instanciación (desktopportal.cpp/.h) y **la lista de interfaces
que el backend ANUNCIA**. El tercero es el que se olvidaría y el que importa: anunciar
`impl.portal.Print` sin implementarlo hace que el frontend enrute a un portal que no contesta, que
es peor que no tenerlo. Cada `sed` lleva su `grep` de verificación al lado, para que el día que
upstream mueva esas líneas el parche falle RUIDOSO en vez de volverse inerte.

VERIFICADO sobre el artefacto sellado: publica `org.freedesktop.impl.portal.desktop.kde.service`,
y su `kde.portal` anuncia 17 interfaces con **0 apariciones de Print** e incluyendo ScreenCast,
Screenshot y RemoteDesktop, que es exactamente lo que OBS necesita. Y sobre el rootfs hidratado:
están el frontend (`org.freedesktop.portal.Desktop.service`), el backend y el `kde.portal`.

⚠ Y la licencia casi la firmo mal: leí la cabecera de UN fichero y generalicé. Contadas las
etiquetas SPDX del árbol entero: 88 `LGPL-2.0-or-later`, 23 de la fórmula de KDE e.V. y 1
`GPL-2.0-or-later`. El binario las enlaza a todas ⇒ la expresión es la CONJUNCIÓN.

El perfil pasa a 98 raíces, 361/361 listo, deuda 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 23:17:42 +00:00
SergioandClaude Opus 5 542d9875fb kde: upower — la imagen declaraba powerdevil y no tenía batería
Primero de los dos huecos que dejaban a KDE POR DEBAJO de una instalación estándar. El perfil
declaraba `powerdevil` —el gestor de energía de Plasma— pero no a `upower`, que es con quien
powerdevil habla para leer la batería y aplicar perfiles. Medido: upower sólo existía en la cola de
GNOME, y las colas no se ven entre sí (HERMANO→corpus, nunca de reojo). En un portátil eso es un
escritorio sin indicador de batería, y el arranque no falla ⇒ no se ve hasta usarlo.

Cuesta TRES recetas y no siete, y la diferencia es una perilla: `-Dintrospection=disabled`.
GNOME la necesita ENCENDIDA porque su shell hace `imports.gi.UPowerGlib` desde JavaScript, o sea que
carga el typelib. powerdevil NO: habla D-Bus con `org.freedesktop.UPower`. Apagarla saca de la
frontera gobject-introspection, gi-foreign-girs, glib-introspected y py3-setuptools, que sólo viven
en la cola de GNOME.

⚠ Y NO SE PROMUEVEN AL CORPUS, aunque era lo primero que intenté. Al mover `libgudev` allá su
ArtifactHash CAMBIÓ (7404bc8d → 87ca5e73) y eso no es una mudanza: `glib` existe en las DOS colas y
son recetas distintas, así que desde `incoming-gnome/` se construye contra la glib de GNOME y desde
el corpus contra la del corpus. Promoverla habría arrastrado a GNOME a la glib del corpus — el
cuadro de las «dos glib» que este repo ya pagó caro. Revertido y verificado que vuelve al hash de
antes (7404bc8d), o sea GNOME intacto. Se COPIAN a la cola de KDE.
`udev-pc` sí comparte artefacto (sus deps son sólo pkgconf ⇒ mismo hash desde las dos colas, un
solo directorio en el store). `libgudev` es otro a propósito, por la glib.

VERIFICADO sobre el artefacto sellado, no supuesto: trae `usr/libexec/upowerd`, el
`org.freedesktop.UPower.service` de system-services y su política en `system.d` — que es exactamente
lo que powerdevil necesita para que el demonio arranque por activación D-Bus.

El perfil pasa a 49 raíces, 301/301 listo, deuda 0.

Queda el segundo hueco: KDE no tiene backend de portal (ni `xdg-desktop-portal` en su cola), o sea
que no hay compartir pantalla — y en particular la captura de obs-studio, que la imagen ya trae, no
tiene con quién hablar en Plasma. Eso es más caro: pide traer el portal a la cola y ESCRIBIR
`xdg-desktop-portal-kde`, que no existe como receta en ninguna cola.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 22:02:49 +00:00
Sergio e852f48491 takana etapa 5a: los comentarios de las 741 recetas
Barrido de TEXTO puro: 1427 líneas de comentario TOML. Cero ArtifactHash
movidos, y eso está MEDIDO, no deducido: hasheé las 741 antes y después y los
ficheros de hashes son idénticos byte a byte (723 con hash real + 18 que ya no
hasheaban de antes).

El guardián valió la pena: el primer barrido, filtrando por 'la línea empieza
con #', movió el hash de helix, lsof y steam-runtime-sniper. La causa es que una
fase se escribe como compile = <triple> ... <triple> y sus comentarios de SHELL
también empiezan con #, pero viven dentro del VALOR — y las fases sí entran en
hash_inputs. El barrido ahora calcula los rangos de las cadenas multilínea de
TOML y no entra ahí.

Quedan intactos a propósito: .hammer-zig-cc y .hammer-cargo-vendor (literales
dentro de fases), hammerd, hammer-recover y toda ruta que empiece por /
2026-09-09 19:23:26 +00:00
SergioandClaude Opus 5 71904ebbde xwayland: retirar la receta — la decisión ya estaba escrita y decía que no
Decisión del usuario (2026-09-09): X11 se erradica, y eso incluye no construir el servidor que lo
mantiene vivo. La receta se retira; `xwayland` VUELVE a ser lo que sus propios documentos decían.

⚠ LO QUE APARECIÓ AL MIRAR: esto ya estaba decidido, por escrito y DOS VECES, el 2026-09-03
(commit f64859ba):
  docs/state/targets.toml:143   «`xwayland` sigue acá como RAÍZ pero su receta NO se va a escribir:
                                 lo provee una imagen ajena enjaulada … el hueco se disuelve sin
                                 receta y sin tocar la postura Wayland-only»
  docs/state/qorpa-ajenos.toml  «X11 está fuera de alcance para toda la distro … el Xwayland vive
                                 DENTRO de la imagen —Arch y Fedora ya lo traen— y se cuelga de
                                 nuestro kwin por el socket. La receta no se escribe.»
El 2026-09-08 se escribió igual (3d8c6fc6, «cerrar los 3 huecos que quedaban»), y los dos
documentos siguieron diciendo lo contrario durante toda la jornada de hoy. No hubo que cambiar
ninguno de los dos: alcanzó con borrar la receta para que el repo volviera a coincidir con ellos.

MEDIDO ANTES DE SACARLA, no supuesto:
  · Sólo kwin podía lanzarlo. mutter va con -Dxwayland=false y wlroots con -Dxwayland=disabled ⇒
    GNOME, sway y COSMIC no podían usarlo aunque el binario existiera. Nunca sirvió a más de un
    perfil de los cuatro.
  · NINGUNA app del catálogo necesita servidor X: todo lo gráfico es Wayland nativo (Qt6 con
    qtwayland, GTK3 Wayland-only, mpv, OBS con ENABLE_WAYLAND=ON, foot, fuzzel, swayimg). El
    consumidor que lo justificaba está nombrado en qorpa-ajenos.toml y es Steam, que corre
    enjaulado y TRAE EL SUYO ADENTRO.
  · Y la imagen KDE ya arrancaba sin él: la propia receta contaba que KDE sellaba 1037/1037 con las
    apps X11 muertas. Esto no estrena una configuración, vuelve a una ya probada.

EFECTO EN EL GRAFO, verificado regenerando: `xwayland` deja de ser una receta y pasa a clase
`ajeno` —que es como targets.toml decía que había que contarlo— y el perfil escritorio-kde baja de
304 a 299 nodos con deuda 0. Los cinco que se van son la cadena que sólo él usaba.

⚠ QUEDAN CINCO RECETAS HUÉRFANAS, y no las borro de paso: `libfontenc`, `libXfont2`, `libxkbfile`,
`libxshmfence` y `xkbcomp`. Medido: NADA más en el catálogo las declara, y ninguna es raíz de
ningún perfil ⇒ siguen selladas pero no entran en ninguna imagen. Sacarlas es su propia unidad de
trabajo y su propia decisión.

El triaje pasa de `provisto` a `opcional` con la historia entera en su `porque`, y con eso se cae
el alias `xwayland xwayland` de alias-triaje.txt, que habría afirmado que tenemos una receta con
ese nombre.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 18:55:20 +00:00
SergioandClaude Opus 5 3379a1f170 licencias: las 26 que faltaban, y el guardián que las contaba mal
CAMPAÑA CERRADA: 1166/1166 recetas declaran `license`. Ninguna adivinada — cada una sale del
fichero de licencia de su fuente PINEADA (tarball del sha256 de la receta, o el commit exacto en
la forja), y la cita queda como comentario en la propia receta.

⚠ Y EL GUARDIÁN ESTABA MAL, que es el hallazgo que vale más que las 26. `licencias-rootfs.sh`
resolvía la receta por NOMBRE DE FICHERO (`ls recipes/$pkg.toml`), y el paquete se llama por su
campo `name`, que en 34 recetas NO coincide: nu.toml→`nushell`, dust.toml→`du-dust`,
incoming-kde/qtbase.toml→`qt6-qtbase`… Medido: **14 paquetes que SÍ declaran licencia salían como
«licencia desconocida»** y el guardián vetaba una imagen perfectamente publicable.
El falso veto se nota; el hermano silencioso NO: si existe un `<pkg>.toml` que pertenece a OTRO
paquete, la versión vieja reportaba la licencia EQUIVOCADA sin decir nada. Hoy no pasa —medido,
0 casos, y de los 34 nombres duplicados CERO declaran licencias distintas—, pero ahora es
imposible en vez de improbable.

El arreglo tuvo que ser por LOS DOS lados, y el primer intento rompió el otro: el grafo de estado
nombra sus nodos por el fichero (`dust`) y el artefacto del store por `name` (`du-dust`), así que
resolver sólo por `name` dejaba a `dust` sin licencia. Ahora busca por `name` y cae al fichero.
Medido en los dos sentidos: corpus entero 1128/1128, perfil base+cli 81/81, cero sin licencia.

Y probado CON ROTURA A PROPÓSITO además del control, que es lo único que distingue a un guardián
que sirve de uno que nunca salta:
  paquete inexistente en la lista               → exit 1 y «ESTA IMAGEN NO SE PUEDE PUBLICAR»
  control (zlib nushell qt6-qtbase lsof tzdata) → exit 0, y escribe los textos
(⚠ ojo al medir: `script | tail` devuelve el exit de `tail`. La primera corrida dijo exit=0 sobre
la rotura y no era el guardián, era el pipe.)

SE LEVANTA EL VETO QUE SDD 20 DEJÓ ESCRITO. Decía que `base` y `cli` iban con 2 paquetes cada una
con binarios y licencia desconocida: `lsof` y `tzdata`, «que necesitan la vía LicenseRef- y siguen
vetando a propósito». Hechos los dos, con su texto real en licenses/:
  lsof    → LicenseRef-lsof (licencia propia de Purdue, sin identificador SPDX)
  tzdata  → LicenseRef-tz-public-domain (su LICENSE: «all files in the tz code and data … are in
            the public domain»; los tres ficheros BSD-3-Clause que menciona NO se instalan — la
            receta sólo compila zic y deja /usr/share/zoneinfo)

⚠ DOS QUE NO SE PUEDEN REDISTRIBUIR, y ahora el veto los ve:
  duplicacy    NO ES LIBRE. Su LICENSE.md: «Free for personal use or commercial trial; non-trial
               commercial use requires per-computer CLI licenses … $50 per year»
  waybackurls  NO DECLARA LICENCIA: en el commit pineado la raíz es .gitignore, README.mkd,
               go.mod, main.go y script/ — sin LICENSE ni COPYING, y el README no la menciona. Sin
               concesión expresa, el defecto es «todos los derechos reservados»
Los dos con LicenseRef y un texto en licenses/ que explica qué hay, en vez de dejar el campo vacío,
que se lee como «todavía no lo poblamos». Ninguno está hoy en un perfil de imagen; si alguien los
mete, el guardián corta.

De paso queda escrito el texto de `LicenseRef-qorpa-ajena-no-enumerable`, que ya se usaba en
steam-runtime-sniper y no tenía fichero; y `licencias-textos.sh` bajó los canónicos nuevos
(BSL-1.0 para boost, GCC-exception-3.1 que ya hacía falta).

Hueco conocido y anotado en la receta: `XFree86-1.0` (rama del OR de hwdata) se queda sin texto —
SPDX no publica ese identificador, sólo XFree86-1.1, que es otra licencia, y el tarball lo nombra
sin incluirlo. El guardián avisa y no veta, que es correcto: la otra rama del OR es la GPL y su
texto sí está.

NADA SE RE-HASHEA: `license` está fuera de `hash_inputs`. Verificado, no supuesto — `hammer hash`
sobre pigz, lsof y boost después de editarlas devuelve el hash cuyo artefacto YA está en el store.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 17:47:16 +00:00
SergioandClaude Opus 5 3c628deeb6 purpose: el último hueco de la frontera, y enganchado a las tres apps
purpose 6.27.0 — el marco de «compartir» de KDE. 23 plugins (código de barras, bluetooth,
portapapeles, correo, imgur…) más sharefileitemaction.so, que añade «Compartir» al menú de
Dolphin.

Era el último hueco. La receta de okular lo degradaba con el flag oficial
FORCE_NOT_REQUIRED_DEPENDENCIES y su cabecera decía «los que no tenemos sellados» — un ESTADO,
no una preferencia. Ahora sale de esa lista.

⚠ Y va ENGANCHADO, no sólo autorado: una receta que nadie alcanza no arregla nada. okular sale
de la lista de degradados; gwenview y spectacle lo declaran (ninguna lo mencionaba: construían
sin él y el CMake se lo saltaba en silencio). Coste medido antes de tocar: las tres son hojas
con 0 dependientes transitivos ⇒ 3 builds, sin cascada.

La prueba es el enlace, no la intención: las tres referencian libKF6Purpose (2 cada una).

Un tropiezo con su lección: el CMake abortó pidiendo tres MÓDULOS QML —org.kde.prison,
org.kde.kitemmodels, org.kde.kcmutils— que no salen de ningún find_package. Los pide con
ecm_find_qmlmodule, o sea que comprueba que el IMPORT exista, no que la librería esté enlazada.
Las tres recetas ya existían y publicaban su qmldir; sólo faltaba pedirlas. Un requisito que no
se ve leyendo los find_package.

KAccounts6 NO se pide: su find_package va sin REQUIRED y arrastraría toda la torre de
kaccounts/signond que esta distro no tiene.

Verificado: REPRODUCE bit a bit · tarball en el mirror · escritorio-kde 304/304 sellado, deuda 0.

FRONTERA: 0 HUECOS.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 14:21:02 +00:00
SergioandClaude Opus 5 3d8c6fc6c7 KDE: cerrar los 3 huecos que quedaban — polkit-qt-1, qqc2-breeze-style y xwayland
La frontera queda en CERO huecos y cero pendientes, y el perfil escritorio-kde en 302/302
sellados. Los tres eran huecos de RUNTIME: KDE sellaba 1037/1037 con la autorización muerta,
los controles QML en estilo genérico y ninguna app X11 capaz de arrancar.

polkit-qt-1 0.201.1 — al conectarlo se vio lo que ninguna métrica decía: kauth NO traía plugin
de backend, ni siquiera el directorio. Ahora trae kf6/kauth/backend/kauth_backend_plugin.so con
el símbolo KAuth::Polkit1Backend. Cascada de 26 dependientes reconstruida, 26/26 sin fallos.
Añadirlo cambió la rama del CMake y pidió kwindowsystem y tras él las X11 — cada cosa dicha por
el configure al fallar, no supuesta.

qqc2-breeze-style 6.7.2 (la del stack Plasma, NO la 6.7.4 de nixpkgs: mezclar versiones de un
mismo release es pedir desajuste de ABI en los plugins QML, que se ve en runtime y no al
construir). Enganchado a plasma-workspace como deps.runtime, no build: es un plugin que Qt carga
por la ruta de imports. Verificado que runtime no re-hashea ⇒ cero rebuilds.

xwayland 24.1.13 — resultó ser una CADENA de seis: libfontenc, libXfont2, libxkbfile,
libxshmfence, xkbcomp y el servidor. Ninguna existía. Tres tropiezos con su lección:

  · libxkbfile 1.2.0 ya no trae ./configure: es sólo meson. El resto de las libs X11 de la cola
    son autotools, así que copiar su plantilla era lo natural y estaba mal.
  · «checking for freetype2... no» culpaba a freetype, que estaba perfecta: freetype2.pc declara
    Requires: zlib, libpng y pkg-config resuelve transitivamente. El mensaje señala al paquete
    equivocado.
  · libXfont2 construye una .so y moría en «recompile with -fPIC» contra la libfreetype.a
    estática. Van las variantes -shared.

  Y xkbcomp es el eslabón que NINGÚN build habría delatado: xwayland lo lanza como subproceso en
  runtime (xkb/ddxLoad.c) y su meson lo pide con required:false, así que la receta compila igual
  y el servidor arranca sin teclado. Se encontró leyendo la fuente.

⚠ Sin GLX, y no por preferencia: glx/meson.build:43 pide dependency('gl') y ninguna cola publica
gl.pc — las tres recetas de mesa van con glx y glvnd apagados por decisión anterior. Las apps
X11 corren en 2D. ⚠ Y el meson.build RAÍZ engaña: ahí build_glx sólo enciende una tabla hash y
parece gratis; yo mismo di la preocupación por infundada mirando el fichero equivocado.

Verificado: Xwayland arranca y se identifica («The X.Org Foundation Xwayland Version 24.1.13»),
las 6 REPRODUCEN bit a bit, los 5 grafos con deuda 0, y los 6 tarballs en el mirror.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 22:26:17 +00:00
SergioandClaude Opus 5 ca2c164512 sombras: CERO — promover las 6 compartidas al corpus y barrer sus 16 copias
Las 6 que quedaban (fuse3, hwdata, icu4c, libdisplay-info, libelogind, lua) no tenían copia en
el corpus, así que borrar una habría roto su cola: la resolución es sibling-first y después el
catálogo PADRE, nunca una cola hermana. Se promueve una y se barren las 16.

Las 16 eran byte a byte IDÉNTICAS entre sí, con el mismo ArtifactHash — medido con 'hammer hash',
no deducido del nombre. Cada una la comparten entre 2 y 4 imágenes, que es exactamente el
criterio que dejó escrito xkeyboard-config al promoverse: lo que comparten varias imágenes tiene
que vivir en el corpus o no lo alcanzan.

A diferencia de aquella, acá las copias SÍ se barren en el mismo movimiento: sin copia en el
corpus no había dónde caer, y dejarlas sería mantener hasta 4 ficheros que son el mismo hash.

Verificado con la huella de las 1167 recetas antes y después:
  ficheros de receta   1167 → 1157   (16 borradas, 6 promovidas)
  hashes supervivientes  ninguno se movió ⇒ CERO rebuilds
  los cinco grafos       deuda 0, huérfanas [], sellados == recetas
  static-audit           MIENTEN 0 de 690
  duplicados             SOMBRAS REDUNDANTES: 0   ← de 14

⚠ Y una lectura que casi publico mal: mi primera comparación de hashes dijo 'CAMBIÓ ✗' en las
seis. Era el grep de la comparación, que no casaba y dejaba el valor 'antes' vacío — los hashes
nuevos eran idénticos a los medidos minutos antes. Un instrumento roto que grita es tan malo
como uno mudo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:47:55 +00:00
SergioandClaude Opus 5 a4a462b751 sombras: barrer 14 recetas redundantes que ya tenían copia en el corpus
Las 14 sombras marcadas 'redundante' dan el MISMO ArtifactHash en todas sus colas — no son
variantes, son el mismo artefacto declarado dos, tres, cuatro y hasta cinco veces. Medido con
'hammer hash' receta por receta, no deducido del nombre.

Se barren sólo las que YA tenían copia en el corpus, porque la resolución es sibling-first: una
dep desde incoming-kde busca incoming-kde/x y, si no está, CAE al corpus/x. Son 8 nombres, 14
ficheros: bzip2-shared, glib-shared, lcms2, mpc, pcre2-shared, sqlite-shared, xkeyboard-config
y xz-shared.

13 de los 14 eran byte a byte idénticos al del corpus. El decimocuarto, xkeyboard-config,
difiere en 14 líneas de COMENTARIO (mismo hash), y ese comentario es el permiso explícito para
esto: quien la promovió el 2026-09-05 escribió que dejaba las copias a propósito y que
'barrerlas es otra unidad de trabajo, no un efecto colateral de ésta'. Ésta es esa unidad.

Verificado con la huella de las 1181 recetas antes y después: NINGÚN hash superviviente se
movió ⇒ cero rebuilds. Y tras regenerar los cinco grafos: deuda 0, huérfanas [], y todas las
clausuras de perfil siguen completas.

⚠ Nota sobre una lectura que casi me confunde: los conteos de 'recipes' NO bajan (kde sigue en
1034) y eso es lo correcto — cuentan nodos alcanzables, no ficheros. Antes incoming-kde/x tapaba
a corpus/x; ahora el del corpus ocupa su lugar. Un nodo por otro.

Quedan 6 nombres (fuse3, hwdata, icu4c, libdisplay-info, libelogind, lua) sin copia en el
corpus: ésos exigen promover una primero, y van aparte.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:44:28 +00:00
SergioandClaude Opus 5 381780aab4 fuentes: tapar el agujero de libtool y que el vigía distinga noticia de emergencia
El vigía decía 5 fuentes muertas y sólo UNA estaba en riesgo de verdad: busybox y freetype
tenían el tarball en la caché local Y en el mirror, y firefox-pgo-profile apunta a .invalid a
propósito. La que no tenía copia en ningún lado era libtool (incoming-kde), con ftpmirror.gnu.org
devolviendo 502 — o sea una receta que ya no se podía reconstruir y nadie lo sabía.

Arreglado: el tarball se bajó de ftp.gnu.org, se verificó contra el sha256 PINEADO (coincide
byte a byte), y está en la caché local y en el mirror. La URL de la receta pasa al espejo que
responde, y se midió que eso no re-hashea nada — ANTES y DESPUÉS dan el mismo
b3:5c09bff5..., que es el ADR 0013 comprobado en vez de citado.

Y el vigía ahora cruza cada fuente muerta con la caché local y el mirror, porque mezclar
'upstream caído con el blob guardado' (noticia) con 'caído y sin copia' (emergencia) hace que
el número suba, nadie lo mire, y el día que uno importe esté enterrado entre cuatro que no. A
un guardián lo mata el ruido. Ahora informa EN RIESGO aparte:

  == vivas 1175 / 1179   muertas arriba 4   EN RIESGO 0

⚠ Y si el mirror no se puede consultar —el worker no tiene la clave del Storage Box— dice
'indeterminado', NUNCA 'EN RIESGO': un instrumento que no pudo correr no puede parecer un
hallazgo.

Probado con rotura a propósito y con los dos controles, que es lo que separa un guardián que
sirve de uno que nunca saltó:
  sha inexistente + upstream muerto → EN RIESGO        ✓ salta
  blob en caché + upstream muerto   → cache-local      ✓ no salta
  mirror inalcanzable               → indeterminado    ✓ no alarma en falso

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:14:21 +00:00
Sergio 59a0e56a16 licencias 97% (1132/1165): «no hay fichero» y «no reconozco el texto» no son lo mismo
El script decía «sin COPYING ni declaración en el árbol» para `lsof`, `when`, `wpa_supplicant`,
`perl-xml-parser` y `fuse3` — y las cinco SÍ tienen un COPYING o un LICENSE en la raíz. Lo que
pasaba es que ninguna de mis huellas reconocía su texto, que es un problema distinto y se acciona
distinto: uno pide buscar la licencia en otro sitio, el otro pide una huella nueva o leerla. Decir lo
mismo de los dos casos mandaba a mirar donde no era. Ahora el mensaje nombra el fichero y cita su
primera línea, y con eso tres se resolvieron leyéndolas:

  · `wpa_supplicant` — su COPYING no es una licencia sino un aviso: «the project has chosen to use
    only the BSD license option for future distribution», y remite al README. El README trae las tres
    cláusulas clásicas ⇒ BSD-3-Clause. Sin seguir esa remisión no había veredicto posible.
  · `when` — «under the same terms as Perl, or, at your option, under version 2 of the GPL». «Los
    mismos términos que Perl» ES la disyunción Artistic-1.0-Perl OR GPL-1.0-or-later, y la opción de
    GPL-2 ya queda cubierta por el `-or-later`.
  · `perl-xml-parser` — su LICENSE es el texto íntegro de la Artistic License 2.0.

Ese último obligó a cerrar un lazo que yo mismo había dejado abierto: el script se niega a declarar
un SPDX cuyo TEXTO no tengamos en `licenses/`, porque la obligación legal es entregar el texto y no
el nombre. Pero `licencias-textos.sh` deriva qué textos bajar DE las licencias ya declaradas ⇒ una
licencia genuinamente nueva no podía entrar por ningún lado. El orden que lo resuelve es: declarar
con evidencia, bajar el texto, comprobar que llegó. `licenses/` pasa de 44 a 48 textos y el único que
queda sin texto canónico es `LicenseRef-qorpa-ajena-no-enumerable`, que es un identificador nuestro y
SPDX no publica.

Quedan 33. `lsof` (licencia propia de Purdue) y `fuse3` (aviso compuesto: LGPL para la librería, GPL
para las utilidades) siguen pendientes a propósito, y el resto son expresiones que decide una
persona: gmp, ffmpeg, clang18, llvm18 y los `gi-*` traen VARIOS ficheros de licencia que dicen cosas
distintas, y en ffmpeg la respuesta ni siquiera está en el árbol —la deciden los flags de la receta.

Los 3 ArtifactHash, idénticos antes y después.
2026-09-05 18:10:52 +00:00
Sergio 96855001c6 licencias: 96% (1124/1164) — --fetch para los tarballs que no estaban en caché
Ocho paquetes más (giflib, pcre2, nghttp2, libogg, libvorbis, speexdsp, libuv, tea) con la misma
regla de evidencia. Su tarball no estaba en `work/tarballs/`, así que el modo `--fetch` lo baja a un
temporal, lo verifica contra el sha256 QUE LA RECETA PINEA —o es el árbol exacto o no se mira— y lo
borra. No se escribe en la caché de hammer a propósito: es suya, y un fichero puesto ahí por otro
camino es una vía de envenenamiento que nadie audita.

Dos correcciones al criterio, las dos porque produjo una afirmación falsa:

  · `gmp` salía GPL-3.0-or-later. Su `COPYING` es la GPLv3, pero al lado trae `COPYING.LESSERv3` y
    `COPYINGv2` porque la biblioteca es LGPL. La regla anterior —«el `COPYING` a secas gana al
    sufijado»— arregla socat, cuyo `COPYING.OpenSSL` es una excepción, y rompe gmp, donde el extra
    nombra otra VERSIÓN y no una dep. Esa diferencia es demasiado fina para codificarla sin
    equivocarse, así que ahora se identifican TODOS los ficheros de la raíz y sólo hay veredicto si
    dicen lo mismo. gmp, ffmpeg y los tres `gi-*` quedan pendientes, que es lo correcto: en ffmpeg
    la respuesta ni siquiera está en el árbol, la deciden los flags de la receta.

  · Pero «varios ficheros» no es «ambigüedad»: el `COPYING` de pcre2 son dos líneas apuntando a
    `LICENCE.md`, y los dos dicen BSD-3. Por eso se unen las identificaciones en vez de contar
    ficheros — ambiguo es que digan cosas DISTINTAS.

Y el TSV pasa a ser ACUMULATIVO. Una receta ya sembrada sale del conjunto de entrada porque ya tiene
`license`, así que regenerar el fichero entero borraba su cita — y la cita es el rastro de
auditoría, lo único que deja revisar un veredicto sin repetir el trabajo. Un fichero de evidencia
que se olvida de lo que ya probó no es evidencia.

Los 10 ArtifactHash afectados, idénticos antes y después.
2026-09-05 15:43:51 +00:00
Sergio ba1fb2d3a8 licencias: 95% (1114/1164) — la evidencia sale del tarball pineado, offline
`licencias.sh --sembrar` escribe desde una tabla curada a mano y `licencias-desambiguar.sh` resuelve
`-only` vs `-or-later` preguntándole a la búsqueda de código de GitHub. Los dos dejan fuera lo mismo:
lo que nadie curó y lo que no vive en GitHub.

Pero `work/tarballs/` indexa cada tarball por su sha256, así que el árbol EXACTO que la receta pinea
ya está en disco: la declaración del propio autor, en el commit que construimos, sin red. De las 76
sin licencia, 55 tenían su tarball cacheado y 25 salieron con evidencia citable.

`scripts/licencias-tarball.py` la busca en tres niveles: la declaración del autor (`Cargo.toml`,
`meson.build`), un único fichero en `LICENSES/` (REUSE, que usa KDE), y el texto del COPYING más la
CONCESIÓN buscada en las cabeceras de los fuentes — excluyendo COPYING/LICENSE, porque el apéndice
de la GPL trae literalmente «or (at your option) any later version» y buscarla ahí da siempre
positivo siendo plantilla. Es la regla que ya fijó `licencias-desambiguar.sh`, aplicada al árbol
pineado en vez de a GitHub.

La primera versión resolvía 40, y CUATRO estaban mal. Las dejo escritas porque son la forma del
error, no accidentes:

  · `socat` salía BSD-2 por su `COPYING.OpenSSL`, que es la excepción, no la licencia. Un `COPYING`
    a secas gana ahora a cualquier sufijado.
  · `pigz` salía Apache-2.0 por `zopfli/COPYING`: la licencia de una pieza VENDORIZADA leída como la
    del contenedor. Sólo se mira la raíz.
  · `openssh` salía MIT porque su `LICENCE` es un compendio de cuatro y me quedaba con la primera
    que pegara. Si el texto trae varias, no hay veredicto: lo compone un humano.
  · `nano` salía GPL-3.0-**or-later** citando el «either version 2» de su `aclocal.m4` — plantilla de
    autotools, no del proyecto, y encima de otra versión. Ahora la cita tiene que venir de un fichero
    del autor Y hablar de la misma versión mayor que el COPYING.

Y dos bugs míos que producían el mismo daño en silencio: la marca de BSD-3 era «Neither the name of»,
que libpcap y libzip no usan («The names of the authors may not be used to endorse») ⇒ se declaraban
BSD-2; y el mayor de versión lo sacaba de `"GPL-3.0".rsplit("-",1)[0][-1]`, que da «L», así que la
comprobación de coherencia rechazaba TODA cita válida.

La validación final no es una regex: un identificador vale si tenemos su texto en `licenses/`. La
obligación legal es acompañar el binario del TEXTO, así que un SPDX que no podemos entregar no
adelanta nada y sí crea una afirmación que no se sostiene. Eso es lo que atrapa el «GPL2+» que meson
deja escribir en `gsd-schemas` y `libgdm`, que no es un SPDX sino taquigrafía.

Nada se sembró a ojo: cada línea de `docs/licencias-evidencia.tsv` lleva la cita que la decidió, y
las 50 que quedan salen listadas con lo que SÍ se encontró en vez de rellenarse.

Comprobado que no se invalida nada: los 26 ArtifactHash afectados son idénticos antes y después
(`license` no está en `hash_inputs`) — medido, no supuesto.
2026-09-05 15:34:35 +00:00
Sergio 670a5b6b49 OBS Studio 32.2.2 — segunda app gráfica de usuario final, con el renderer portado a EGL
13 plugins sellados, entre ellos los que importan: linux-pipewire (captura de
pantalla en Wayland), obs-ffmpeg, obs-x264, obs-outputs (RTMP RTMP),
linux-pulseaudio/alsa y text-freetype2.

EL PORT. El glad de OBS hacía dlopen("libGL.so.1") + dlsym("glXGetProcAddressARB")
y devolvía 0 si no lo hallaba, o sea que el renderer no arrancaba: OBS estaba
atado a GLX —y por tanto a X11— aun corriendo en Wayland puro. Acá nadie publica
libGL.so.1 y el libglvnd del corpus va sin GLX a propósito. El parche carga por
libEGL.so.1 + eglGetProcAddress, que es lo que OBS ya usa para las extensiones.
Verificado en el artefacto, no en el log: libobs-opengl.so.30 tiene CERO
ocurrencias de glXGetProcAddressARB, sus NEEDED son libEGL.so.1 +
libwayland-egl.so.1, y el binario no filtra a glibc.

DÓNDE VIVE. En incoming-kde y no en el corpus porque su frontend es Qt6 y las 13
recetas Qt viven sólo en esa cola. Se midió antes de descartar el corpus: qtbase
sin X11 cierra en 26 nodos que YA están en el corpus, pero el qtbase de la cola va
xcb=ON, así que un qtbase de corpus tendría otro hash con el MISMO nombre de
artefacto ⇒ dos Qt peleando por /usr/lib/libQt6Core.so. Unificar obligaría a
apagarle xcb a KDE: radio 119.

Los símbolos indefinidos salieron por CAPAS y ninguno nombraba al culpable:
freetype (.a no PIC) → fontconfig (idem) → i2d_SSL_SESSION → inflateInit_. Las dos
primeras se arreglaron usando las variantes -shared que YA existían en el corpus;
las dos últimas con -lssl -lcrypto -lz, porque OBS resuelve curl con el FindCURL
de CMake, que toma libcurl.a por fichero y no lee su Libs.private. Un símbolo
indefinido nombra a la librería que lo USA, no a la que falta.

Huecos escritos en la receta para que no se descubran en la mano del usuario:
sin webcam (ENABLE_V4L2=OFF, libv4l2 no está en ninguna cola), sin salida MPEG-TS
(SRT/RIST ausentes) y sin scripting (falta swig). Grabar, capturar pantalla y
publicar por RTMP no pasan por ninguno de los tres.
2026-09-04 17:17:17 +00:00
Sergio 269e8410fd estado: cosecha granja 2026-09-04T15:02:12Z — avance del árbol KDE 2026-09-04 15:02:12 +00:00
SergioandClaude Opus 5 914c1b72af kcoreaddons: prender el módulo QML — el menú de Plasma ABRE, y detrás de él konsole
`-DKCOREADDONS_USE_QML=OFF` estaba desde que se escribió la receta, con el argumento razonable de
que un framework tier-1 no debería arrastrar QML. El precio no se vio hasta hacer CLIC en el
lanzador dentro de QEMU: `kickoff` importa `org.kde.coreaddons` y ese módulo lo instala esta receta
y ninguna otra ⇒ **el menú de aplicaciones no abría**. La librería C++ salía completa, sus 70
consumidores enlazaban bien y el perfil reportaba 100%.

Es la forma más pura del «sellado ≠ arranca»: no falta una librería, falta una porción OPCIONAL de
una librería que sí está. Ninguna métrica de clausura puede verlo — mide recetas, no features.

`qtdeclarative` ya estaba en `[deps].build`, así que prenderlo no agrega una dep: deja de tirar lo
que ya se podía construir.

VERIFICADO CON UN SOLO BUILD (56 s), a propósito, en vez de pagar la cascada para averiguarlo:
  · panel → menú abre (usuario, buscador, Favoritos/Todas, Aplicaciones/Lugares/Sesión)
  · buscar «konsole» + Enter → la terminal arranca y corre:
        uname -a         → Linux (none) 6.16.12 #1 SMP PREEMPT_DYNAMIC … x86_64
        konsole --version → konsole 25.04.3
Es la cadena completa del escritorio por primera vez: panel → menú → búsqueda → app → shell.

COSTO, medido antes de tocar y confirmado después: `yupana radio kcoreaddons` predijo 71, y el grafo
regenerado da exactamente **71 en deuda** (`escritorio-kde 192/263`). Queda como deuda DECLARADA
para una campaña de granja; la imagen de hoy corre con un kcoreaddons más nuevo que aquel contra el
que enlazaron sus consumidores, lo que es legítimo porque cruza un SONAME (misma ABI, sólo se suma
un módulo QML) — la misma regla que decidió la promoción de pipewire.

De yapa: `export SHELL=/bin/sh` en plasma-start-qemu.sh. El aviso rojo de konsole («Could not find
'', starting '/bin/sh' instead») era real y no venía de /etc/passwd —que dice /bin/sh— sino de que
konsole lee $SHELL y este getty no es un login shell.

Y el barrido que encuentra esto sin hacer clic queda escrito en el runbook: cruzar los `import` de
los `.qml` instalados contra los módulos con `qmldir`. Además de éste destapó `org.kde.kscreenlocker`
y `org.kde.newstuff.core`, sin diagnosticar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YGXe6mShYYw6V8ea1dQ13u
2026-09-03 21:57:38 +00:00
SergioandClaude Opus 5 cab9439644 fuentes: dejavu al corpus (arregla un wanted que dejé), KDE con fuente, y la nerd de monospace
TRES COSAS, y la primera es un bug mío de hace un rato.

1. dejavu-fonts PROMOVIDA AL CORPUS — arregla un nodo `wanted` que introduje.
   Al añadirla de raíz a escritorio-gnome quedó como `wanted`: la receta existía en
   incoming-{kde,wlr,cosmic} y NO en incoming-gnome ni en el corpus, y una receta no
   alcanza una cola hermana. O sea que la raíz no resolvía a nada y GNOME seguía sin
   fuentes. `wanted` NO es `debt`, así que drenaje.json seguía diciendo deuda=0 y el
   hueco no salía por ninguna métrica — se vio mirando el nodo en build-state-gnome.json.
   Promoción gratis: las tres copias sellaban el mismo hash (b3:5b3a5df3) y sus deps
   están vacías. Las tres se jubilan. Ahora los cuatro perfiles resuelven a corpus y los
   cinco grafos quedan con CERO nodos `wanted`.

2. dejavu-fonts en escritorio-kde, como se pidió. Tenía UNA fuente y de rebote, dentro
   de qtbase — apoyarse en un detalle de empaquetado de Qt deja sin nada a todo lo que
   no es Qt.

3. dejavu-fonts-nerd 3.5.1 en los CUATRO perfiles: DejaVu Sans Mono parcheada con Nerd
   Fonts. Lo que se midió antes de escribirla, porque cambia la forma de hacerla:

   - SE AÑADE, NO REEMPLAZA, y no es prudencia: la licencia de Bitstream Vera exige que
     una fuente modificada se RENOMBRE. Por eso upstream la llama «DejaVuSansM Nerd Font
     Mono» — leído del name de la TTF, no supuesto. Una fuente nerdeada NO puede
     responder al nombre de la original; sustituirla rompería a todo lo que pide «DejaVu
     Sans Mono», empezando por foot, que ya murió una vez así.
   - SÓLO LA MONOESPACIADA: upstream no publica DejaVu Sans ni Serif parcheadas, y en una
     fuente de interfaz proporcional esos glifos no los pide nadie. «Todas nerdeadas» no
     se puede cumplir al pie de la letra.
   - SÓLO UNA DE LAS TRES VARIANTES: NerdFont / NerdFontMono / NerdFontPropo son los
     mismos glifos con distinto avance. Las doce pesan 32 MB; las cuatro de Mono, 11 MB.
     Se quedan las Mono, que son las correctas para una rejilla de terminal. Referencia:
     la familia DejaVu ENTERA son 9,8 MB.

   ⚠ EL NÚMERO DEL .conf ESTÁ MEDIDO, NO ELEGIDO. fontconfig carga conf.d en orden
   alfabético y el <prefer> que llega antes gana. Con 60-nerd-monospace.conf —que ordena
   después de 60-latin.conf, que ya prefiere Noto/DejaVu/Inconsolata— `fc-match
   monospace` seguía dando DejaVu Sans Mono: la conf estaba INSTALADA Y ERA INERTE, el
   mismo modo de fallar que el plugin ALSA de PipeWire. A 59- gana. 45-latin.conf también
   menciona monospace pero usa <default>, no <prefer>, así que no compite.

   ⚠ Y strip_components = 0, que tampoco es cosmético: el tarball de nerd-fonts es PLANO
   y con el default de 1 el árbol de fuentes queda VACÍO — el build no se detiene ahí,
   sigue y falla más tarde en el cp, con un mensaje que no menciona la extracción.

   ⚠ LA LICENCIA NECESITA UNA PASADA HUMANA antes de `hammer pack`: el LICENSE.txt del
   tarball cubre sólo DejaVu/Bitstream Vera y no menciona los ~10 conjuntos de iconos
   importados, que tienen licencias propias (Font Awesome CC-BY-4.0, Octicons MIT,
   Material OFL, Powerline MIT…). El campo dice lo DOCUMENTADO, no el conjunto real; no
   se inventa una cadena SPDX. Anotado en la receta.

EVIDENCIA, contra el conf.d REAL del artefacto de fontconfig:
  monospace          -> DejaVuSansM Nerd Font Mono   (los iconos llegan)
  "DejaVu Sans Mono" -> DejaVu Sans Mono             (intacta)
  sans-serif         -> DejaVu Sans                  (sin tocar)
  serif              -> DejaVu Serif                 (sin tocar)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo
2026-09-03 16:09:24 +00:00
Sergio 3448ca4678 estado: cosecha granja 2026-09-03T06:02:15Z — avance del árbol KDE 2026-09-03 06:02:15 +00:00
Sergio f19b8b3e4a jubilar 13 copias de cola que sellan IDÉNTICO al corpus — y de paso el grafo deja de mentir
Continúa lo que ya se hizo el 2026-09-02 con las 8 copias de gnome. Medido receta por receta con
`hammer hash`: de los 30 nombres que viven en el corpus Y en alguna cola, 13 dan el MISMO
ArtifactHash que su gemela del corpus y 22 son variantes deliberadas (glib/gtk4/pango de gnome,
dbus/openssl/libxml2 de kde…) que NO se tocan.

Se van las 13 redundantes: alsa-lib ×3, nasm ×2, zlib-shared ×2, y de incoming-kde ffmpeg,
fontconfig-shared, freetype-shared, libjpeg-turbo-shared, libpng-shared y vulkan-headers. Cada
consumidor las resuelve ahora en el catálogo PADRE, con el mismo hash.

VERIFICADO ANTES Y DESPUÉS, no argumentado: se snapshotearon los 47 consumidores directos, se
borraron las 13, y se re-hashearon. **0 consumidores vivos con hash distinto** (las 4 diferencias
son las propias recetas borradas, que se consumían entre sí). Cero rebuild.

EL EFECTO QUE NO SE BUSCABA Y ES EL MÁS VALIOSO: `build-state.json` guarda sus nodos POR NOMBRE, y
cuando un nombre vive en dos colas la membresía se consulta por el par `(cola, nombre)` de UNA sola
de ellas. Resultado: `ffmpeg`, `alsa-lib`, `vulkan-headers` y `zlib-shared` reportaban
`perfiles: []` —o sea "no está en ninguna imagen"— **mientras estaban en las cuatro**. Ahora dicen
la verdad, y `escritorio-kde` pasa de 183 a 185 porque aparecen dos nodos que el grafo no contaba.

La lección para el próximo análisis, que ya quedó en `scripts/vigia-sonames.py`: sobre el grafo se
pregunta con `yupana.membresia()`, que llavea por `(cola,nombre)`; el campo `perfiles` del JSON es
fiable sólo mientras el nombre viva en una sola cola.

Sin cambios en la deuda: cosmic sigue 105/106 por el OOM de xdg-desktop-portal-cosmic.
2026-09-03 05:13:21 +00:00
Sergio 5e6b3631e2 pipewire ×3: ALSA pasa a ser la ABI de audio de la distro — el flag no alcanzaba
Las tres recetas pasan a `-Dpipewire-alsa=enabled`. Sirve a TODA app ALSA del corpus, no sólo a mpv:
un cliente que abre "default" desemboca en PipeWire por `libasound_module_pcm_pipewire.so` en vez de
pelearle la tarjeta al servidor. Es protocolo en vez de ABI compartida — la misma figura con la que
el ADR 0015 cruza el borde de la jaula.

EL FLAG SOLO NO HACE NADA, y ésta es la parte que no se ve venir: meson deja los plugins en
`/usr/lib/alsa-lib` (bien, ahí los busca alsa-lib) pero la CONFIGURACIÓN en
`/usr/share/alsa/alsa.conf.d`, **un directorio que alsa-lib no lee**. Sus `@hooks` cargan
`/var/lib/alsa/conf.d`, `/usr/etc/alsa/conf.d` y `/etc/alsa/conf.d` — leído del `alsa.conf` del
artefacto sellado, no supuesto. Sin el enlace que agrega la fase install, el plugin queda instalado
y no lo usa nadie: sellado e inerte, que es la familia de fallo del artefacto vacío. Se enlazan los
DOS ficheros: `50-pipewire.conf` hace que el destino EXISTA, `99-pipewire-default.conf` hace que sea
el destino POR DEFECTO — sin el segundo, mpv abriendo "default" no llega igual.

EVIDENCIA (test discriminante, porque "no falla" no prueba nada acá):
  mpv --audio-device=alsa/pipewire  → abre el device, falla al conectar (no hay demonio) ⇒ el PCM
                                      ESTÁ DEFINIDO
  mpv --audio-device=alsa/noexiste  → "ALSA lib: Unknown PCM noexiste"  ⇒ el control
El camino de verdad —que suene— sólo se puede ejercer con un PipeWire vivo, o sea en la sesión; eso
no se probó y no se afirma.

⚠ PRECIO, escrito para que no se diagnostique mal: con `99-pipewire-default.conf` puesto,
`pcm.!default` ES PipeWire. En una máquina donde PipeWire no esté corriendo, un cliente ALSA ya no
cae a la tarjeta: no suena. Es el trato que hace toda distro con pipewire-alsa.

Radio medido antes de tocar (`yupana radio pipewire`): 4 cosmic / 3 gnome / 2 kde. Reconstruidos 10
de 11 dependientes.

⚠ DEUDA DECLARADA, 1: `incoming-cosmic/xdg-desktop-portal-cosmic` murió DOS VECES por OOM (7 G de
RAM, sin cgroups, y otro agente compilando Rust a la vez — `dmesg` confirma «Out of memory: Killed
process (cargo)»). No es un fallo de la receta ni del cambio: es la máquina. Queda visible en el
grafo (escritorio-cosmic 105/106) en vez de escondido, y lo levanta el worker o un reintento con la
máquina libre.

Los otros tres perfiles cierran: KDE 183/183, GNOME 132/132, sway 140/140.
2026-09-03 05:11:47 +00:00
Sergio 520f1d5279 polkit (variante KDE) + polkit-qt-1 0.201.1: Plasma ya puede pedir autorización
Tercer y cuarto hueco de RUNTIME del triaje. Sin polkit-qt-1, Plasma no puede
elevar privilegios: ni montar un disco, ni cambiar ajustes del sistema.

Son DOS recetas porque hacía falta una segunda polkit. Hammer resuelve las deps
hermano→padre —la cola propia, después recipes/— y nunca cruza a una cola hermana,
así que la polkit de incoming-gnome es invisible desde incoming-kde. Y aunque se
viera no serviría: aquélla va con -Dintrospection=true contra glib-introspected,
que es la ISLA DINÁMICA del shell de GNOME (gjs importa gi://Polkit y necesita el
typelib). KDE enlaza las libs desde C++ y el typelib le sobra; traerlo obligaría a
meter gobject-introspection entero en la cola.

La nueva es homónima a propósito, mismo patrón deliberado que dbus (incoming-kde vs
raíz) y gmp (incoming-kde vs incoming-cosmic), con el mismo coste conocido:
store-gc no puede decidir por NOMBRE cuál de los dos sellados es el vigente. No la
renombré a polkit-kde porque el .pc que busca polkit-qt-1 es polkit-gobject-1, no
el nombre del paquete: renombrar sólo movería el problema al lector.

Radio medido antes de escribirla (yupana radio polkit): la de incoming-gnome tiene
6 dependientes transitivos y no se toca; la nueva, 0. Cero daño colateral.

Nada de esto necesitó descubrirse: glib-shared ya existía en la cola KDE y su
propio encabezado nombraba a polkit como uno de los motivos por los que se escribió.

── El guardián que sí hizo falta ────────────────────────────────────────────────
polkit-qt-1 sondea polkit con check_function_exists, que COMPILA Y ENLAZA. Si ese
enlace falla por algo del sandbox —y no porque la función falte—, cmake NO da
error: imprime «You have an older polkit-1 version» y define
POLKIT_QT_1_COMPATIBILITY_MODE. El build sella, el artefacto pesa lo esperado y la
autorización queda recortada sin que nadie se entere. La fase configure ahora
aborta si HAVE_POLKIT_SYSTEM_BUS_NAME_GET_USER_SYNC no llegó a 1 en el header
generado: polkit 127 tiene esa función, así que un 0 significa «el sondeo no pudo
enlazar», no «polkit es viejo». Pasó: no hay modo compatibilidad.

También va -DQT_MAJOR_VERSION=6 explícito. El default del CMakeLists es "5", y sin
la flag construiría bindings con otros nombres (polkit-qt5-1) que el dependiente
no encontraría hasta mucho después.

── Lo que esto NO enciende, a propósito ─────────────────────────────────────────
Los dos consumidores siguen esquivando polkit igual que antes:
  · kauth construye con el backend polkit OPCIONAL apagado (cae al backend fake);
  · plasma-workspace apaga el helper de Región&Idioma con -DGLIBC_LOCALE_GEN=OFF
    -DGLIBC_LOCALE_PREGENERATED=ON, que es justo lo que evita el PolkitQt6-1
    REQUIRED.
Encenderlos es otra decisión con su propio radio (plasma-workspace arrastra medio
escritorio). La pieza está puesta; la palanca no se toca sin pedirlo.

⚠ Y con las librerías viaja la postura de seguridad que ya declaraba
arje-polkit-compat: el demonio responde is_authorized=true a TODO. Estas libs son
la INTERFAZ que el escritorio espera, no la política. Queda repetido en las dos
recetas nuevas porque son las que ponen la pieza en manos del escritorio.

Las dos REPRODUCEN bit a bit (verificar-repro.sh 2/2). Los NEEDED de
libpolkit-qt6-core-1 son exactamente los esperados: Qt6DBus, Qt6Core,
libpolkit-gobject-1, gio/gobject/glib y libc.

corpus 788/788 · escritorio-kde 171/171 · grafo CIERRA · gate --check OK
Queda 1 wanted en KDE: xwayland — y ése no es deuda técnica sino una decisión
(X11 al tacho, Xwayland = compat opcional por-imagen, no en el core).
2026-09-03 00:38:55 +00:00
Sergio de660fc10f qqc2-breeze-style 6.7.2: el estilo QML de Plasma sellado — KDE pasa de 3 wanted a 2
Segundo hueco de RUNTIME del triaje de la frontera. Nadie lo pide para construir
—por eso el escritorio sellaba completo sin él— pero sin este módulo los controles
QML de Plasma (botones, sliders, combos, los menús de los applets y de los KCM) se
dibujan con el estilo genérico de Qt. No lo reemplaza qqc2-desktop-style: aquél es
el estilo de escritorio integrado con KStyle; éste es la implementación QML nativa
de Breeze, la que Plasma 6 usa por defecto.

Dos cosas que no eran obvias:

1. Se llama casi igual que el vecino y viene de otro tarball. qqc2-DESKTOP-style
   sale de Frameworks 6.27.0; qqc2-BREEZE-style sale del release de Plasma 6.7.2,
   el mismo de breeze/kwin/plasma-workspace. Copiar la URL del vecino da 404.
   El sha256 va contrastado contra el .sha256 que publica KDE al lado del tarball,
   no sólo contra lo que bajó acá: la primera descarga volvió con 0 bytes y su
   sha256 era el de la cadena vacía — un vacío que se lee como éxito.

2. La lista de deps no es la del vecino copiada: sale de la clausura de
   find_dependency de los KF6*Config.cmake que ya están en el store. Ese recorrido
   enseñó algo reutilizable: casi todo lo que esos configs piden (X11, XCB,
   Wayland, OpenSSL, BZip2, LibLZMA) vive dentro de un `if (NOT TRUE)` — la rama
   de build ESTÁTICO — y por lo tanto es código muerto en nuestro corpus, que
   compila KF6 dinámico. Por eso acá no hay libX11 ni xorgproto, coherente con
   Wayland-only. El find_package(X11) del CMakeLists raíz no es REQUIRED, así que
   falla en silencio sin romper el feature_summary(FATAL_ON_MISSING_REQUIRED).
   Confirmado a posteriori: los NEEDED del plugin son exactamente los 5 KF6 que la
   clausura predijo (KirigamiPlatform, IconThemes, ColorScheme, GuiAddons,
   ConfigCore) más Qt6 Quick/Gui/DBus/Core.

La fase install verifica por CONTENIDO, no por presencia: qmldir de org.kde.breeze
y de org.kde.breeze.impl no vacíos, Button.qml presente y el plugin de plataforma
de kirigami instalado. Un módulo QML sin su qmldir ocupa disco y arranca con el
estilo genérico sin decir nada. Salieron 83 controles y 3 .so.

Selló al primer intento y REPRODUCE bit a bit (verificar-repro.sh 1/1).

corpus 788/788 · escritorio-kde 166/166 · grafo CIERRA · gate --check OK
Quedan 2 wanted en KDE: xwayland y polkit-qt-1.

Nota sobre el diff de los cinco grafos: cambian los `dependientes_total` de las
deps de esta receta en TODAS las vistas, no sólo en --kde. Es correcto y está
documentado en build-state.py: ese campo se calcula sobre el grafo entero (todas
las colas del disco), que es la corrección del bug de libdrm.
2026-09-02 23:40:21 +00:00
SergioandClaude Opus 5 42db2dfb35 gmp: las dos recetas son variantes DELIBERADAS, no un duplicado — queda escrito
Yo mismo las reporte como "la misma clase de colision que onda1" y me pase: no
lo son. onda1 tenia una copia RANCIA del mismo build; esto son dos builds
distintos, cada uno correcto para su frente:

    KDE     link=dynamic  --enable-shared --enable-cxx  => libgmp.so + libgmpxx.so
    COSMIC  link=static   --disable-shared              => libgmp.a, sin C++

Las dos citan libqalculate y llegan a conclusiones opuestas sobre gmpxx.h, y las
dos tienen razon para su cola. Unificarlas romperia una de las dos.

Lo que compartir nombre SI cuesta es que hace ambigua la clasificacion de
store-gc: un artefacto rancio de una puede caer como SUPERADO porque la otra
tiene sellado vigente. La condicion es precisa y esta medida — solo hay riesgo si
el hash vigente de una NO esta sellado, y hoy las dos lo estan => exposicion
CERO. Antes de podar con nombres compartidos hay que comprobar ESO, no el nombre.

La salida, si algun dia molesta, es renombrar la dinamica a gmp-shared (la
convencion que el corpus ya usa: zlib-shared, cairo-shared...). No se hizo
porque cuesta:  da 7 sellados de KDE que caen a deuda.  es
el mismo par por la misma razon.

Los comentarios NO entran en hash_inputs (medido: mismo hash antes y despues),
asi que esto no re-hashea nada.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 20:33:11 +00:00
sergioandClaude Opus 5 0ac421b516 libsndfile: su configure sólo busca python2.x — tumbaba CUATRO recetas y parecía fallo de cada una
COSMIC cerró 25 de 30 raíces. De los 5 fallos, CUATRO daban el mismo mensaje —
«error: no suitable Python interpreter found»— en wireplumber, xdg-desktop-portal,
xdg-desktop-portal-cosmic y cosmic-settings-daemon.

NO ERA DE ELLAS, Y NI SIQUIERA ERA DE MESON. El error viene de un `configure` de AUTOTOOLS que
prueba `python2.2`, `python2.1`, `python2.0` —literalmente— y aborta al no hallarlos. Se
identificó por las flags del comando en el log (`--disable-mpeg --disable-full-suite`), que son
inconfundibles de **libsndfile**: una dep común a las cuatro.

Y declarar `python3` en `[deps]` NO ayuda —dos de las cuatro ya lo tenían—: el problema no es
que falte el intérprete, es que el script no reconoce ese NOMBRE. Autoconf respeta la variable
de entorno `PYTHON`, así que se le pasa `PYTHON=python3` y sella.

LA LECCIÓN, que hoy ya se repitió con `dbus-shared`: cuando varias recetas fallan con el MISMO
mensaje raro, el fallo está en una dep común — y **la forma de identificarla es mirar QUÉ
configure/meson.build lo emite**, no la receta que se estaba construyendo. Las flags del comando
y el número de línea del meson.build son la firma del paquete que realmente muere.

Aplicado a las tres copias (incoming-gnome, -cosmic, -kde), que dan el mismo hash. Y de paso
`cosmic-settings-daemon` sí necesitaba `python3` en deps, que no lo declaraba: dos causas
distintas bajo un mensaje idéntico.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 01:17:01 -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 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 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
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 4.8 24d9fa7fdd kde/deps: libXft — declarar expat y dejar asentado por qué queda diferido
La cadena de deps .pc SÍ quedó resuelta (libpng+expat añadidos); el muro restante es PIC
(freetype.a/libpng.a/expat.a no-PIC dentro de libXft.so), no resolución. Nadie lo consume:
plasma-workspace (su único declarante) selló sin él — KDE es Wayland, Xft es X11 legacy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 21:44:55 -04:00
sergioandClaude Opus 4.8 44d06a899e kde: kwindowsystem KWINDOWSYSTEM_QML=ON — construye el módulo QML org.kde.kwindowsystem
Elimina el injerto del artefacto viejo que destrababa la sesión Plasma anidada.
Desktop.qml de plasma-workspace importa ese módulo; sin él plasmashell falla
"module not installed". qtdeclarative ya estaba en deps. Rebuild va a la granja.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 20:04:59 -04:00
sergioandClaude Opus 4.8 e6a62a04fb kde: anotar deuda KWINDOWSYSTEM_QML=OFF en el recipe (rompe Desktop.qml de plasmashell)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 17:29:11 -04:00
sergioandClaude Opus 4.8 9d96d4f59c kde: diferir libXft — huérfano PIC, nadie lo consume
libXft es el único de los 11 que no sella. Falla por PIC (freetype/libpng/expat
estáticas no-PIC dentro de un .so), riesgo que su propio header ya predecía. NADIE
lo consume: plasma-workspace (su único declarante) selló SIN él porque KDE es Wayland.
Forzarlo sellaría un artefacto muerto. A .deferred/ para que el loop no lo reintente;
la cadena de deps .pc quedó resuelta (libpng+expat), sólo resta el muro PIC (Capa 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 14:59:41 -04:00
sergioandClaude Opus 4.8 7ba0b8abf9 kde: destrabar los 11 que no sellaban — 2 causas raíz
- libcanberra: URL de 0pointer.de muerta → mirror BLFS/OSUOSL (mismo tarball, sha256
  idéntico verificado). Desbloquea 7: knotifyconfig/konsole/plasma-{desktop,pa,workspace}/powerdevil.
- cadena X11 (deps .pc faltantes, recetas ya existían): libICE/libSM += xtrans;
  libXft += libpng (freetype2.pc); libXtst += libXfixes (xi.pc). Desbloquea plasma-workspace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 12:06:19 -04:00
sergioandClaude Opus 4.8 8f7109f4e9 harkaq: el barrido queda en 0 IRREDUCIBLES — perl ya existía (§4.11)
La única deuda irreducible del barrido (§4.10) era /usr/bin/perl en
ca-certificates y curl. Dos hallazgos al abrirla:

1. EL COMENTARIO DE ca-certificates.toml YA LO DECÍA, escrito por quien la portó:
   "El resto del build (mk-ca-bundle.pl → cert.pem → split-ca-bundle.sh) usa el
   perl + coreutils del rootfs". La deuda estaba escrita EN PROSA y era invisible
   para el sistema; harkaq la convirtió en un veredicto. Es la tesis del §0 en una
   línea: no hace falta que nadie DESCUBRA nada, hace falta que la máquina pueda
   VER lo que ya se sabía.

2. LA RECETA TAMBIÉN EXISTÍA: recipes/incoming-kde/perl.toml, importada el 13/07
   para la campaña KDE (syntax-highlighting e intltool exigen perl). CUARTA
   convergencia independiente: dos campañas necesitaban el mismo binario y
   llegaron por caminos que no se hablan.

Construye tal cual (b3:c7a899bd…) y con el artefacto en el store:
    /usr/bin/perl → declarar dep: perl     exit=0 ⇒ CERO deuda irreducible

EL BARRIDO DE 24 RECETAS QUEDA EN 0 IRREDUCIBLES. La métrica del §7 (<5%) se
cumple midiendo lo que la métrica quería medir: cosas que no sabemos construir.
Resultado: ninguna.

Receta promovida a recipes/perl.toml (no había canónica ⇒ sin colisión). Lo que
queda es mecánico y no es diseño: declarar `make` en las ~10 recetas que lo usan
y `perl` en ca-certificates/curl. OJO: eso re-hashea sus artefactos y son
paquetes del base-system (índice firmado 748) ⇒ decisión de rollout, no un sed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 18:51:32 -04:00
sergioandClaude Opus 4.8 964a6931d2 kde/Plasma: spectacle SELLA — la CAPTURA DE PANTALLA (la app más cara de la campaña)
spectacle 6.7.2 (7a6db883) → /usr/bin/spectacle. Cierre VERIFICADO, los 6 componentes de la cadena:
libKPipeWireRecord.so.6 + libopencv_core.so.410 + libopencv_imgproc.so.410 + libtesseract.so.5.5 +
libKF6PrisonScanner.so.6 + libKQuickImageEditor.so.1.

Cadena nueva completada en esta tanda:
  ffmpeg 7.1            faafef5e  libavcodec/avutil/avformat/avfilter/swscale — kpipewire los exige los
                                  4 REQUIRED. ffmpeg NO usa autotools: su configure toma --cc/--ar/
                                  --ranlib, y hay que darle wrappers de UN SOLO TOKEN (--ar="zig ar" con
                                  espacio se ejecutaría como binario único — mismo gotcha que el AR de
                                  los crates 'cc'). **--disable-autodetect** = determinismo: sin él
                                  configure escanea el sandbox y activa libs a discreción.
  libva 2.22.0          121cd0de  libva.so + libva-drm.so, REQUIRED por kpipewire. Sólo la capa de
                                  despacho; los drivers reales son RUNTIME (dlopen). Sólo backend DRM.
  kpipewire 6.7.2       745665f3  KPipeWire + KPipeWireRecord. Deps: pipewire + ffmpeg + libva + gbm/EGL
                                  (mesa) + libepoxy.
  kquickimageeditor     0a4f8156  **BUMP 0.5.0 → 0.6.2.1**: spectacle 6.7 incluye
                                  <KQuickImageEditor/AnnotationDocument>, que NO existe en la serie 0.5
                                  (no tiene src/annotations). La 0.6.x suma deps propias: KF6Config
                                  REQUIRED + OpenCV 4.7 (stack blur, WITH_OPENCV=TRUE por defecto).

Por qué era cara: TODO en spectacle es REQUIRED y casi nada degradable. En particular **KPipeWire no se
puede esquivar**: find_package va sin REQUIRED y set_package_properties lo marca TYPE REQUIRED (eso sí se
degrada con sed), pero src/CMakeLists.txt:101 linkea K::KPipeWireRecord INCONDICIONALMENTE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:08:58 -04:00
sergioandClaude Opus 4.8 8207207251 kde/Plasma: pipewire 1.2.7 — el SERVIDOR de audio real (+ destraba la cadena de spectacle)
pipewire (6d15a22c) → libpipewire-0.3.so.0 + libspa-* + daemon 'pipewire' + **'pipewire-pulse'** (habla
el protocolo PulseAudio, así que los clientes libpulse ya sellados le hablan) + tools (pw-cli/pw-play/
pw-record/pw-mon/pw-dump/...). Cierra el lado SERVIDOR del audio: hasta ahora sólo teníamos el CLIENTE
(libpulse con -Ddaemon=false).

Dos frentes lo necesitaban: (1) audio real de Plasma 6; (2) spectacle → kpipewire → pipewire.

Fuente del gitlab.freedesktop.org (como networkmanager/modemmanager). Recortado al core+SPA: sin bluez5
(arrastraría los códecs aptx/ldac/aac/opus), sin jack/v4l2/libcamera/gstreamer/ffmpeg/vulkan/roc/lv2/
avahi/x11/echo-cancel-webrtc/libusb/flatpak/snap; systemd/logind/selinux/rtkit off (no hay systemd).
alsa+sndfile+libpulse+dbus+udev enabled (las 4 ya selladas).

GOTCHA static-vs-shared (variante nueva del patrón): **sin ncurses a propósito**. Su única consumidora es
la tool pw-top (monitor de terminal), guardada por 'if ncurses_dep.found()'. El ncurses del catálogo es
static-only y su .pc arrastra '-static' al link ⇒ 'error: using shared libraries requires dynamic linking'
al enlazar pw-top contra libpipewire-0.3.so. Quitando la dep, meson saltea pw-top y el resto construye.
(Alternativa futura si se quiere pw-top: variante ncurses-shared.)

Próximo: ffmpeg → kpipewire → spectacle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:52:51 -04:00
sergioandClaude Opus 4.8 abd7337069 kde/Plasma: tesseract/leptonica/kquickimageeditor — cadena de spectacle (queda 1 blocker: KPipeWire)
Selladas:
  leptonica 1.85.0        e80a5d36  procesamiento de imagen; dep dura de tesseract. Codecs recortados a
                                    las variantes .so/PIC que ya tenemos (libjpeg-turbo-shared +
                                    libpng-shared + zlib-shared); TIFF/WEBP/OPENJPEG/GIF off.
  tesseract 5.5.0         08c05238  OCR. spectacle lo exige DURO: pkg_check_modules(TESSERACT REQUIRED)
                                    en CMakeLists:111, sin option() para apagarlo. Sólo la lib (sin
                                    training tools, que piden pango/cairo/icu).
  kquickimageeditor 0.5.0 3d4bd904  editor de imagen QtQuick; spectacle lo marca TYPE REQUIRED.

spectacle.toml se commitea CON su blocker documentado en la cabecera (misma convención que usaba
networkmanager-qt): **KPipeWire**. find_package(KPipeWire) va sin REQUIRED y set_package_properties lo
marca TYPE REQUIRED (eso se degrada con sed), PERO src/CMakeLists.txt:101 linkea
INCONDICIONALMENTE ⇒ no hay forma de compilar sin él. Falta la cadena pipewire → (ffmpeg, para
KPipeWireRecord) → kpipewire.

El resto de su cadena YA quedó resuelto y sellado esta sesión: opencv + prison-scanner + zxing-cpp +
tesseract + leptonica + kquickimageeditor + xcb-util-cursor (sin este último: 'No suitable backend
platform was found ... XCB-CURSOR').

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:45:30 -04:00
sergioandClaude Opus 4.8 b68970675b kde/Plasma: zxing-cpp 2.3.0 + prison-scanner (KF6PrisonScanner) — cadena de spectacle
zxing-cpp 2.3.0 (c98afd82) → libZXing.so: decodificador/codificador de códigos de barras y QR.
prison-scanner 6.27.0 (cbfd6dcc) → libKF6Prison.so.6 + **libKF6PrisonScanner.so.6**.

Por qué la variante: el prison canónico de esta cola se selló con WITH_ZXING=OFF/WITH_MULTIMEDIA=OFF ⇒ no
provee KF6::PrisonScanner, y spectacle corta el build en seco:
  if (NOT TARGET KF6::PrisonScanner) message(SEND_ERROR "Prison built without required PrisonScanner")
prison-scanner activa WITH_ZXING=ON + WITH_MULTIMEDIA=ON (qtmultimedia ya sellado). Nombre distinto para
NO re-hashear el prison que ya consumen plasma-workspace/plasma-nm — mismo patrón que kcoreaddons-QML /
kwindowsystem-QML / qcoro-shared.

GOTCHA zxing: hay que compilar **READERS *y* WRITERS**. Con ZXING_WRITERS=OFF el header ZXing/BitMatrix.h
ni se instala, y prison NO sólo escanea — también GENERA códigos (zxingutil.cpp/pdf417barcode.cpp lo
incluyen) ⇒ 'fatal error: ZXing/BitMatrix.h file not found'.

spectacle sigue sin construir: además exige (sin flag para apagarlos) pkg_check_modules(TESSERACT REQUIRED
tesseract) — OCR, arrastra leptonica — y kquickimageeditor TYPE REQUIRED.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:37:17 -04:00
sergioandClaude Opus 4.8 e07e316c98 kde/Plasma: opencv 4.10.0 (core+imgproc) — dep de spectacle
opencv (79526f4b) → libopencv_core.so.4.10 + libopencv_imgproc.so.4.10 + opencv4.pc. spectacle (la
herramienta de captura de pantalla) lo exige: find_package(OpenCV 4.7 REQUIRED core imgproc), lo usa en
src/QtCV.h.

OpenCV es enorme (~95MB de fuente, decenas de módulos): se recorta con **BUILD_LIST=core,imgproc** (CMake
ni configura el resto) + todo OFF (apps/tests/docs/python/java/protobuf/DNN/GUI/video/ffmpeg/IPP/TBB/CUDA/
OpenCL/codecs). Los codecs WITH_* van OFF porque viven en imgcodecs, que no construimos.

**GOTCHA zig-wrapper DURABLE (2da vez que aparece, ahora documentado):** el wrapper clásico de esta cola
arma la lista de args en $a SIN comillas ⇒ SPLITEA cualquier arg con espacios. OpenCV pasa
-DOPENCV_ALLOCATOR_STATS_COUNTER_TYPE="long long" ⇒ zig recibe 'long' suelto y falla con
'error: long: unrecognized file extension'. Fix acá: wrapper PASS-THROUGH con "$@" (OpenCV no es
ECM/KDE, no necesita el filtro de -Wl,--fatal-warnings). Es el mismo bug que ya había pegado en
libkscreen (moc_predefs con -I"dir1 dir2").

spectacle NO construye todavía: además de OpenCV exige KF6::PrisonScanner, y el prison sellado se hizo
con WITH_MULTIMEDIA=OFF (sin el componente Scanner, que pide ZXing + Qt Multimedia).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:32:58 -04:00
sergioandClaude Opus 4.8 e8ab362dd4 kde/Plasma: kinfocenter + kmenuedit (info del sistema y editor de menú)
kinfocenter 6.7.2 (9dee4f29): bin kinfocenter + KCMs de hardware (kcm_cpu/interrupts/kwinsupportinfo/
xserver/opencl/energyinfo/...). kmenuedit 6.7.2 (d13a64f4): editor del menú de aplicaciones. Ambos sin
recetas nuevas.

DEUDA REGISTRADA — qtbase sin Vulkan: el KCM about-distro ('Acerca de este sistema') incluye
<QVulkanInstance>/<QVulkanFunctions> tanto en sus helpers (opengl-helper/vulkan-helper) como en
GPUEntry.h. Esos headers SÓLO los genera Qt6Gui si qtbase se configuró con Vulkan, y el qtbase sellado
NO lo tiene (vulkan-headers/vulkan-loader están sellados, pero los usa kwin directo, no Qt). Se podó el
KCM entero: activar vulkan en qtbase cascadearía un rebuild de TODO el stack Qt/KF6/Plasma (horas), como
ya se vio con el fix de zlib-shared → kwin(1825 obj)+plasma-workspace(1962 obj). Pendiente para una
próxima cascada planificada de qtbase (junto con otras features que falten).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:18:59 -04:00
sergioandClaude Opus 4.8 52ca9de8b7 kde/Plasma: systemsettings 6.7.2 — el CENTRO DE CONFIGURACIÓN
systemsettings (4c304dd8) sella a la PRIMERA: bin /usr/bin/systemsettings, NEEDED libKF6KCMUtils.so.6 +
libKF6KCMUtilsCore.so.6 + libPlasmaActivities.so.7. Cero recetas nuevas (todas las deps ya selladas) y
sin pelear DocTools: systemsettings lo declara en OPTIONAL_COMPONENTS.

Era el hueco más grande del escritorio: los KCMs se habían apagado para poder compilar plasma-desktop, y
sin systemsettings no hay shell donde alojarlos. Ahora existe el contenedor + ya hay KCMs reales
construidos por otras piezas de esta sesión: kcm_networkmanagement (plasma-nm), kcm_pulseaudio
(plasma-pa), kcm_powerdevilprofilesconfig (powerdevil), kcm_kscreen (kscreen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:14:32 -04:00
sergioandClaude Opus 4.8 3e0194609a kde/Plasma: plasma-pa SELLA — el APPLET DE VOLUMEN, frente de AUDIO cerrado
plasma-pa 6.7.2 (51d7a25b): applet QML org.kde.plasma.volume + kcm_pulseaudio + audioshortcutsservice.
Cierra el frente de audio: hasta ahora el lab sólo tenía libcanberra con backend NULL (sin reproducción).
Cadena completa nueva:
  alsa-lib/speexdsp/libsndfile → pulseaudio (cliente) → pulseaudio-qt → plasma-pa

pulseaudio 17.0 (108cac6e) → libpulse.so.0 + libpulse-mainloop-glib.so.0 + libpulse-simple.so.0 (+ .pc).
  - **-Ddaemon=false -Dclient=true**: se construye SÓLO la biblioteca cliente. Es lo correcto acá — el
    servidor de audio previsto es PipeWire (habla el protocolo PulseAudio) pero los clientes igual
    linkean el libpulse de PulseAudio. Evita todo el árbol de módulos del daemon (alsa/bluez/jack/
    avahi/orc/fftw/webrtc-aec).
  - -Dglib=enabled es OBLIGATORIO (sin él no hay libpulse-mainloop-glib, que plasma-pa exige);
    lo habilita glib-shared.
  - **GOTCHA lld durable**: PulseAudio comparte UN map-file (version script) entre libpulse,
    libpulse-simple y libpulse-mainloop-glib ⇒ al enlazar cada una, el script asigna PULSE_0 a símbolos
    que viven en las OTRAS: 'version script assignment of PULSE_0 to symbol pa_glib_mainloop_new failed:
    symbol not defined'. GNU ld sólo avisa; ld.lld (el de zig) lo trata como ERROR desde lld 17. Fix:
    -Dc_link_args=-Wl,--undefined-version.

pulseaudio-qt 1.8.1 (c6849b9e) → libKF6PulseAudioQt.so.5, selló a la primera. OJO: NO está en el path de
plasma/ sino en download.kde.org/stable/pulseaudio-qt/, y la versión viva es 1.8.x (1.6.0 del
find_package es sólo el mínimo).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:12:01 -04:00
sergioandClaude Opus 4.8 85cfb02d4d kde/Plasma: powerdevil + kscreen (energía y pantallas) + base de AUDIO (alsa-lib/speexdsp/libsndfile)
powerdevil 6.7.2 (299af51a): daemon de energía + acciones (suspendsession/dimdisplay/dpms/
brightnesscontrol) + KCMs. kscreen 6.7.2 (ef6218e6): kcm_kscreen + kscreen KDED + kscreen-console +
hdrcalibrator.

Base de audio REAL (el lab sólo tenía libcanberra con backend NULL, sin reproducción):
  alsa-lib 1.2.14   c6896caf  libasound.so.2 (--disable-python)
  speexdsp 1.2.1    dc235b15  libspeexdsp.so.1 (resampler de PulseAudio)
  libsndfile 1.2.2  c44d0142  libsndfile.so.1 (--disable-external-libs: sin FLAC/Opus, que no están
                              sellados; WAV/AIFF/AU basta para sonidos del sistema). Necesita python3.
Siguiente eslabón: pulseaudio → pulseaudio-qt → plasma-pa (applet de volumen).

3 lecciones de la depuración de powerdevil (dep-set de 69):
- ** FALTABA** y el síntoma era engañoso: 'Could NOT find KF6 (missing: KIO KCMUtils
  XmlGui)'. La cadena real es KF6ConfigWidgets→find_dependency(KF6WidgetsAddons) ausente ⇒ ConfigWidgets
  NOT_FOUND ⇒ cascadea a XmlGui/KIO/KCMUtils. Para diagnosticar hay que seguir los 'could not be found
  because dependency X' hacia ARRIBA, no fiarse de los componentes que CMake lista.
- **PlasmaWaylandProtocols/WaylandProtocols/qtwayland** son deps directas de todo lo que toca Wayland
  (powerdevil, kscreen). Idem los QML modules (kscreen: org.kde.kitemmodels + org.kde.plasma.plasma5support
  → kitemmodels/plasma5support directos; ambos YA traen su qml/, no hacía falta variante QML=ON).
- **timeout del build**:  mató powerdevil a mitad del rebuild de plasma-workspace (mi
  cambio de zlib-shared cascadeó kwin[1825 obj]+plasma-workspace[1962 obj]). Usar timeouts largos
  (9000) para recetas con dep-sets grandes. Además: 24778 AUTO-MATCHEA el propio
  comando de chequeo → usar .

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:06:01 -04:00
sergioandClaude Opus 4.8 f5a3432831 kde/Plasma: plasma-nm 6.7.2 SELLA — el APPLET DE RED, frente de red cerrado
plasma-nm (6080f27f) construido: applet QML org.kde.plasma.networkmanagement + kcm_networkmanagement +
plugins VPN (openvpn/openswan/ssh/sstp/strongswan/iodine/fortisslvpn). Cierre verificado:
libKF6NetworkManagerQt.so.6 + libKF6ModemManagerQt.so.6 + libqt6keychain.so.1.

Cierra el frente que plasma-workspace esquivó parcheando NetworkManagerQt a opcional. Cadena entera:
  glib-shared → networkmanager (libnm)    → networkmanager-qt ─┐
  glib-shared → modemmanager (libmm-glib) → modemmanager-qt ───┴→ plasma-nm

Deps nuevas de esta tanda:
  modemmanager 1.22.0   9e4ce41d  libmm-glib. -Dqmi/mbim/qrtr=false evita libqmi/libmbim/libqrtr;
                                  polkit=no, udev=false (+udevdir explícito, lo exige el assert).
  modemmanager-qt 6.27  37e954bb  KF6ModemManagerQt (REQUIRED en el find_package(KF6) de plasma-nm
                                  aunque no haya módem).
  qtkeychain 0.16.0     6a1319b0  claves WiFi. **LIBSECRET_SUPPORT=OFF**: por defecto ON y exige
                                  libsecret-1 (llavero de GNOME); apagado queda KEYCHAIN_DBUS =
                                  kwallet vía Qt6DBus, que es el backend que KDE usa ⇒ cero deps nuevas.
                                  OJO: el tag de git es '0.16.0' SIN prefijo 'v'.
  libxslt 1.1.43        b41cb0fc  xsltproc. A diferencia de NM (donde sólo servía a man/ y se degradó),
                                  ModemManager lo USA de verdad: include/meson.build:25 genera
                                  ModemManager-names.h desde header-generator.xsl.
  qcoro-shared 0.12.0   b8ed5b49  el qcoro canónico sella sólo .a sin PIC (su CMake no fija
                                  BUILD_SHARED_LIBS) ⇒ 'R_X86_64_32S QCoro::detail::TaskBase<QDBusMessage>
                                  recompile with -fPIC' al linkear plasma-nm. Variante con
                                  BUILD_SHARED_LIBS=ON; nombre distinto para no re-hashear el qcoro que
                                  ya consumen plasma-workspace/powerdevil.

BUILD_OPENCONNECT=OFF es importante: con ON, plasma-nm hace find_package(Qt6WebEngineWidgets REQUIRED)
⇒ arrastraría qtwebengine (Chromium), diferido por el ADR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 10:48:26 -04:00
sergioandClaude Opus 4.8 89569a6ce2 kde/Plasma: NetworkManager 1.52 + libndp → networkmanager-qt SELLA (blocker duro resuelto)
Habilitado por glib-shared (deuda Capa 0 recién saldada). La receta networkmanager-qt documentaba un
' BLOCKER DURO': pkg_search_module(NetworkManager REQUIRED IMPORTED_TARGET libnm>=1.4.0) sin receta de
NetworkManager en el catálogo. Resuelto:

networkmanager 1.52.0 (f3d89133) → libnm.so.0 + libnm.pc + headers (NetworkManager.h/nm-version.h).
  - Fuente: gitlab.freedesktop.org (download.gnome.org sólo llega a NM 1.9.x; el proyecto migró).
  - **-Dcrypto=null es la clave**: NM ofrece crypto ∈ {nss,gnutls,null}; 'null' evita nss (→nspr/sqlite)
    y gnutls (→nettle/libtasn1/p11-kit), dos cadenas enormes. Sin validación de certificados 802.1X,
    pero libnm compila y la API D-Bus queda completa.
  - Deps duras satisfechas: libudev (libudev-zero ya sellado), gio (glib-shared), libndp (receta nueva),
    uuid (util-linux), dbus.
  - NM va pidiendo sus flags de a uno; los que hicieron falta: -Dld_gc=false (lld no soporta linker
    garbage collection), -Dsystemdsystemunitdir=no, -Dconcheck=false (curl), -Dnmcli=false/-Dreadline=none.
    sed a meson.build:92: find_program('xsltproc') es INCONDICIONAL pero xsltproc sólo se usa en man/
    (no se construye con docs=false) → required:false, evita la receta libxslt entera.

libndp 1.9 (036eb8c7): sin tarball con configure pregenerado (mirrors 404) ⇒ git-archive +
con el autoconf/automake del rootfs de build (patrón 'de gueto', como gcc/cmake).

networkmanager-qt 6.27.0 (b5850a40) SELLA. Hallazgo: libKF6NetworkManagerQt.so NO enlaza libnm — sólo
Qt6Network/DBus/Core. libnm es dep de BUILD (headers/enums); el runtime es D-Bus puro. Confirma el
comentario original de la receta. Próximo: plasma-nm (el applet).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 10:25:28 -04:00
sergioandClaude Opus 4.8 4e02422680 kde/Plasma: glib-shared + pcre2-shared — DEUDA CAPA 0 'glib shared-PIC' SALDADA
La deuda más arrastrada del ADR 0011: glib canónico es -Ddefault_library=static --prefer-static (sólo
.a) ⇒ no enlaza en un .so; por eso plasma-workspace tuvo que parchear NetworkManagerQt a opcional
(esquivando el rabbit-hole libnm→glib).

glib-shared 2.88.1 (dc46a620) produce el set dinámico completo: libglib-2.0.so.0 + libgobject-2.0.so.0 +
libgio-2.0.so.0 + libgmodule-2.0.so.0 + libgthread-2.0.so.0 + libgirepository-2.0.so.0. Conserva los
switches del canónico (tests/nls/libmount/selinux/introspection off) — sólo cambia el modo de librería,
sin arrastrar deps nuevas.

pcre2-shared 10.47 (f254abaa) era el prerrequisito: el pcre2 canónico es --disable-shared SIN --with-pic
⇒ su .a no entra en libglib.so. compiler=gcc como el canónico (su comentario advierte que zig-cc
MISCOMPILA libs C, patrón file/jq); el .so es ABI-compatible con los consumidores zig. libffi NO necesitó
variante: ya usa --with-pic.

Cierre verificado: libglib-2.0.so.0 → libpcre2-8.so.0; libffi PIC queda embebido estático.
Destraba: libnm (NetworkManager→plasma-nm), polkit, xdg-desktop-portal, gstreamer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 10:08:10 -04:00
sergioandClaude Opus 4.8 324870e566 kde/Plasma: tanda de 5 apps ligeras (9-13) — kcharselect/kfind/kruler/kdf/kwalletmanager
CERO recetas nuevas: las 5 usan sólo deps ya selladas. Binarios verificados en los artefactos.
  kcharselect  da2ea71b  selector de caracteres Unicode
  kfind        9c46fee5  buscador de archivos (+qt5compat por Qt6Core5Compat REQUIRED, +kfilemetadata)
  kruler       f69c1bc8  regla de pantalla (+kstatusnotifieritem)
  kdf          fe681807  espacio en disco → bins kdf + kwikdisk (+kcmutils)
  kwalletmanager 2d31f0be  gestor de billetera → bin kwalletmanager5 (+kwallet/kcmutils)

4/5 sellaron a la primera con el patrón app-KDE estándar. kwalletmanager pidió además degradar DocTools:
marca TYPE REQUIRED en set_package_properties ⇒ feature_summary aborta; sed TYPE REQUIRED→OPTIONAL (el
mismo patrón que konsole/gwenview; distinto de ark/okular donde DocTools va en el COMPONENTS list).

Apps: konsole+dolphin+kate(+kwrite)+kcalc+ark+filelight+gwenview+okular+kcharselect+kfind+kruler+kdf+
kwalletmanager = 13.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 10:03:33 -04:00
sergioandClaude Opus 4.8 122557615f kde/Plasma: okular 25.04.3 (8va app, visor documentos) + poppler 25.02.0 + freetype/fontconfig shared — DEUDA CAPA 0 SALDADA
okular sella (5efc2ad9) con 8 generadores: poppler (PDF) + kimgio + txt + comicbook + fax + fb + dvi +
xps. okularGenerator_poppler.so → libpoppler-qt6.so.3 verificado.

poppler 25.02.0 (59461aff), Qt6-only: sin QT5/glib/cpp/utils/tests; NSS3/GPGME/LIBCURL/LIBTIFF off y
LIBOPENJPEG=none (sin deps selladas; los JPEG2000 embebidos no renderizan, el resto del PDF sí).
Cierre libpoppler.so VERIFICADO soberano: libfreetype.so.6 + libfontconfig.so.1 + libjpeg.so.62 +
libpng16.so.16 + liblcms2.so.2 + libz.so.1 — sin fugas al sysroot.

**DEUDA CAPA 0 'freetype/fontconfig shared-PIC' (marcada pendiente en ADR 0011) SALDADA:**
freetype-shared 2.14.3 (76fd1f4b, libfreetype.so.6, --without-harfbuzz corta el ciclo con harfbuzz) +
fontconfig-shared 2.18.1 (6ed9e303, libfontconfig.so.1). expat NO necesita variante: el canónico ya usa
--with-pic. Las variantes omiten los 3 patches Alpine de rendering (viven en recipes/, copiarlos
arriesga colisión de patches homónimos; no afectan el rasterizado que poppler necesita).

Fixes okular: FORCE_NOT_REQUIRED_DEPENDENCIES (flag OFICIAL que sugiere el propio feature_summary) para
DocTools/Purpose/TIFF/LibSpectre/KExiv2Qt6/DjVuLibre/EPub/Discount/QMobipocket6; +plasma-activities
(REQUIRED), +kpty (comicbook), +kwallet (ya sellada). GOTCHA musl durable: synctex_parser.c usa
vasprintf (extensión GNU) con -std=c99 ⇒ musl no la declara en modo estricto ⇒ CMAKE_C_FLAGS=-D_GNU_SOURCE.

Apps: konsole+dolphin+kate+kcalc+ark+filelight+gwenview+okular.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 09:56:17 -04:00
sergioandClaude Opus 4.8 31fe5eb937 kde/Plasma: gwenview 25.04.3 (7ma app, visor imágenes) + phonon/exiv2 + shared image libs + fix zlib versionado
gwenview sella (1d2bb09d). NEEDED verificado: libexiv2.so.28 + libjpeg.so.62 + libpng16.so.16 +
liblcms2.so.2 + libphonon4qt6.so.4. Deps nuevas: phonon 4.12.0 (f0cdba38, multimedia REQUIRED, recorte
Qt6-mín) + exiv2 0.28.5 (3eebcce9, EXIF REQUIRED vía FindLibExiv2 de ECM, minimal sólo-zlib + fix
-Wno-error=date-time). kImageAnnotator degradado a OPTIONAL.

Más deuda Capa 0 (static→shared/PIC): libjpeg-turbo-shared (2c0dca7f, libjpeg.so.8) + libpng-shared
(bf8f7724, libpng16.so.16) — el .a canónico no enlaza en gwenviewlib.so.

FIX SOBERANÍA zlib versionado: zlib-shared re-hecho con -Wl,--version-script,zlib.map ⇒ ahora exporta
compressBound@@ZLIB_1.2.0 e inflateReset2@@ZLIB_1.2.3.4. Qt6 (libQt6Core/Gui) NEEDED esos @tags; el
libz.so previo (--whole-archive sin mapa) sólo daba nombres pelados → ld.lld fallaba con
--no-allow-shlib-undefined y Qt caía en runtime a la libz de Alpine (fuga). El .so versionado satisface
consumidores versionados y no-versionados. Apps: konsole+dolphin+kate+kcalc+ark+filelight+gwenview.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 08:44:40 -04:00