ee1b6eb0dfafa32bd430cdf4d5baba4e5b4d8db7
39
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3a83d2eda4 |
gnome: xz-shared — sin ella NINGUNA app de la imagen carga, no una
`scripts/vigia-sonames.py` sobre los cinco perfiles marcaba `liblzma.so.5` en GNOME pedido por `libadwaita` y por `python3`. La columna de QUIÉN lo pide es la que decide, y acá decidió fuerte: mirando el artefacto sellado, el `NEEDED` no lo lleva un binario suelto sino **`usr/lib/libadwaita-1.so.0`**, que es la librería contra la que enlaza toda app GTK4/GNOME de la imagen. Sin proveedor del SONAME el loader falla en TODAS, no en una. Misma fuga de siempre —el `xz` canónico del corpus es `.a`, así que el rootfs lo resolvía contra el sysroot Alpine DEL LAB— y por eso invisible al store: el lab no entra en `hash_inputs`. La receta `-shared` existía sólo en `incoming-kde`. Se promueve al corpus con el mismo procedimiento que `bzip2-shared` el 2026-09-03, y comprobando lo mismo antes de creerlo: el hash es idéntico desde las dos rutas (b3:174289d5) ⇒ un solo artefacto y cero rebuilds. Si hubiera diferido, sería otra receta y no valdría la promoción. Va sólo en GNOME: en cosmic y sway ese soname lo pide únicamente `python3`, que es herramienta de build y no viaja en la imagen. GNOME pasa de 3 sonames sin proveedor a 2. De los dos que quedan, `libperl.so` es de `perl` (build), y `libreadline.so.8` lo pide `usr/bin/sqlite3` —el shell de la CLI, NO `libsqlite3.so.0`—, así que las apps están bien y lo roto es el comando. Queda anotado como verruga, no como rotura. |
||
|
|
92d47cfe1d |
mirada: las tres -shared que faltaban — el USB resolvía expat/zlib/libffi contra el lab
`scripts/vigia-sonames.py` sobre los cinco perfiles: `escritorio-mirada` era el único que aún tenía la fuga al sysroot del lab en componentes de RUNTIME. `mesa-swrast` y `wayland` salen con `NEEDED libexpat.so.1`, `libz.so.1` y `libffi.so.8`; las recetas canónicas de expat, zlib y libffi son `--disable-shared`; ningún artefacto del cierre publicaba esos SONAME. O sea que el rootfs los resolvía contra el Alpine DEL LAB y el USB sólo arrancaba donde hubiera Alpine debajo — que es peor que una dep faltante, porque el lab no entra en `hash_inputs` y el store no puede ni notarlo. Es la misma fuga que los otros cuatro perfiles cerraron el 2026-09-03. mirada quedó fuera porque su lista nació como copia literal del PKGS de `mirada-usb.sh` y nadie la revisó desde entonces. La dirección hoy está invertida —el script deriva su PKGS de `targets.py escritorio-mirada`— así que arreglarlo acá arregla el USB, y no hay dos listas que puedan divergir. Actualicé el comentario, que seguía diciendo «lift verbatim». Las tres viven en `corpus`, la misma cola del perfil, y ya están selladas ⇒ CERO rebuilds: sólo entran a la clausura. NO sumo `bzip2-shared` ni `ncurses-shared`, que sí llevan los otros perfiles: acá esos sonames los pide únicamente `python3`, que es herramienta de build y no viaja en la imagen. El vigía imprime siempre QUIÉN pide cada soname justamente para poder separar eso; sin esa columna su informe no se puede triar y uno acaba tapando ruido. Verificado: mirada pasa de 10 sonames sin proveedor a 7, y los 7 que quedan son todos de `python3` y `perl`. |
||
|
|
b606bf988b |
targets.toml: atuq entra en los cuatro escritorios
Hasta ahora atuq estaba sellado y NO estaba en ninguna imagen. Es exactamente la lección que este fichero ya aprendió con `foot` en el perfil de sway: una receta sellada que ningún perfil declara no la lleva nadie, y la métrica de clausura no lo puede ver porque mide lo DECLARADO. Va en los cuatro por el mismo motivo que `mpv` y desde el mismo sitio: vive en el CORPUS, y una receta resuelve sibling-first y después el catálogo padre, así que las cuatro colas lo alcanzan. Arrastra la cadena GTK3 en sus variantes `-shared`, y el comentario lo dice: con las estáticas, libgtk-3 y libgdk-3 se llevaban cada una su copia de pango/cairo y el navegador no llegaba a pintar. NOTA sobre la métrica: el grafo del hub sólo reporta base/cli/escritorio-mirada — los cuatro escritorios no aparecen en `by_profile` porque sus raíces viven en las colas. Es previo a este cambio y no lo introduce; queda anotado porque significa que esta declaración NO se ve todavía en `build-state.json`. |
||
|
|
e684c26e52 |
targets: obs-studio entra al perfil escritorio-kde (274/274)
Una receta sellada que ningún perfil declara NO ESTÁ EN NINGUNA IMAGEN, y la métrica de clausura no lo puede ver porque mide lo declarado — la lección que este fichero ya aprendió con foot en sway y con las 22 apps KDE. OBS estaba sellado y en ninguna imagen. Entra SÓLO en escritorio-kde, y no por preferencia: su frontend es Qt6 y las 13 recetas Qt viven sólo en esa cola. Verificado con `yupana perfiles obs-studio`. El perfil pasa de 263/263 a 274/274 — arrastra 11 nodos a la clausura, todos ya sellados, y el grafo sigue cerrando. De paso: el aviso de los «tres huecos de mpv» estaba repetido en los CUATRO perfiles de escritorio y hoy quedó vencido en los cuatro (ALSA/PipeWire, Lua/OSC y vaapi están cerrados). Corregidos los cuatro; el assert de count==1 fue lo que destapó que no era uno solo. |
||
|
|
8c4e1a6b24 |
cursores: cosmic y sway corrían con el puntero INVISIBLE — receta propia, y el vigía medía mal
`vigia-imagen.py` daba ✗ en cursores en DOS de los cuatro escritorios. No es cosmético: con el cursor por software —obligatorio en virtio-gpu y en todo render por CPU— el compositor dibuja la imagen que le da el TEMA, y sin tema el ratón se mueve invisible. cosmic llegó a 43/43 y sway a 173/173 así, porque un tema de cursor no es dep de build de nadie: sólo entra si se DECLARA. `adwaita-cursors` (corpus, 48.1, data-only): del mismo tarball que `adwaita-icon-theme` pero SÓLO `Adwaita/cursors/` — 39 ficheros y 14 MB, sin un icono. Promover el tema entero habría regalado a sway y a cosmic los iconos de GNOME, que está anotado como decisión pendiente y no como olvido. Las dos cosas que el tarball no trae y la receta fabrica: · los nombres X11 heredados (`left_ptr`, `xterm`, `watch`, `hand2`…) son enlaces que genera el `meson.build` de upstream. El mapa se PARSEA de ahí, no se copia: copiado envejece en silencio. Si el origen de un enlace no existe, la fase falla — upstream pone un `files()` como aserción. · `/usr/share/icons/default/index.theme` con `Inherits=Adwaita`. Sin `XCURSOR_THEME` en el entorno, libXcursor y wlroots buscan el tema llamado literalmente `default`; sin él no hay puntero AUNQUE Adwaita esté instalado. Es el eslabón que hace que ande sin configuración. ⚠ no declarar esta receta junto a `adwaita-icon-theme`: chocan en `Adwaita/cursors/*`. Y el vigía estaba midiendo el invariante de al lado: exigía `index.theme` en el directorio para contar un tema, que es correcto para ICONOS —la búsqueda XDG recorre `Directories=`— y falso para CURSORES, porque libXcursor abre `<tema>/cursors/<nombre>` directo y el índice sólo hace falta para seguir un `Inherits=`. Con la receta instalada seguía diciendo «NINGÚN tema de cursor». De paso queda anotado en `targets.toml` que el comentario de cosmic decía «sin ellos arranca sin puntero» sobre `cosmic-icons`, que no trae cursores: describía una protección que no existía. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGyBj4QyeCZiwLMkP9GJp6 |
||
|
|
d69c437051 |
escritorios: KDE y GNOME corrían SIN tema de iconos — el panel vacío no era el panel
Medido sobre los artefactos del cierre de cada imagen, contando qué `usr/share/icons/*/`
trae un `index.theme` (que es lo que convierte un directorio en un tema):
escritorio-kde sólo Breeze_Light y breeze_cursors — que son CURSORES
escritorio-gnome CERO, ni siquiera hicolor
escritorio-cosmic Cosmic + hicolor <- el único que estaba bien
escritorio-sway CERO
Las dos capturas de QEMU de hoy ya lo mostraban y se leyeron como «arranca»:
- `plasma6-qemu-2026-09-03-kactivitymanagerd.png`: panel con el reloj y nada más. Los `.so`
de los applets estaban TODOS instalados; lo que faltaba era qué pintar. `kickoff`,
`systemtray`, `showdesktop` y `trash` SON un icono, así que sin tema quedan de ancho cero
— el reloj se ve porque dibuja TEXTO. El log lo decía en una línea:
`kf.iconthemes: Icon theme "breeze" not found.`
- `gnome-shell-qemu-2026-09-03-libs-compartidas.png`: barra superior con la fecha y el pill
de espacios, y la DERECHA vacía — red, volumen y batería son iconos.
`breeze` (ya declarado) es el tema de WIDGETS y CURSORES; los ~14.000 iconos viven en
`breeze-icons`, receta aparte, sellada desde siempre y declarada por NADIE. Igual
`adwaita-icon-theme` en GNOME, que además trae los XCursor (su cabecera dice por qué:
sin tema de cursor no hay puntero visible con el cursor por software de virtio-gpu).
Es la figura de las fuentes y de `foot` otra vez: data de RUNTIME, ninguna arista de BUILD
la alcanza, y la métrica de clausura no la echa de menos porque mide lo declarado.
`hicolor-icon-theme` —el fallback obligatorio de freedesktop— se promueve al corpus para que
lo alcancen las cuatro imágenes: hash IDÉNTICO desde la cola y desde el corpus
(b3:98ad44a5), y sus 4 consumidores (adwaita-icon-theme, cosmic-icons, cosmic-app-library,
cosmic-launcher) miden el mismo hash antes y después ⇒ un solo artefacto, CERO rebuilds.
Cierre tras declararlos, todo sellado y sin deuda:
kde 263/263 (+2) · gnome 158/158 (+2) · sway 173/173 (+1) · cosmic 133/133 (igual)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YGXe6mShYYw6V8ea1dQ13u
|
||
|
|
8df2559556 |
escritorio-kde: declarar kactivitymanagerd (plasmashell ABORTA sin él)
Arrancando la imagen KDE en QEMU: kwin toma el DRM, expone wayland-0, plasmashell arranca… y la pantalla se queda EN NEGRO con los dos procesos vivos. El serial repetía 'STATUS: kwin=1 plasmashell=1' durante minutos, que se lee como salud. La causa estaba en el log de Qt, no en el estado de procesos: kde.plasmashell: Aborting shell load: The activity manager daemon (kactivitymanagerd) is not running. No sale de la clausura de las 7 raíces porque NO es dep de build de nada: plasmashell lo pide por D-Bus al arrancar. scripts/kde/plasma-start-qemu.sh ya lo lanzaba (l.188); lo que faltaba era que el paquete entrara al rootfs. Ya estaba sellado — declararlo no cuesta un build. Misma figura que las raíces de runtime de GNOME (imports.gi.*): lo que se invoca por bus es invisible al grafo de deps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0164nrZWZc78Mr2srrsnoM8U |
||
|
|
6c37df6fa4 |
ncurses-shared: cierra la fuga de pw-top al lab, que llevaba desde agosto
recipes/pipewire.toml:85-88 afirma que quitando la dep de ncurses «meson saltea pw-top
y el resto construye». ES FALSO, y llevaba así desde al menos el 2026-08-29. Quitar la
dep no desactivó nada: el guardián de upstream es `if ncurses_dep.found()` y meson lo
encontró igual, en el sysroot Alpine DEL LAB. pw-top se construye, se sella y sale con
NEEDED libncursesw.so.6, que ningún artefacto del cierre publica porque el ncurses del
catálogo es --without-shared. Una herramienta rota dentro de las CUATRO imágenes,
invisible para el store porque el lab no entra en hash_inputs.
LA LECCIÓN, que es más grande que pw-top: QUITAR UNA DEP DE [deps] NO APAGA LA FUNCIÓN.
Cambia de dónde sale. Para apagarla de verdad hay que decírselo a la perilla del
proyecto; si no la hay, la dep tiene que estar declarada y satisfecha desde el store.
POR QUÉ UNA RECETA NUEVA Y NO RE-SELLAR PIPEWIRE. El arreglo limpio es declarar la dep y
reconstruir; cuesta 10 dependientes directos y 7 sellados que caen a deuda, entre ellos
xdg-desktop-portal-cosmic y cosmic-settings-daemon, que son Rust —el portal murió por
OOM tres veces y el que selló tardó 48 min con pico de 5,4 GiB de swap—. No se paga eso
hoy por una herramienta de diagnóstico, y menos con otro agente compilando en la misma
máquina. Lo que cruza acá es un SONAME, y para eso el repo ya tiene regla escrita:
enlazar contra una variante y CORRER contra otra es legítimo cuando lo que cruza es un
SONAME. Cero rebuilds.
⚠ QUEDA DEUDA ANOTADA: pipewire sigue enlazando contra el lab en BUILD. El día que se
re-selle por cualquier otro motivo hay que declarar ncurses-shared en sus [deps] y
corregir el comentario mentiroso. Esto tapa el síntoma en runtime, no la causa.
DOS COSAS QUE COSTARON, y están escritas en la receta:
- `-stats` es un flag de GNU ld que lld rechaza, y viene DENTRO del token
`-Wl,-soname,...,-stats,-lc` que arma el configure de ncurses. No se puede pasar por
LDFLAGS ni hay perilla MK_SHARED_LIB, y el patrón .zwrap de poppler tampoco sirve tal
cual porque filtra argumentos completos y acá hay que reescribir uno.
- Quitando `-stats`, el siguiente en caer es el `-lc` del mismo token. El driver de zig
valida lo que va dentro de `-Wl,` y no deja pasar ninguno de los dos; libc la liga él
solo, así que la cola `,-stats,-lc` se va entera. Se quita del Makefile GENERADO, con
un grep previo que FALLA si el configure deja de emitirlo (para no seguir en silencio).
EVIDENCIA, con control discriminante:
sin ncurses-shared -> Error relocating /lib/libncursesw.so.6: __vfprintf_chk: symbol
not found (símbolo de _FORTIFY_SOURCE de glibc que musl no
tiene: la fuga al lab, reproducida)
con ncurses-shared -> carga y corre; sólo falla en el runtime de PipeWire por no haber
demonio ni plugins SPA en la raíz de prueba
vigia-sonames en los cuatro perfiles: libncursesw.so.6 Y libpanelw.so.6 desaparecen.
Lo que queda son herramientas de build (go, python3, perl) más tres de RUNTIME que NO
son de este cambio y quedan anotadas: spidermonkey pide libgcc_s/libstdc++ en gnome,
libadwaita pide liblzma, y sqlite-shared pide libreadline.
Grafos: 820/820, 999/999, 883/883, 856/856, 833/833.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo
|
||
|
|
68274d6c2a |
kde: declarar las 22 apps que ya estaban selladas y en ninguna imagen
CERO builds: las 22 llevaban tiempo selladas en incoming-kde y no las declaraba nadie, así que sólo entran a la clausura. El perfil pasa de 200 a 259 nodos y sigue 998/998. POR QUÉ FALTABAN, que no es lo mismo que «se decidió que no fueran». Las 7 raíces del perfil son el set MÍNIMO del arranque en metal, tomado de docs/HANDOFF-noche-kde-2026-07-14.md:135. Ese mismo documento nombra lo que faltaba como el trabajo siguiente: «Capa 2 KF6 / apps núcleo: importar+construir konsole/dolphin/kate vía granja (extiende el escritorio usable)». Se construyeron y se sellaron; lo que nunca ocurrió fue DECLARARLAS. La métrica no lo podía ver porque mide lo declarado — la misma figura que dejó a sway en 121/121 sin emulador de terminal. Sin esto la imagen era compositor + shell + tema y nada más: sin terminal no se puede salir de un fallo, y sin plasma-nm/plasma-pa/powerdevil no hay red, ni audio, ni gestión de energía. Entran en tres grupos: - plomería de Plasma: plasma-desktop, plasma-nm, plasma-pa, powerdevil, kscreen, systemsettings, kinfocenter, kmenuedit, kwalletmanager - núcleo usable: konsole, dolphin, kate, okular, ark, spectacle, gwenview - accesorios ya construidos: kcalc, kfind, filelight, kcharselect, kruler, kdf Cómo se encontró, para repetirlo: listar los (cola,nombre) cuyo artefacto instala un usr/share/applications/*.desktop y que yupana.membresia() no asigna a ningún perfil. Salieron 23; 22 eran de acá. VERIFICADO con scripts/vigia-sonames.py, que es donde 22 componentes de RUNTIME nuevos podrían filtrar al lab: escritorio-kde queda con 1254 sonames provistos y 5 sin proveedor, y los 5 son ruido conocido —cmake, python3 y perl son herramientas de build que la imagen no instala, más el pw-top de pipewire que ya estaba anotado—. Ninguna app nueva aporta un NEEDED huérfano. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo |
||
|
|
1f415802f1 |
apps: GNOME tenía imagen sin terminal ni editor — arreglado con CERO recetas; y el montón A queda agotado
DOS COSAS, y la segunda no estaba en el plan.
1. EL MONTÓN A SE AGOTÓ DE COSAS SIN MURO. Re-triadas con scripts/provee.py las tres
candidatas que la tabla daba como baratas o dudosas; las tres son muro, y ninguna por
el motivo que decía la tabla:
- imv → no hay proveedor de OpenGL de escritorio (ya documentado; la sustituyó swayimg)
- mupdf → la nota decía «el X11 es del visor mupdf-x11; mupdf-gl no». Falso: platform/gl/
va sobre GLUT + OpenGL de escritorio, el mismo muro que imv. mupdf NO TIENE
visor Wayland: sus dos UIs son X11 o GL. El motor no tiene muros pero no hace
falta, el PDF ya lo da poppler.
- inkscape→ era GTK3 encubierto, como la tabla sospechaba: INKSCAPE_1_4_4 pide
gtkmm-3.0>=3.24 y gtk+-3.0>=3.24. master SÍ migró a GTK4 (gtk4>=4.14) pero
está sin publicar, y además el catálogo no tiene NI UN binding C++:
provee.py da ✗ en sigc++-2.0, glibmm-2.4, cairomm-1.0, pangomm-1.4 y gtkmm.
⇒ todo lo que queda está detrás de UNA de cuatro decisiones (GTK3 / Qt6-en-el-corpus /
GL de escritorio / X11), no de trabajo de recetas.
2. LO QUE SÍ ESTABA ROTO, Y NO ERA FALTA DE RECETAS. Cruzando la membresía de los cuatro
perfiles contra emuladores de terminal, editores y gestores de ficheros:
escritorio-cosmic term=cosmic-term editor=cosmic-edit archivos=cosmic-files
escritorio-sway term=foot editor=vim archivos=—
escritorio-gnome term=— editor=— archivos=—
escritorio-kde term=— editor=— archivos=—
Es la lección de foot otra vez y a mayor escala: sway llegó a 121/121 SIN emulador de
terminal porque nadie lo declaraba, y la métrica de clausura no lo ve porque mide lo
DECLARADO. Un escritorio sin terminal no es uno incompleto: es uno del que no se puede
salir cuando algo falla.
GNOME arreglado con CERO recetas nuevas: foot y helix viven en el CORPUS, ya estaban
selladas y no las declaraba NINGÚN perfil. foot es Wayland puro sobre xdg-shell (no
pide protocolos de wlroots) así que corre bajo mutter igual que bajo sway; su único
NEEDED es libc.so. helix es TUI y corre dentro de la terminal.
⚠ KDE NO SE TOCA, y es un hallazgo aparte que hay que acordar con ese frente: tiene 22
apps con .desktop selladas en su cola y sin declarar (konsole, dolphin, kate, okular,
spectacle, ark, gwenview, systemsettings, kcalc…) y además le faltan plasma-desktop,
plasma-nm, plasma-pa, powerdevil y kscreen — o sea red, audio, energía y pantalla. Su
perfil son 13 raíces de ARRANQUE EN METAL, no la imagen de escritorio completa (ésa se
hidrató aparte, por hash). No cuesta un build; cuesta acordarlo.
Nota de método: build-state.py invoca `hammer hash` ~1000 veces y el otro agente
recompiló el binario a mitad del barrido ⇒ kjobwidgets salió `unhashable` y KDE reportó
997/998. No era la receta: era la carrera. Re-corrido da 998/998.
Los cinco grafos: 819/819, 998/998, 882/882, 855/855, 832/832, cero nodos `wanted`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo
|
||
|
|
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
|
||
|
|
da0186d250 |
apps: zathura + backend de PDF, en gnome/cosmic/sway — y tres defectos de imagen que salieron
La cadena: 5 recetas nuevas (girara, xxhash, poppler-glib, zathura,
zathura-pdf-poppler) y 5 promociones GRATIS al corpus (json-glib, lcms2, glib-shared,
pcre2-shared, bzip2-shared — todas con hash idéntico desde la cola y desde el corpus,
medido con hammer hash antes de mover nada).
NO va en escritorio-kde, y está escrito en tres sitios para que no se liste por
descuido: su backend necesita una poppler con ENABLE_GLIB=ON, y esa imagen ya trae la
de Qt6 vía okular. Las dos instalan /usr/lib/libpoppler.so.146 y son artefactos
DISTINTOS ⇒ hidratar las dos pone dos ficheros en la misma ruta. La salida no sería
listarla igual, sería jubilar una de las dos popplers.
LAS TRES COSAS QUE SE ROMPIERON, que valen más que las recetas:
1. -DENABLE_GLIB=ON SE APAGA SOLO Y EL BUILD SALE OK. CMakeLists:260 hace
`if(NOT CAIRO_FOUND) set(ENABLE_GLIB OFF)`: no falla, obedece distinto. El primer
artefacto selló sin nada de glib, exit 0, sin aviso. La causa era una línea que este
repo ya tiene como patrón: `.pc Requires` → `[deps].build`. cairo.pc pide pixman-1 y
pixman no estaba declarado ⇒ `pkg-config --exists cairo` falso ⇒ CAIRO_FOUND falso.
Un .pc que falta a tres saltos apaga una FUNCIÓN, no una librería. La receta ahora
comprueba en install que poppler-glib.pc y libpoppler-glib.so existan.
2. DOS COPIAS ESTÁTICAS DE GObject EN UN PROCESO. Con la glib estática del corpus todo
sella y zathura arranca — y al dlopen del plugin escupe «cannot register existing
type 'gchar'» y no abre nada. No son dos ficheros en una ruta: son dos copias del
sistema de tipos dentro del mismo proceso, una en el ejecutable y otra dentro de
libpoppler-glib.so. Un .a NO duplica (sólo tiene símbolos sin definir, se resuelven
al ligar); el problema aparece sólo cuando dos objetos enlazados por separado meten
cada uno la suya. Arreglo: las TRES recetas de la cadena declaran glib-shared.
3. FUGA AL LAB, cazada por scripts/vigia-sonames.py: zathura selló con
NEEDED libsqlite3.so.0, un SONAME que ningún artefacto del cierre publica — meson
había resuelto dependency('sqlite3') contra el sysroot Alpine DEL LAB. Y declarar la
dep NO alcanzó: el .pc da un -lsqlite3 pelado y el linker prefiere la .so del lab
sobre la .a del store. Lo arregla -Dprefer_static=true. Medido: los NEEDED bajaron de
DIEZ a CUATRO y los cuatro los publica el cierre.
DOS DEFECTOS DE IMAGEN PREEXISTENTES que salieron de paso:
- libbz2.so.1 no lo publicaba nadie y freetype-shared lo pide, en los TRES perfiles.
Se vio de verdad al probar el visor (el plugin no hacía dlopen). bzip2-shared existía
sólo en incoming-kde; promovida y puesta de raíz junto a expat-shared/libffi-shared.
- escritorio-gnome NO TRAÍA NI UN FICHERO DE FUENTE. Contado sobre los artefactos del
cierre: gnome=0, sway=22, kde=1 (una de rebote dentro de qtbase). Tenía fontconfig,
que es el MOTOR que busca fuentes, no una fuente. Un PDF con base-14 se ve VACÍO y sin
error. Añadida dejavu-fonts, la única receta de fuentes del catálogo entero.
⚠ KDE queda igual y NO se toca acá: no lleva zathura y su árbol lo trabaja otro frente.
EVIDENCIA DE QUE ANDA, no de que sella:
- `zathura --version` con el plugin lista «(plugin) pdf-poppler (2026.07.18)» sin un
solo GObject-CRITICAL.
- poppler-render-check, receta-TESTIGO en el espíritu de gtk4-hello: arma un PDF a mano,
lo abre con poppler-glib, lo rasteriza sobre cairo y CUENTA PÍXELES — 9600 negros,
exactamente el rectángulo de 160x60. Un lienzo blanco no pasa. Su primera versión
medía el TEXTO y falló: el sandbox no tiene fuentes, que es cómo se descubrió el
hueco de arriba. El assert quedó sobre el rectángulo, que no depende de tipografía, y
el texto se informa aparte.
Los cinco grafos quedan en N/N con cero deuda.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo
|
||
|
|
d8dd779812 |
apps: swayimg 4.7 sellada, visor de imágenes en las cuatro imágenes
El plan proponía `imv` como paso 4. Al medirla apareció un muro que el método de triaje no podía ver: imv dibuja con OpenGL de función fija (glBegin/glOrtho) y esta distro NO tiene proveedor de GL de escritorio — las tres variantes de mesa van -Dglx=disabled -Dglvnd=false y no publican libGL.so ni gl.pc ni opengl.pc, y no hay receta libglvnd. La trampa fina: mesa SÍ instala GL/gl.h, así que compila entero y muere al ligar. Darlo vuelta = autorar libglvnd + rehacer mesa (radio 139). swayimg cubre el mismo caso de uso sin tocar GL (rasteriza a wl_shm) y con CERO recetas nuevas: sus deps requeridas ya estaban en el corpus. De yapa trae backend DRM (imágenes en TTY pelada, sin compositor). Pineada 4.7 y no 5.5 a propósito: desde la 5.0 luajit es obligatoria y no hay receta (la lua5.2 del OSC de mpv es otra ABI). Escribir luajit es el próximo paso barato. -Dversion=4.7 no es cosmético: su default 0.0.0 dispara un `git describe` sobre el árbol ⇒ la versión estampada en el binario dependería del checkout. Misma familia que el -Dbuild-date de mpv. Evidencia de que anda, no sólo de que sella: NEEDED = libc.so y nada más (cero glibc, cero X11, cero GL), `--version` dice 4.7 con jpeg/png/gif/webp/tiff, prueba las dos UIs (Wayland → DRM) y el bucle de decodificación rechaza lo que no es imagen. Añadida a las raíces de los cuatro perfiles (sellado ≠ instalado). Los cinco grafos quedan en N/N con cero deuda. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo |
||
|
|
39f5007cff |
wf-recorder 0.6.0: la primera app que cobra la promoción de pipewire
Sellada b3:25caa359 al primer intento. `--help` corre y los NEEDED traen `libpipewire-0.3.so.0`: graba CON audio, que era exactamente lo que anoche no se podía. Es la app que estaba bloqueada por el defecto del triaje —preguntaba «¿existe la receta?» en vez de «¿la alcanza quien la usa?»—: sus dos backends de captura de sonido vivían sólo en colas y una receta del corpus no alcanza una cola hermana. Con pipewire en el corpus, cae sola. `-Ddefault_audio_backend=pipewire` explícito y no `auto`: su meson resuelve `auto` mirando qué encontró en el sandbox (meson.build:95-101), o sea que el artefacto dependería de lo que quedó montado en el lab. Misma disciplina que en mpv y ffmpeg. ⚠ SE LISTA SÓLO EN `escritorio-sway`, y la razón es de PROTOCOLO: captura por `wlr-screencopy`, que implementan los compositores wlroots. KWin y mutter NO lo implementan —usan el portal/ScreenCast—, así que meterlo en esas dos imágenes sería enviar una herramienta que no puede funcionar ahí: deuda fantasma con forma de app. En COSMIC hay que verificar si cosmic-comp expone el protocolo antes de listarlo; no se listó a ciegas. Cubre el caso de uso principal por el que uno instala OBS, con UNA receta en vez de las 20 + Qt6 + X11 que OBS pedía. escritorio-sway 146/146. |
||
|
|
f64859bade |
qorpa export: shims generados, y la clase ajeno para que nadie los cuente mal
Paso 5 del ADR 0015, sus dos mitades. SHIMS. `hammer qorpa export <id>` genera lanzadores finos y `.desktop` en el espacio del host, desde lo DECLARADO en `[export]` — nunca todo: exportar todo haría que el `ls` de la imagen compita con el nuestro, que es la falla de Bedrock (arbitra en tiempo de exec, por heurística). Gana en tres cosas contra un FUSE: cero costo en runtime, `cat` al shim y ves qué hace, y se revoca borrándolos. Se GENERAN, no se copian. El `.desktop` se arma con lista BLANCA de claves, así que `Exec`, `TryExec`, `Path` y `DBusActivatable` quedan fuera por definición y no por enumeración — una lista negra dejaría entrar la próxima clave ejecutable que invente el estándar. El Exec original se cita en un comentario del fichero generado, para que se vea qué decía y qué no se copió. El icono se busca en la vista merged (upper primero, imagen después: si no, se perdería lo que instaló el gestor de paquetes) y se copia al host, porque un icono que el host no resuelve se ve como un cuadrito gris. Y `exported.json` registra cada fichero escrito, para que `--remove` borre EXACTAMENTE eso y no por patrón sobre el ~/.local/bin de alguien. Probado de punta a punta con un .desktop ajeno real de la imagen de Arch: el shim corre `pacman -Q` del huésped desde el host, el X-KDE-Wayland-Interfaces quedó fuera, el icono viajó, y --remove dejó 0 ficheros con la instancia intacta. CLASE `ajeno`. build-state.py inyecta los nodos declarados en el nuevo docs/state/qorpa-ajenos.toml ANTES que los `wanted`, y ese orden es la mitad del punto: un nodo que provee una imagen ajena no es una receta por escribir. Con eso el `xwayland` de escritorio-kde deja de ser deuda y pasa a contarse aparte: escritorio-kde 187/188 listo falta 1 (raíces 14, + 1 ajenas) Dos decisiones que sostienen esa cifra: los ajenos se RESTAN del denominador (si entraran, el número que se lee como "cuánto construimos" crecería solo cada vez que alguien enjaula una app), y la declaración vive en el REPO y no se lee de /var/lib/hammer — build-state.json se commitea y lo regenera el cron en dos máquinas; si la clase saliera de las instancias instaladas, cada una diría algo distinto y se pisarían en cada cosecha. Es el error que ya se cometió con sealed_remoto. Qué provee una imagen ajena es diseño; qué tenés instalado, no. Un ajeno tampoco se hashea, y no por comodidad: no tiene procedencia de fuente, así que un hash afirmaría que lo reproducimos. 2 tests nuevos (que del .desktop ajeno no sobreviva nada ejecutable; que el shim no se rompa con rutas raras). 47/47. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U5cQtQrYNjWJVXVE6aEpQ2 |
||
|
|
f9da495b8c |
vigía de sonames: KDE, GNOME y COSMIC tenían la MISMA fuga al lab que sway ya había documentado
Verificando que mpv anduviera en las cuatro imágenes salió esto: `libEGL.so.1` (mesa) pide
`libexpat.so.1` y `libwayland-client.so.0` pide `libffi.so.8`, las recetas canónicas de expat y
libffi son `--disable-shared`, y ningún artefacto del cierre publica esos SONAME ⇒ los tres rootfs
los resolvían contra el **sysroot Alpine DEL LAB**.
Es peor que una dep faltante: el lab NO entra en `hash_inputs`, así que el store no puede notarlo —
el artefacto se sella, el perfil reporta 100%, y la imagen sólo arranca en una máquina con Alpine
debajo. El perfil de sway ya tenía escrito exactamente este párrafo desde 2026-08-26; lo que faltaba
era el instrumento para ver que las otras tres estaban igual.
Arreglo (gratis, sin rebuild: las dos recetas ya estaban selladas por sway): `expat-shared` y
`libffi-shared` pasan a raíces de los tres perfiles. Van de raíces y no de `[deps]` por la misma
razón que las fuentes y el XKB — son data de RUNTIME y ninguna arista de build las alcanza.
`scripts/vigia-sonames.py` es el guardián que sale del punto ciego: recorre los NEEDED de todo el
cierre de cada imagen contra los SONAME que ese mismo cierre publica. Dos decisiones de diseño:
· keying por PAR `(cola, nombre)` vía yupana, NO por nombre — `build-state.json` colapsa los
nombres que viven en dos colas y su campo `perfiles` puede quedar vacío para una receta que sí
está en la imagen.
· imprime SIEMPRE quién pide cada soname, porque el cierre incluye herramientas de build
(python3, cmake, perl, go) que la hidratación no instala: sin esa columna el informe no se tría.
Después del arreglo, `libexpat.so.1` y `libffi.so.8` desaparecen de los tres. Lo que queda son
hallazgos REALES que no son de este commit y quedan anotados:
· kde: karchive pide libbz2.so.1 y liblzma.so.5
· gnome: spidermonkey pide libstdc++.so.6 y libgcc_s.so.1; libadwaita pide liblzma.so.5;
freetype-shared pide libbz2.so.1; sqlite-shared pide libreadline.so.8
· cosmic: llvm18 pide libgcc_s.so.1
· los tres: `pw-top` de pipewire enlaza `libncursesw.so.6` DEL LAB — y la receta afirma en un
comentario que sin la dep «meson saltea pw-top». Es falso desde al menos el 2026-08-29:
`dependency('ncursesw')` lo encuentra igual en el sysroot del lab. El comentario dice una cosa
y el binario otra.
|
||
|
|
01b86fd0fb |
targets: mpv entra como raíz de los cuatro escritorios — sellado no es instalado
Sin esto mpv quedaba sellado y en NINGUNA imagen. Es exactamente la lección que este fichero ya tiene escrita en el perfil de sway: `foot` estaba sellado en el corpus, ningún perfil lo listaba, y el escritorio daba 121/121 SIN EMULADOR DE TERMINAL. La métrica de clausura mide las raíces declaradas y no puede ver lo que falta en la declaración. Se lista en los cuatro porque mpv vive en el corpus: una receta resuelve sibling-first y después el catálogo padre, así que desde cualquiera de las cuatro colas se alcanza. Los cuatro perfiles siguen en 0 deuda y cierran con la clausura nueva ya sellada: escritorio-kde 171 → 180/180 escritorio-gnome 119 → 129/129 escritorio-cosmic 90 → 103/103 escritorio-sway 129 → 139/139 Corpus 788 → 798 recetas, 798 selladas. grafo: CIERRA | topo-sort: OK en los cinco. |
||
|
|
776692d01a |
ADR 0015 (propuesto): imágenes ajenas — el mundo glibc entra enjaulado y no entra al store
Decide la frontera antes de escribir código. Sale de una medición incómoda: el
corpus tiene cuatro escritorios que cierran y CERO navegador, ofimática,
reproductor o editor de imagen. Al partir el «qué falta» por causa, la
intersección de «sólo X11» con «compilable desde fuente en musl» es casi vacía:
casi todo lo que se pierde por Wayland ya estaba perdido por la libc. El montón
que duele son binarios ajenos que nadie va a recompilar.
Las siete decisiones:
D1 — Una imagen ajena NO es un artefacto y no vive en el store. El store promete
reconstrucción bit a bit desde fuente; un rootfs de Fedora no. Meterlo ahí
sería la misma clase de error que el artefacto vacío: algo que se lee como
garantía y no lo es. Namespace paralelo, por digest, fuera de hash_inputs.
D2 — Se cruza el borde con protocolos y nodos de dispositivo, NUNCA con
librerías. Wayland/PipeWire son protocolos; /dev/dri y /dev/ntsync son ABI
de kernel. Mesa va adentro de la imagen. Corolario: la jaula no sabe qué
libc hay adentro, y por eso resuelve el montón entero de una vez.
D3 — El manifiesto es la verdad; el `upper` del overlay es CACHÉ. Misma relación
que receta↔artefacto. De ahí se caen solas la actualización de base (se
recrea, no se rebasea), el respaldo (KB, no GB) y la poda.
D4 — Cuatro granularidades, no una. El runtime curado inmutable (tipo 2) sigue
siendo el preferido cuando alcanza: se sella. El rootfs con dnf existe
porque es justo lo que el tipo 2 no permite.
D5 — Transparencia por shims GENERADOS, no por un FUSE global. Es el poder de
Bedrock sin sus formas: cero costo en runtime, inspeccionable, revocable, y
se exporta lo declarado (Bedrock arbitra en tiempo de exec, con heurísticas).
Los nodos exportados entran al grafo con clase `ajeno` ⇒ no se pueden contar
como corpus. Bedrock no puede decirte qué tenés.
D6 — Steam ya ES un contenedor: se anida pressure-vessel adentro, que es la
configuración que Valve prueba. El bwrap anidado hay que VERIFICARLO.
D7 — Es el único lugar del sistema donde la política se escribe en vez de
derivarse. harkaq deriva `política = clausura(deps)`; una imagen ajena no
tiene clausura declarada. Excepción nombrada y acotada, por defecto vacía.
Y lo que el ADR admite que NO resuelve, escrito para no descubrirlo en producción:
el socket de Wayland es un borde de privilegio y lo pasamos crudo (screencopy y
virtual-keyboard incluidos — Flatpak pasa un proxy filtrante, nosotros no lo
tenemos); el UID mapping va a fallar primero y las piezas ya están en el corpus
(shadow instala newuidmap/newgidmap y crea /etc/subuid vacío, falta
provisionarlo); es una segunda cadena de suministro sin garantías; y hay que
acotar por escrito el claim de bit-repro o la cultura de números honestos se
erosiona sola.
Se cae gratis: `xwayland` deja de ser deuda del corpus (va DENTRO de la imagen,
que ya lo trae, y se cuelga de kwin por el socket) ⇒ el wanted de KDE se
disolvería sin escribir la receta y sin tocar Wayland-only. GIMP e Inkscape dejan
de reabrir la deuda GTK3. Y del plan de juegos: F2 (glibc+multilib desde fuente,
«una campaña entera») queda CANCELADA y F0 (flatpak+ostree al catálogo)
innecesaria.
Lo nativo no se afloja: el montón A se sigue construyendo, en orden mpv → OBS →
Firefox.
Toca sólo documentación: el ADR nuevo, la nota de generalización en
plan-jaula-juegos.md §Capa 3, y el comentario en targets.toml que evita que
alguien escriba la receta de xwayland sin ver la decisión pendiente. Cero recetas
tocadas, cero re-hasheo: --kde sigue en 978 sealed / 1 wanted / 171-171, CIERRA.
|
||
|
|
0ac6fbfb5b |
targets: el perfil GNOME ya no reclama las 3 recetas aparcadas por diseño
`targets.toml` declaraba gnome-session, gnome-settings-daemon y gdm como raíces del perfil, mientras el encabezado de las tres recetas dice "APARCADA por diseño" desde el 2026-08-07, verificado contra el meson.build de cada tag: las tres mueren en GTK3, que es una de las tres deudas que el frente GNOME aparcó a propósito (GTK3 / X11 / PAM). Dos documentos del repo decían cosas opuestas, y el que se mira primero es el grafo. El resultado era deuda FANTASMA: escritorio-gnome reportaba 124/127 con 3 en `never` para siempre, se leía como trabajo pendiente, y el worker las reintentaba en cada ciclo. En esta misma sesión me hizo afirmar dos veces que GNOME estaba "a 3 recetas de cerrar". No bloquean el escritorio: gnome-shell no depende de gnome-session ni de g-s-d, ni en build ni para arrancar. El camino vivo es mutter → gnome-shell, lanzado por arje; el único que pedía gnome-session era gdm. Las recetas SIGUEN en el repo con su análisis intacto. Si algún día se autora GTK3, se vuelven a añadir a `paquetes` y el objetivo reaparece solo. escritorio-gnome: 119/119, CIERRA. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4 |
||
|
|
f8f679d038 |
corpus: expat-shared y libffi-shared cierran la fuga al Alpine del lab
sway es `link = "dynamic"` A PROPÓSITO —un compositor dlopea los drivers DRI de mesa en runtime— y sale con doce NEEDED. Nueve los cubría la clausura (pixman, drm, evdev, input, udev, wayland-server, wlroots, xkbcommon, libc), porque esas recetas ya son dinámicas. Los otros tres —libz.so.1, libexpat.so.1, libffi.so.8— venían de recetas `--disable-shared`, así que NINGÚN artefacto sellado producía ese `.so` y el rootfs los resolvía contra el sysroot Alpine DEL LAB. POR QUÉ ERA PEOR QUE UNA DEP FALTANTE. Una dep ausente falla ruidosamente. Ésta no: el lab NO entra en `hash_inputs`, así que el store daba el artefacto por bueno mientras el binario sólo arrancaba en una máquina que tuviera Alpine debajo. La fuga era invisible para todo el sistema de medición. `zlib-shared` ya existía en el corpus y sólo faltaba declararla. `expat-shared` y `libffi-shared` son nuevas, calcadas del patrón: autotools con --enable-shared, sin el truco de --whole-archive que zlib-shared necesita porque SU configure aborta bajo zig cc. SONAMEs verificados contra lo que pide el ELF: libexpat.so.1, libffi.so.8, libz.so.1. Exactos. NO se tocó `link` en las canónicas: entra en `hash_inputs` y habría re-hasheado expat, libffi y todo lo que los lista en deps —fontconfig, dbus, mesa, glib, python3, los crates `-sys`— cientos de recetas selladas por libs que ya están bien. El nombre `*-shared` es distinto del canónico, así que conviven. Verificado antes de construir: recalculadas las 794 recetas, **0 hashes cambiados**, sólo las 2 nuevas. Van al CORPUS y no a incoming-wlr/ porque la resolución de deps es hermano→padre: una receta del corpus no ve una cola. Es donde ya viven zlib-shared, fontconfig-shared, freetype-shared… VERIFICADO CON PÍXELES, no con el log. Rootfs rehidratado desde cero (126/126), CERO ficheros de `.dev-fs/alpine`. Cero «Error relocating». La captura tiene el MISMO sha256 que la de las libs de Alpine: 177fea396caa9dca, 1280x720, 383 colores. Tercera vez que la evidencia sale bit a bit igual al cambiar la procedencia — la soberanía no costó ni un píxel. Perfil: escritorio-sway 126/128. Faltan strace (linux-headers del lab) y rsync (404 de upstream). QUEDA UN RESTO: el loader `/lib/ld-musl-x86_64.so.1` todavía se toma del host. `recipes/musl.toml` existe en el corpus pero está EN DEUDA y fuera de todo perfil — mismo agujero de declaración, un nivel más abajo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016v9ozVm44p6DB7EMXeZK4o |
||
|
|
428ad80b24 |
wlr: fuentes y XKB DECLARADAS en el perfil — la captura sale bit a bit idéntica
`dejavu-fonts` y `xkeyboard-config` entran en `recipes/incoming-wlr/` y en las raíces de `escritorio-sway`. La clausura pasa de 123 a 125 y ambas ya estaban selladas: cero builds. POR QUÉ TENÍAN QUE SER RAÍCES Y NO PODÍAN LLEGAR POR CLAUSURA. Son DATOS, no binarios: ninguna receta depende de una fuente ni de un mapa de teclado para COMPILAR. El grafo puede seguir todas las aristas que quiera y no va a alcanzarlas nunca. Si no se declaran, no están — y el perfil sigue dando 100%, porque mide la clausura de las raíces declaradas. Copias BYTE-IDÉNTICAS a las de incoming-kde, a propósito. Ya había tres copias iguales de xkeyboard-config (kde, gnome, cosmic) y dos de dejavu-fonts (kde, cosmic); ésta es la cuarta. No se consolidan al corpus ahora porque eso toca las colas de otros tres frentes que otros agentes trabajan. Mantenerlas idénticas deja esa consolidación como un `git mv` trivial en vez de un merge: cuatro ficheros iguales se unifican de un tirón, cuatro casi-iguales exigen revisión. VERIFICADO de punta a punta, no por el log: rootfs rehidratado DESDE CERO con sólo lo que la clausura declara (123/123), y `sway-headless.sh` sin una línea de inyección manual de fuentes ni XKB. Cero errores de xkbcommon, cero de fcft. La captura resultante tiene el MISMO sha256 que la de ayer con todo inyectado a mano — 1280x720, 383 colores. La declaración es exactamente equivalente a la inyección, y el pipeline reproduce. Queda como deuda real (no de declaración): libz.so.1 / libexpat.so.1 / libffi.so.8, que sway pide por estar enlazado dinámico y el corpus sólo produce como `.a`. Y `fonts.conf` NO era deuda: lo trae el propio artefacto de fontconfig. Perfil: escritorio-sway 123/125. Los 2 que faltan son strace (choca con los linux-headers del lab) y rsync (404 de upstream), ninguno del escritorio. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016v9ozVm44p6DB7EMXeZK4o |
||
|
|
64e1ad2942 |
khipu: el grafo de sway llevaba 17 días congelado — el latido nunca corría --wlr
`build-state.py --wlr` existe desde que se abrió el frente, y su propio comentario dice que sin él
el frente es INVISIBLE para el khipu. La línea nunca se agregó a `cosecha-cron.sh`: el latido
regeneraba {base,kde,gnome,cosmic} y saltaba wlr.
Medido: build-state-wlr.json quedó fijo el 2026-08-09 anunciando `escritorio-sway 121/121`. Hoy,
regenerado, da 108/123. En el medio se re-hashearon freetype, make, python3 y libpng-pic, que
arrastraron a deuda a 14 dependientes (fuzzel, yambar, swaybg, swaylock, slurp, sed, strace, tzdata,
rsync, pciutils, procs, sd, skim, tokei). Nadie lo vio porque el número que se mira estaba perfecto.
Un grafo que nadie regenera no envejece en cualquier dirección: envejece hacia el OPTIMISMO. Sólo
puede sobreestimar lo sellado, porque el paso del tiempo únicamente invalida hashes, nunca los crea.
Va también `foot` a las raíces de escritorio-sway. El comentario de targets.toml afirmaba que entraba
por la clausura de `cli`; el grafo lo desmiente — `perfil.cli` no lo lista y ningún perfil lo
arrastraba. El escritorio daba 121/121 SIN EMULADOR DE TERMINAL. Se vio al hidratar la clausura para
armar la imagen, no antes: la métrica mide la clausura de las raíces DECLARADAS, y es estructuralmente
ciega a lo que falta en la declaración.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016v9ozVm44p6DB7EMXeZK4o
|
||
|
|
55dd36d97a |
perfil escritorio-sway: 121/121 CERRADO — la cuarta imagen de escritorio, y la más barata
Declarado en targets.toml y verificado con el grafo: **121 nodos, 121 sellados, falta 0**. Es una imagen construible hoy, no una intención. Nueve raíces (sway, yambar, fuzzel, swaybg, swaylock, swayidle, grim, slurp, wl-clipboard) más `hereda = ["cli"]`, porque un WM sin userland debajo no se usa: hacen falta la terminal y las herramientas. `foot` no se lista porque ya entra por la clausura de `cli`. El resto de la imagen —wlroots, mesa, wayland, libinput, seatd, cairo, pango, fcft…— lo calcula el grafo siguiendo las aristas: escribir la clausura a mano es justo lo que targets.toml existe para evitar. LA COMPARACIÓN QUE VALE: KDE y GNOME fueron campañas de semanas porque debajo tienen una torre de C (Qt entero, GTK, la cascada de mesa). Esto es una decena de binarios pequeños sobre wlroots y salió en una noche. Ya estaba escrito en el SDD 20 como hipótesis —«los WMs ligeros son la mejor relación esfuerzo/resultado que queda»—; ahora está medido. `--wlr` en build-state.py, con su flag propio por la misma razón que COSMIC: sin él el frente es INVISIBLE para el khipu, y `yupana radio` sobre una receta compartida (wayland, libinput, pixman, mesa, libxkbcommon…) no reportaría la imagen sway entre las afectadas — o sea que el próximo que toque una de ésas mediría de menos y creería que no rompe nada. Queda lo que no puede decidir el grafo: probarlo en QEMU CON PANTALLA. La regla ya pagada cara es que las imágenes de escritorio no se validan con `-nographic`, porque el compositor puede «arrancar» en los logs y no pintar nada. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
8d10bccf34 |
🔇 wireplumber: construido, corriendo… y NO era el bloqueo
b3:b8f3baf0, selló a la primera. Arranca desde cosmic-start ("wireplumber OK (pid
192) — hay gestor de sesión"), se conecta al grafo (dos clientes en wpctl status) y
wpctl pasa a mostrar una sección Video que antes no existía.
Y el Start de ScreenCast SIGUE sin Response a los 60s. Mismo resultado exacto.
LA HIPÓTESIS QUEDA MATADA POR MEDICIÓN. "Falta el gestor de sesión que mueva el nodo
de Paused a Streaming" era mía y era razonable; no era cierta. Queda escrita junto a
su refutación porque una hipótesis descartada CON EVIDENCIA vale más que una lista de
sospechosos: acota el próximo paso a lo que queda, que es el backend mismo.
El dato nuevo, que es por dónde seguir: con wireplumber corriendo, `wpctl status`
lista `Video → Streams` VACÍO durante el handshake. O sea que el nodo
`cosmic-screencast` que SÍ existe en `pw-cli ls Node` no llega a wireplumber como
stream gestionado. Próximo movimiento: RUST_LOG=trace sobre screencast_thread, no
otra dep.
── por qué receta propia y no la de GNOME ──────────────────────────────────────
La de incoming-gnome funciona pero NEEDea libglib/libgobject/libpipewire de la ISLA
DINÁMICA de GNOME: traerla metería una segunda glib y una segunda pipewire en la
imagen. De 19 deps, 14 dan hash idéntico; las que divergen divergen a propósito —
sobre todo `pipewire`, que acá apunta a la de COSMIC (338d1d8c), la que el escritorio
realmente ARRANCA. Un gestor de sesión contra otra pipewire que la que corre no
gestiona nada.
El cambio de fondo es glib → glib-shared. COSMIC usa la glib ESTÁTICA del corpus, que
le alcanza al portal porque es un ejecutable. Acá no: wireplumber produce un .so y 17
módulos, y libglib-2.0.a tiene 44.275 reubicaciones R_X86_64_32/32S ⇒ no es PIC. La
regla del frente GNOME (readelf -r ANTES de gastar el build) ahorró uno.
Y la salida no fue una campaña nueva sino una MEDICIÓN: incoming-kde/glib-shared
copiada a esta cola resuelve al MISMO hash (0584ce1f) y ya estaba sellada ⇒ cero
rebuild. Idem pcre2-shared, lua y libelogind. Las dos glib coexisten sin pisarse (.a
y .so son ficheros distintos) y el portal conserva sus 3 NEEDED.
escritorio-cosmic: 84 → 89 recetas, 0 faltantes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
ee037912a9 |
🎥 ScreenCast: el stream SE CREA — nodo cosmic-screencast vivo en pipewire
La receta de la sonda (b3:af49d32d) y lo que midió. Es la única receta de la campaña
cuyo producto no es una pieza del escritorio sino un instrumento para medirlo: entra
a la imagen porque un handshake de portal sólo se puede ejercer DESDE la sesión, con
bus y compositor vivos, y sale ESTÁTICA (0 NEEDED) porque un instrumento no debe
depender de aquello que mide.
[1/4] CreateSession → Response 0, session_handle ✓
[2/4] SelectSources → Response 0 ✓
[3/4] Start → el backend ABRE "Share your screen", con
miniatura EN VIVO del framebuffer y el output
Virtual-1; se elige, se pulsa Share…
y NO llega Response en 60s ✗
El log del backend da la línea exacta:
screencast_thread: state-changed 'Connecting' -> 'Paused'
Y `pw-cli ls Node` durante la espera da el veredicto INDEPENDIENTE:
node.name = "cosmic-screencast" media.class = "Video/Source"
EL NODO DE VIDEO EXISTE EN EL GRAFO DE PIPEWIRE. La cadena entera —cliente →
frontend → backend → compositor → demonio— funciona hasta crear y negociar el stream.
Lo único que no ocurre es el Response de vuelta tras quedar en `Paused`. Eso es un
lugar muy distinto del de esta mañana ("no hay demonio con quien negociar").
Sospecha para el próximo paso, y es HIPÓTESIS no medición: falta `wireplumber`. Sin
gestor de sesión nadie mueve el nodo de Paused a Streaming y el backend parece
esperarlo. Construirlo la confirma o la mata.
Gotchas que costaron corridas y quedan escritos:
· matar el backend se lleva puesto al frontend (ambos pierden dueño del bus);
· el lanzador busca por NOMBRE VISIBLE: `cosmic-term` no matchea, `Terminal` sí —
escribir el nombre del binario abre otra app;
· `| head -N` bufferiza y deja la terminal en blanco: parece colgada y está esperando;
· pkg-config OMITE los -L de dirs "estándar" y zig cc cross NO los busca ⇒
`-ldbus-1` pelado da "unable to find static system library", que suena a librería
faltante cuando lo que falta es la ruta.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
1e786aaf42 |
🚪 cosmic: el BACKEND del portal sella (b3:7ad0f124) — cadena completa en la imagen
69 min. NEEDED: libgbm, libpipewire, libxkbcommon, libc. Instala el binario en /usr/libexec, el .service de D-Bus con @libexecdir@ sustituido, el cosmic.portal que declara las cinco interfaces (Access/FileChooser/Screenshot/Settings/ScreenCast) y sus iconos. clang18 se construyó en la granja y se cosechó al laptop (b3:62c6bfb5), pero el backend NO se pudo construir allá: el worker no tiene la cola COSMIC horneada —el snapshot golden es del 2026-07-15 y toda esta cola es posterior— así que intentó reconstruir pipewire y murió buscando glib. Es la regla de «rootfs laptop ≠ worker» pero con el STORE: lo que en el laptop es cache-hit, en el worker es un build entero con sus propias deps. Y destapó que la receta de pipewire NO lleva --wrap-mode=nodownload: ante una dep faltante intenta bajarse un subproyecto de internet y, sin red, el error que sale no es «te falta glib» sino «Unhandled python exception / This is a Meson bug». Queda anotado como deuda. --offline SIN --locked, y no es descuido: el sed del parche corre en la fase compile, o sea DESPUÉS del cargo vendor, así que cargo ve el Cargo.toml cambiado y con --locked se niega. Quitar una feature sólo puede ENCOGER el conjunto de crates, así que lo que haga falta ya está vendorizado; la hermeticidad la da --offline + el árbol vendorizado, no el --locked. Dos raíces en el perfil y en la hidratación, porque son DOS procesos que se encuentran por D-Bus en runtime y ningún [deps] los relaciona. Imagen en 83 recetas (eran 74). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
520271ea2f |
📷 cosmic: cosmic-screenshot sellada y ROTA A PROPÓSITO — y la glib compartida YA existe
b3:8b57ec9b, 9 minutos, NEEDED = libc.so y nada más. Un solo NEEDED, y el único `[deps] build = []` de la campaña: 130 líneas de Rust que no dibujan ni hablan wayland. Se incluye en la imagen sabiendo que falla, para que el hueco sea MEDIBLE en vez de supuesto. Error exacto capturado corriéndola desde cosmic-term dentro de la VM: panicked at src/main.rs:76:10: failed to send screenshot request: Portal(ZBus(MethodError(ServiceUnknown, "The name org.freedesktop.portal.Desktop was not provided by any .service files"))) Misma forma que la deuda de org.freedesktop.locale1: un nombre de D-Bus que nadie sirve. LA CADENA DEL PORTAL SON TRES ESLABONES, NO DOS. Medido en el fuente: xdg-desktop-portal-cosmic declara DBUS_NAME = "org.freedesktop.impl.portal.desktop.cosmic" (src/main.rs:27) — es BACKEND, no toma el nombre que los clientes buscan. Falta también el frontend xdg-desktop-portal, y ninguno de los dos está en ninguna cola. ⚠ CORRECCIÓN AL PROPIO RUNBOOK: decía que `gvfs` exigía «una campaña propia». Es falso desde que KDE selló las piezas. Verificado con `hammer hash` desde las dos colas —el método correcto para saber si una receta se comparte—: glib-shared 2.88.1 (b3:0584ce1f) y pcre2-shared (b3:f254abaa) resuelven IDÉNTICO desde incoming-cosmic ⇒ cero rebuild, los artefactos sirven tal cual. zlib-shared ya estaba en la cola. libffi entra estático dentro de la .so (su Requires.private lo ignora pkg-config fuera del modo estático). Lo que queda de `gvfs` NO es técnico sino una decisión: mete una segunda glib en la imagen —lo que GNOME midió y evitó— y re-hashea cosmic-files, que arrastra a cosmic-term y cosmic-edit porque lo usan como crate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
b51f90ffea |
🛍 cosmic: cosmic-store — sella (b3:a06437f7), y BoringSSL cruza a musl sin cmake
La quinta aplicación, y la primera de la suite que choca con que hammer es
OTRA distro: una tienda es la cara de un gestor de paquetes y el de abajo no
es el suyo. De los cuatro backends de `src/backend/`:
flatpak pide libflatpak (GObject) ⇒ la cadena glib COMPARTIDA más
ostree/libsoup/gpgme: la torre de C que esta campaña no tiene
packagekit Rust puro (packagekit-zbus) pero necesita el DEMONIO en el bus
rpm-ostree irrelevante
pkgar el único que arranca: ni demonio ni enlace, lee el AppStream
del sistema — o sea los .metainfo.xml que instalan las recetas
ALCANCE HONESTO: con pkgar NAVEGA, no INSTALA. Ninguna operación está
cableada al .swm de hammer (Etapa F). El camino para arreglarlo quedó
identificado y no cuesta un solo .so de C: servir
`org.freedesktop.PackageKit` sobre .swm, mismo patrón que
arje-logind-compat.
HALLAZGO REUTILIZABLE: `aws-lc-sys` (BoringSSL, C + ensamblador) compiló
bajo zig-cc/musl SIN cmake y SIN perl — ninguno de los dos está en los 182
binarios de work/builder-rootfs/usr/bin. Tomó el camino de bindings
pregenerados (`cargo:rustc-cfg=universal`) y compiló los 21 MB de
libaws_lc_crypto.a con el crate `cc`. El `Compiling cmake v0.1.58` del log
es el crate ayudante, que se compila aunque el binario no se invoque. Esto
destraba cualquier receta futura que entre con rustls por defecto, que hoy
es casi todo lo que use reqwest.
NEEDED: libxkbcommon.so.0 y libc.so, igual que cosmic-edit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
d5f798a6b1 |
✎ cosmic: cosmic-edit — la 4ª aplicación, y el Cargo.lock miente por exceso
El editor de texto sella en b3:2323a325, igual que el dry-run. Es la más barata de las cuatro: depende de `cosmic-files` como CRATE con `default-features = false`, así que su árbol ya estaba compilado (68 min de enlace, no de compilación desde cero). Lo que aprendió esta receta, y que corrige un borde de la regla anterior: **el `Cargo.lock` lista lo POSIBLE, no lo ENCENDIDO**. Aparecen `gio-sys`, `glib-sys` y `gobject-sys` —que en cualquier otro paquete mandarían a declarar glib y de ahí a la cadena compartida— y sin embargo entran sólo por la feature `gvfs`, que se apaga. El lock dice el universo; las features dicen el recorte. Features: `--no-default-features --features dbus-config,wayland`. Fuera `gvfs` (pide las glib compartidas, el corpus las tiene estáticas) y `wgpu` (el que desbordó el filesystem dos veces en cosmic-files). La doble barra `pop-os//` que mordió en applets y settings acá está comentada en el Cargo.toml; verificado con grep ANTES del build. Evidencia: el binario enlaza sólo `libxkbcommon.so.0` y `libc.so` — dos NEEDED, el mínimo de la suite. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
232f23c5a8 |
⚙ cosmic: cosmic-settings — el panel de control, y NO arrastra medio sistema
Sellada b3:716dac53. Cola 33/33, escritorio-cosmic 71/71. Abre desde el lanzador con la barra lateral entera (Red, Bluetooth, Accesibilidad, Escritorio, Pantallas, Sonido, Energía, Entrada, Aplicaciones, Fecha y hora, Sistema y cuentas). Tarda ~20s con render por software; no está colgado. La sorpresa buena: nada de NetworkManager, libpulse, udisks ni accountsservice — habla con los daemons por zbus, que es Rust puro. Se verificó ANTES de escribir la receta listando los crates -sys del Cargo.lock, que es donde vive la verdad sobre qué C hace falta: sólo drm-sys, input-sys, libudev-sys, dav1d-sys, wayland-sys (dlopen) y gettext-sys. Regla barata: grep '^name = ".*-sys"' Cargo.lock antes de adivinar deps por lo que el programa hace. Volvió a morder la doble barra de cosmic-protocols// (404 de GitHub, muere en el fetch con tres reintentos). Segunda víctima ⇒ es patrón de la suite, no rareza de un repo. Instala 32 .desktop, uno por página. Y default_schema va con find, no cp plano: es el árbol <Componente>/v1/<clave> de cosmic-config, donde cada clave es un fichero con su nombre. Deuda que deja su propio log: org.freedesktop.locale1 no lo sirve nadie ⇒ la página de idioma no podrá cambiar nada. Mismo tipo que login1, mismo arreglo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
23c0e82527 |
📁 cosmic: cosmic-files — la 2ª aplicación, y «ya está compilado» era falso por una línea
Sellada b3:48d2b072. Cola 32/32, escritorio-cosmic 70/70. Abre desde la biblioteca y lista el sistema de ficheros real de hammer (bin 72 ítems, dev, ente, etc, lib, lost+found). Entró creyendo que era casi gratis porque cosmic-term ya la compila como crate. No lo era: cosmic-term la declara con default-features = false. Lo que un paquete cuesta depende de con qué features lo pide quien lo usa, así que «ya se compiló» puede ser falso. Dos features apagadas, las dos por medición: · gvfs trae gio/glib y el enlace final pide las glib COMPARTIDAS; el corpus sólo las tiene estáticas. Se pierden montajes remotos, no la navegación local. Por eso tampoco se construye cosmic-files-applet: su Cargo.toml fija gvfs a mano. · wgpu desbordó el filesystem dos veces (No space left on device en /src/target) con wgpu+naga+ash+glow+spirv a codegen-units=1. Sin él el árbol queda en ~2 GB, y no se pierde nada: el resto de la suite pinta con tiny-skia y la imagen no tiene GPU. Y la regla que dejó el intento con glib declarado: el error fue «Package libpcre2-8, required by glib-2.0, not found» — el que falla no es la dep sino lo que su .pc declara en Requires. Declarar una dep trae su artefacto, no su clausura de pkg-config; se lee con grep ^Requires sobre los .pc ANTES de gastar el build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e39610588d |
🖥 cosmic: cosmic-term — la primera APLICACIÓN, y la biblioteca deja de estar vacía
Sellada a la primera (b3:d0ea1c1e). Cola 31/31, escritorio-cosmic 69/69. Dentro de la ventana: bash-5.3#, uname -srm devuelve Linux 6.16.12 x86_64 —el kernel propio de hammer— y qalc -t '6*7' devuelve 42, o sea la calculadora que empaquetamos una hora antes. Se abre con click en su icono en la biblioteca, que hasta hoy salía vacía con razón: los 20 .desktop de la imagen eran NoDisplay=true. Éste no lo es. Lo que arrastra y no se adivina: su Cargo.toml depende de cosmic-files, o sea que el gestor de ficheros entra como LIBRERÍA (selector y drag-and-drop) y compilar la terminal compila medio gestor de ficheros. En esta suite las aplicaciones se usan unas a otras como crates, y el grafo de Cargo no se parece al mapa de componentes. De paso, empaquetar cosmic-files como aplicación queda casi gratis. wgpu viene en default, al revés que el resto de los clientes: se deja, porque wgpu y naga ya se habían compilado enteros para cosmic-workspaces y apartarse de las features por defecto es apartarse de la única combinación que upstream prueba. Cierra con dos NEEDED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
03ec0e6827 |
cosmic: libqalculate + gmp + mpfr — qalc anda, y el plugin del lanzador igual no lo puede usar
Las tres selladas a la primera (gmp b3:d99a0a5d, mpfr b3:13982d20, libqalculate b3:6bb435a7). La cadena entera desde una tecla está en el catálogo: Super → cosmic-launcher → pop-launcher → plugin calc → qalc → mpfr → gmp. Cola 30/30, escritorio-cosmic 68/68. qalc FUNCIONA: -t '2+2' da 4, -f fichero anda, e interactivo sobre terminal calcula. Pero el plugin lo invoca SIN expresión, con stdin en tubería, le escribe la cuenta y cierra — y en ese modo nuestro binario no lee nada. Acotado a que, con el EOF ya pendiente en un stdin que no es terminal, readline() devuelve NULL antes de entregar la línea que sí está en el búfer. Descartado midiendo, para no repetirlo: no es el toolchain (una sonda estática musl del sandbox lee la tubería en C y en C++); no es readline vs no-readline (sin ella es peor: no lee nunca); no es la versión de readline (una 8.3 sombra no movió el síntoma, y se descartó en vez de dejar una receta duplicada inútil); y no es el descriptor 0, porque Could not open "/dev/stdin". —el mismo pipe reabierto por ruta— sí funciona. El que no sirve es el FILE* stdin, y ahí queda la pista. Dos gotchas del empaquetado: gmp va con --disable-assembly (elige rutinas mirando la CPU de quien compila, o sea hornearía la ISA del laptop en el hash), y el configure de libqalculate no encuentra readline porque prueba -lncurses/-lcurses/-ltinfo y el corpus sólo empaqueta libncursesw.a — los alias van en un directorio local, no ensuciando /usr/lib, que es la evidencia de qué se declaró. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
505eaf5e44 |
cosmic: pop-launcher — el lanzador eran DOS programas, y ahora Super abre
cosmic-launcher sólo dibuja: manda lo tecleado por stdin a un proceso hijo, pop-launcher, que es quien busca. Sin ese binario la ventana no tiene qué mostrar y no se muestra — mismo modo de falla que el panel sin applets: falta un HIJO, no una librería, y el log del padre se lee sano. Vive en otro repo (pop-os/launcher), fuera del pin epoch-N. La versión la fija el Cargo.lock de cosmic-launcher (rev a332a3a7 de la 1.2.7), no el último tag: el lock es lo que garantiza que hablen el mismo protocolo. Tarball por commit, porque no hay tag que nombre esa rev. Selló a la primera, b3:64a5cbaa, con un solo NEEDED: libc.so. Verificado de punta a punta: Super abre el lanzador, «?» lista los seis plugins con su sintaxis (o sea que la enumeración y el IPC JSON-sobre-stdio andan) y «=2+2» LANZA el plugin, que contesta «qalc command is not installed». Esa respuesta es la mejor prueba disponible: el hijo corrió, evaluó y devolvió fila. Falta libqalculate, que es un paquete, no un problema. Cola 27/27, escritorio-cosmic 63/63. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
1d7308a97d |
estado: cosmic-applets entra al perfil — el panel no dibuja sin él
No lo lanza la sesión sino el PANEL, por AppID, así que ningún [deps] ni la lista de cosmic-session lo alcanzan. Sin él la imagen se declara completa y el escritorio sale sin barra. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
570fd3747e |
🧮 cosmic: trazarle la yupana — el frente existía en el store y el ábaco no lo veía
Faltaba la mitad del método. SÍ cruzaba incoming-cosmic (lo usé antes de tocar libdisplay-info, pipewire y glib), pero la campaña no estaba en el KHIPU: build-state.py sólo conocía --kde y --gnome, y targets.toml no declaraba perfil. Y eso no era cosmético. Antes de este commit, decía 21 dependientes transitivos y dos imágenes; ahora dice 31 y TRES — escritorio-cosmic entre ellas, con incoming-cosmic=10 en el reparto por cola. O sea que el próximo que tocara libinput, libudev-zero o mesa habría MEDIDO DE MENOS, que es exactamente el punto ciego que la metodología existe para cerrar. Tres piezas: - build-state.py --cosmic (y su build-state-cosmic.json). - perfil.escritorio-cosmic en targets.toml, con las raíces que cosmic-session levanta MÁS los datos que ningún [deps] alcanza (iconos, xkb, fuentes, bash, dbus). Primera medición: 54/61 listo, faltan 7. - el LATIDO lo regenera, por la misma razón por la que se le agregó GNOME en su momento: un frente que el cron no regenera envejece en silencio, y un grafo viejo miente con la misma cara que uno fresco. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
0b333b4c9e |
gnome: integra el frente a yupana — perfil escritorio-gnome + reckoning honesto
1. targets.toml: [perfil.escritorio-gnome] (9 raíces de sesión, cola incoming-gnome) ⇒ `yupana objetivo` ya lo ve; fluye por targets.py. build-state lo SALTA hasta que la cola se cargue (--gnome), así declararlo no reporta raíces fantasma. 2. seed-gnome.py OPTIMIZADO: hornea la triage (sustitución/tooling/opcional/espinazo) como HIPÓTESIS con el caveat "el cierre de nixpkgs sobreestima ~5-10×", marca el keystone (spidermonkey→gjs→gnome-shell), y deja de mentir con el 465 crudo. El espinazo (353) se reporta como COTA ALTA, no como lista de build. Falta (se activa al autorar): grafo build-state-gnome + flag --gnome ⇒ keystones/ drenar nativos sobre GNOME. Hoy la capa OBJETIVO del yupana-gnome está; la GRAFO no. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
9b67268a65 |
triaje: los 170 candidatos de frontera clasificados, y la cadena se ejerce entera
Evidencia dura primero: NINGUNO de los 170 bloquea un build. Toda receta que
pide uno de estos ya está sellada al menos una vez ⇒ hammer construye sin
ninguno. Eso descarta empíricamente "hueco de build" para los 170 y deja sólo
la pregunta de runtime.
VEREDICTOS
provisto 11 — no faltan: ya los da otra receta con otro nombre. nixpkgs parte
en varios paquetes lo que acá es uno solo. Verificado contra el
store: wayland-scanner→wayland, mesa-libgbm→mesa (nuestros tres
mesa producen libgbm.so.1), libxcb-*→xcb-util-*, poppler-qt6→
poppler, gmp-with-cxx→gmp, uname→coreutils.
nix-ismo 5 — andamiaje de nixpkgs (env wrappers, helpers del stdenv, glibc
asomando por su libc).
opcional 150 — software real que nixpkgs habilita y hammer no necesita, con el
porqué agrupado: systemd (usamos arje-zero), X11 heredado (el
escritorio es Wayland), Vulkan/shaders, audio/multimedia,
conectores de BD, tooling de docs/tests, bindings Python de Qt,
paquetería ajena (tenemos .swm).
hueco 4 — gaps de RUNTIME, no de build: shared-mime-info (sin base MIME
no hay tipos de fichero), xwayland (ninguna app X11 corre),
polkit-qt-1 (sin diálogos de autorización), qqc2-breeze-style
(los controles QML caen a un estilo genérico).
CORRIGE UN ERROR MÍO DE P3: dije que mesa-libgbm/libglvnd eran "el muro de
GBM/EGL". Falso — libgbm ya lo produce nuestro mesa. El muro era softpipe vs
llvmpipe, no un paquete ausente.
CUARTO VEREDICTO NUEVO (`provisto`) con su propio lazo: sale a alias-triaje.txt
y seed-graph.py lo carga en MAPA ⇒ esos 11 nombres dejan de contarse como hueco
para siempre. Junto con nixismos-triaje.txt, el sembrador aprende de su triaje.
Y LA CADENA SE EJERCE ENTERA POR PRIMERA VEZ: los 4 huecos entraron como raíces
de escritorio-kde → nacieron 4 nodos `wanted` (raíces 11, sin receta 4; el grafo
sigue cerrando, --check exit 0) → seed-graph los sembró (42 aristas conocidas,
21 candidatos nuevos de frontera) → drenar.py los ordena marcándolos [semilla],
que es la regla de la fuente única a la vista. qqc2-breeze-style no cae en la
onda 1 porque sus deps SEMBRADAS la traban (kcodecs, kirigami…): el andamio
funcionando como se diseñó.
De paso: qtbase se selló mientras corría esto ⇒ la onda 1 de KDE se abrió de 1 a
13 recetas. El cuello de botella que reportó P4 ya está destrabado.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
3a64b603d7 |
catálogo objetivo P1: manifiesto de perfiles — el set de la distro deja de ser un string de shell
El destino de la distro vivía en 2 strings de product-userland-from-repo.sh, 1 de mirada-usb.sh y 55 tandas planas. Ahora en docs/state/targets.toml: un perfil = una imagen enviable, listando sólo las RAÍCES (lo que se pide por nombre); la clausura la calcula el grafo, no un humano. 4 perfiles: base (26), cli (46, hereda base), escritorio-mirada (14), escritorio-kde (7 raíces, cola incoming-kde). scripts/targets.py expande hereda (transitivo, con detección de ciclo) preservando el orden — mirada lo necesita. Lift-and-shift verificado: las 3 listas expandidas son byte-idénticas a los strings que reemplazan. Ninguna imagen cambia de contenido. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |