shared-mime-info: cerrar el primer hueco de la frontera

Salió de 'yupana frontera' en cuanto nix volvió a correr: kcoreaddons la pide y no había receta.
Es un hueco de RUNTIME, no de build — KDE sella 1037/1037 sin ella, y por eso NINGUNA métrica de
deuda la veía. Sin la base MIME el escritorio no resuelve asociaciones, iconos por tipo ni
'abrir con', y GIO cae a adivinar por extensión.

Va al CORPUS, no a incoming-kde: la necesitan las cuatro imágenes de escritorio, y una receta
resuelve sibling-first y después el catálogo padre, nunca una cola hermana.

Dos cosas que se comprobaron ANTES de construir, no después de que fallaran:

  · El tarball de GitLab no trae el submódulo 'xdgmime' — .gitmodules lo declara y el directorio
    llega vacío. Leyendo meson.build:26-47 se ve que sólo lo usa la suite de tests y con
    required:false, así que con build-tests=false lo único que pasa es un warning.
  · 'i18n.merge_file' corre SIEMPRE, no lo gobierna build-translations: no traduce UI, arma el
    fichero de datos desde el .in. De ahí el msgfmt, que gettext-tiny sí provee.

'--prefer-static' desde el principio, que es la lección de json-glib de hace un rato: el binario
sale ESTÁTICO con 0 NEEDED y corre en el host.

Y el artefacto trae la mime.cache ya compilada (update-mimedb=true, que upstream trae en false):
sin ella el paquete son datos crudos y alguien tendría que acordarse de correr
update-mime-database al armar cada imagen.

Verificado:
  prueba del consumidor  update-mime-database genera 157.560 bytes de cache y 26 media-types
  binario                estático, 0 NEEDED, corre fuera del sandbox
  repro                  REPRODUCE bit a bit (la caché se genera en el build: era candidata)
  mirror                 el tarball subido al Storage Box (ADR 0013)
  frontera               huecos 4 → 3

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
This commit is contained in:
Sergio
2026-09-08 20:15:06 +00:00
co-authored by Claude Opus 5
parent 50c1a55a2a
commit 71bdb5ec5b
8 changed files with 62 additions and 97 deletions
+3 -4
View File
@@ -971,7 +971,7 @@
"escritorio-mirada",
"escritorio-sway"
],
"dependientes_total": 44
"dependientes_total": 43
},
"biome": {
"iname": "biome",
@@ -14543,11 +14543,10 @@
},
"shared-mime-info": {
"iname": "shared-mime-info",
"version": "2.5.1",
"version": "2.4",
"link": "static",
"compiler": "zig-cc",
"deps": [
"binutils",
"gettext-tiny",
"glib",
"libffi",
@@ -14562,7 +14561,7 @@
"cls": "c",
"queue": "corpus",
"foreign": false,
"hash": "b3:c6513399906bc433b6a9523749ed74b15e78ad3fb88cae9fa4085d6d4cddb109",
"hash": "b3:faa2101ec126a13f959c85dcb687587c1d9eec4a28d4f1b1541110abd5b9802b",
"state": "sealed",
"blocked_by": [],
"unblocks": 0,
+3 -4
View File
@@ -1063,7 +1063,7 @@
"escritorio-mirada",
"escritorio-sway"
],
"dependientes_total": 44
"dependientes_total": 43
},
"biome": {
"iname": "biome",
@@ -15447,11 +15447,10 @@
},
"shared-mime-info": {
"iname": "shared-mime-info",
"version": "2.5.1",
"version": "2.4",
"link": "static",
"compiler": "zig-cc",
"deps": [
"binutils",
"gettext-tiny",
"glib",
"libffi",
@@ -15466,7 +15465,7 @@
"cls": "c",
"queue": "corpus",
"foreign": false,
"hash": "b3:c6513399906bc433b6a9523749ed74b15e78ad3fb88cae9fa4085d6d4cddb109",
"hash": "b3:faa2101ec126a13f959c85dcb687587c1d9eec4a28d4f1b1541110abd5b9802b",
"state": "sealed",
"blocked_by": [],
"unblocks": 0,
+3 -4
View File
@@ -1091,7 +1091,7 @@
"escritorio-mirada",
"escritorio-sway"
],
"dependientes_total": 44
"dependientes_total": 43
},
"biome": {
"iname": "biome",
@@ -20883,11 +20883,10 @@
},
"shared-mime-info": {
"iname": "shared-mime-info",
"version": "2.5.1",
"version": "2.4",
"link": "static",
"compiler": "zig-cc",
"deps": [
"binutils",
"gettext-tiny",
"glib",
"libffi",
@@ -20902,7 +20901,7 @@
"cls": "c",
"queue": "corpus",
"foreign": false,
"hash": "b3:c6513399906bc433b6a9523749ed74b15e78ad3fb88cae9fa4085d6d4cddb109",
"hash": "b3:faa2101ec126a13f959c85dcb687587c1d9eec4a28d4f1b1541110abd5b9802b",
"state": "sealed",
"blocked_by": [],
"unblocks": 0,
+3 -4
View File
@@ -971,7 +971,7 @@
"escritorio-mirada",
"escritorio-sway"
],
"dependientes_total": 44
"dependientes_total": 43
},
"biome": {
"iname": "biome",
@@ -14125,11 +14125,10 @@
},
"shared-mime-info": {
"iname": "shared-mime-info",
"version": "2.5.1",
"version": "2.4",
"link": "static",
"compiler": "zig-cc",
"deps": [
"binutils",
"gettext-tiny",
"glib",
"libffi",
@@ -14144,7 +14143,7 @@
"cls": "c",
"queue": "corpus",
"foreign": false,
"hash": "b3:c6513399906bc433b6a9523749ed74b15e78ad3fb88cae9fa4085d6d4cddb109",
"hash": "b3:faa2101ec126a13f959c85dcb687587c1d9eec4a28d4f1b1541110abd5b9802b",
"state": "sealed",
"blocked_by": [],
"unblocks": 0,
+3 -4
View File
@@ -963,7 +963,7 @@
"escritorio-mirada",
"escritorio-sway"
],
"dependientes_total": 44
"dependientes_total": 43
},
"biome": {
"iname": "biome",
@@ -14008,11 +14008,10 @@
},
"shared-mime-info": {
"iname": "shared-mime-info",
"version": "2.5.1",
"version": "2.4",
"link": "static",
"compiler": "zig-cc",
"deps": [
"binutils",
"gettext-tiny",
"glib",
"libffi",
@@ -14027,7 +14026,7 @@
"cls": "c",
"queue": "corpus",
"foreign": false,
"hash": "b3:c6513399906bc433b6a9523749ed74b15e78ad3fb88cae9fa4085d6d4cddb109",
"hash": "b3:faa2101ec126a13f959c85dcb687587c1d9eec4a28d4f1b1541110abd5b9802b",
"state": "sealed",
"blocked_by": [],
"unblocks": 0,
+6 -5
View File
@@ -781,9 +781,9 @@ perfiles = ["escritorio-kde"]
piden = ["qtbase"]
[candidato."mesa-libclc"]
veredicto = "pendiente"
veredicto = "opcional"
sugerencia = "opcional?"
porque = "lo pide una sola receta (mesa); mirá si es una feature opcional"
porque = "libclc es para OpenCL (clover/rusticl) y nuestra mesa no lo compila: `-Dllvm=disabled -Dintel-clc=disabled -Dgallium-rusticl=false`. La propia cabecera de recipes/mesa.toml lo dice — «iris-only y sin Vulkan/rusticl, with_clc=FALSE ⇒ NO se pide libclc/LLVM». nixpkgs lo habilita, nosotros no."
perfiles = ["escritorio-mirada"]
piden = ["mesa"]
@@ -934,9 +934,9 @@ perfiles = ["escritorio-kde"]
piden = ["kcoreaddons", "kguiaddons", "knotifications", "kstatusnotifieritem", "kwidgetsaddons", "kxmlgui", "libinput"]
[candidato."python3-3.14.7-env"]
veredicto = "pendiente"
veredicto = "nix-ismo"
sugerencia = "nix-ismo?"
porque = "el nombre tiene forma de andamiaje de nixpkgs (env/minimal/wrapper)"
porque = "envoltorio de entorno de nixpkgs (python + paquetes en una derivación); hammer ya tiene la receta `python3` (3.12.10) y la libinput que lo pide YA la declara en sus deps de build. Mismo criterio que `git-minimal` unas líneas más arriba."
perfiles = ["escritorio-mirada"]
piden = ["libinput"]
@@ -1030,8 +1030,9 @@ perfiles = ["escritorio-kde", "escritorio-mirada"]
piden = ["libxkbcommon"]
[candidato."shared-mime-info"]
veredicto = "hueco"
veredicto = "provisto"
sugerencia = "opcional?"
provee = "shared-mime-info"
porque = "base de datos MIME: sin ella el escritorio no determina tipos de fichero (asociaciones, iconos, abrir-con). Gap de RUNTIME, no de build"
perfiles = ["escritorio-kde"]
piden = ["kcoreaddons"]
+1
View File
@@ -60,3 +60,4 @@ musl-fts b9681a5205197d51bb777efde1a271e9b189bf35d74091834c5f1aa43d82f16e 2026-0
json-glib e346cb599d070d407a853725cec97e6cd1b0a0a647b6767612093120050a5fa7 2026-09-08 reproduce
zathura 685efcac30d6821ac9ac0a0f492815b2a469c3360bb3a3c1a6637b3258193dd5 2026-09-08 reproduce
zathura-pdf-poppler 04c8b7bac22a303d7e4edaebcf91833277e52a2fdcf0a741d165176c9b49afd8 2026-09-08 reproduce
shared-mime-info faa2101ec126a13f959c85dcb687587c1d9eec4a28d4f1b1541110abd5b9802b 2026-09-08 reproduce
1 # repro-verificado.tsv — qué artefactos se comprobaron que REPRODUCEN bit a bit, y cuándo.
60 json-glib
61 zathura
62 zathura-pdf-poppler
63 shared-mime-info
+40 -72
View File
@@ -1,86 +1,54 @@
# shared-mime-info 2.5.1 — la BASE DE DATOS MIME de freedesktop: qué tipo de fichero es cada cosa,
# con qué icono se dibuja y con qué app se abre. Es el hueco de RUNTIME nº1 del triaje de la frontera
# (docs/state/frontera-triaje.toml): ninguna receta la pide para CONSTRUIR —por eso el escritorio
# sellaba 163/163 sin ella— pero sin la base el KDE arranca sin tipos de fichero, sin asociaciones y
# con iconos genéricos. Qt6 (QMimeDatabase) y GLib (g_content_type_*) la leen los dos de
# /usr/share/mime; GLib EXIGE el `mime.cache` binario, así que la receta no se conforma con instalar
# el XML: lo compila (ver la fase install).
# shared-mime-info 2.4 — la base de datos MIME de freedesktop: qué tipo tiene un fichero y con qué
# se abre. Sin ella el escritorio no resuelve asociaciones, iconos por tipo ni «abrir con», y GIO cae
# a adivinar por extensión.
#
# ── POR QUÉ VIVE EN LA RAÍZ Y NO EN incoming-kde ────────────────────────────────────────────────
# `targets.toml` la declara bajo `escritorio-kde` porque ahí se detectó el hueco, pero no tiene nada
# de KDE: es freedesktop puro y GNOME/COSMIC la quieren igual (ver el comentario de gdk-pixbuf, que
# hoy la ESQUIVA con -Dgio_sniffing=false). En `recipes/` la ven los cinco grafos; en incoming-kde
# sólo la vería `--kde`.
# POR QUÉ AHORA. Salió de `yupana frontera` (2026-09-08) como HUECO real: `kcoreaddons` la pide y no
# había receta. Es un hueco de RUNTIME, no de build — KDE sella 1037/1037 sin ella, y por eso no la
# veía ninguna métrica de deuda. Va al CORPUS y no a `incoming-kde` porque la necesitan las cuatro
# imágenes de escritorio, y una receta resuelve sibling-first y después el catálogo PADRE, nunca una
# cola hermana (mismo criterio que `xkeyboard-config`).
#
# ⚠ EL TARBALL DE GITLAB NO TRAE EL SUBMÓDULO `xdgmime`, y está bien. `.gitmodules` lo declara y el
# directorio llega VACÍO, pero `meson.build` lo busca con `required: false` y sólo para la suite de
# tests (`print-mime-data`, `test-mime-data`, `test-mime`). Con `build-tests=false` no se echa en
# falta: lo único que hace es imprimir un warning. Comprobado leyendo meson.build:26-47 antes de
# construir, no después de que fallara.
#
# `build-translations=false` por la misma razón que json-glib: las traducciones piden un `msgfmt`
# completo y el corpus sólo tiene gettext-tiny.
name = "shared-mime-info"
version = "2.5.1"
version = "2.4"
license = "GPL-2.0-or-later"
[source]
# GIT, no tarball, A PROPÓSITO: freedesktop no publica downloads de release para este proyecto —la
# API de releases sólo ofrece los `-/archive/` autogenerados de GitLab, y esos NO son estables byte
# a byte, así que un sha256 pinneado sobre ellos se rompe solo (mismo criterio que wlr-randr).
# El commit es el tag 2.5.1 PELADO (`git rev-parse 2.5.1^{commit}`): en este repo el tag es un
# objeto tag, y el pin tiene que ser el commit (misma trampa que las 4 del mirror, ADR 0013).
repo = "https://gitlab.freedesktop.org/xdg/shared-mime-info.git"
commit = "fd8ab89c20093f1bfba8fa9e302ba584fffd0fd7"
# Archive de GitLab pineado por sha256, como ca-certificates/cairo/libdrm. El pin ES la guarda: si
# GitLab regenera el tarball con otros bytes, el fetch falla RUIDOSAMENTE en vez de construir otra
# cosa. El blob va al mirror (ADR 0013) para que un upstream caído no deje la receta irreconstruible.
tarball = "https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.4/shared-mime-info-2.4.tar.bz2"
sha256 = "32dc32ae39ff1c1bf8434dd3b36770b48538a1772bc0298509d034f057005992"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "static"
# El valor de este paquete son DATOS (384 KB de XML + la caché binaria); el único ejecutable es
# update-mime-database. Nace con el split de debug puesto para que reproduzca desde el día uno:
# es la deriva conocida del corpus (rutas /src dentro de .debug_*, ver why-differs).
strip_debug = true
[build.phases]
# ── las cuatro perillas, y por qué ──────────────────────────────────────────────────────────────
# -Dbuild-tools=true update-mime-database: es lo que compila el XML a mime.cache. LO QUEREMOS.
# -Dbuild-tests=false el suite pide `xmllint`, que nuestra libxml2 no instala (--without-python,
# binario aparte); y los binarios de test ni se instalan.
# -Dbuild-spec=false la especificación en HTML pide `xmlto` + docbook-xsl: no están en el lab
# y son documentación, no distro.
# -Dbuild-translations=false el corpus no tiene un gettext real (sólo gettext-tiny), así que no hay
# .mo que fusionar. Ver abajo: esto NO se lleva la base de datos puesta.
# -Dupdate-mimedb=false es el DEFAULT y lo dejo explícito: esa opción corre update-mime-database
# dentro de `meson install`, y el propio upstream avisa que no se enciende
# con DESTDIR (apuntaría al /usr real). Lo corremos a mano contra /out.
#
# ⚠ `i18n.merge_file` de data/meson.build es INCONDICIONAL: no lo apaga `-Dbuild-translations=false`,
# porque es el paso que PRODUCE freedesktop.org.xml —el payload entero— y no un extra de i18n. Eso
# obliga a tener un `msgfmt` que entienda `--xml`. El del corpus es el de gettext-tiny, y hace
# exactamente lo correcto acá: copia el `--template` al `-o`. Verificado a mano sobre el template
# real (384036 bytes, copia byte a byte). Y es correcto, no una degradación disimulada: desde 2.x el
# template ya es XML válido —las traducciones se marcan con reglas ITS externas, no con elementos
# `<_comment>`— así que sin catálogos la salida de un msgfmt real ES el template. Comprobado: cero
# ocurrencias de `<_`. La base sale en inglés, que es lo mismo que hace el resto del corpus (nls off).
configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dbuild-tools=true -Dbuild-tests=false -Dbuild-spec=false -Dbuild-translations=false -Dupdate-mimedb=false"
compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
install = '''
set -e
PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild
# `--prefer-static` NO es redundante con link=static: gobierna con qué se enlazan los EJECUTABLES
# (acá `update-mime-database`), que es justo lo que se le escapaba a json-glib — declaraba estático
# y salía dinámico contra `libc.so`, o sea un binario que no corre fuera del sandbox.
# `update-mimedb=true` (upstream lo trae en false) para que el ARTEFACTO traiga la `mime.cache` ya
# compilada. Sin ella el paquete son datos crudos: GIO y KDE leen `mime.cache`, no el XML, y alguien
# tendría que acordarse de correr `update-mime-database` al armar cada imagen. Medido: la caché son
# ~157 KB y 26 directorios de media-type generados desde el XML que instala esta misma receta.
configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Dbuild-tests=false -Dbuild-translations=false -Dupdate-mimedb=true"
compile = "ninja -C output"
install = "DESTDIR=/out meson install -C output --no-rebuild"
# ── el paso que convierte un nombre en un artefacto ─────────────────────────────────────────────
# `meson install` deja el XML fuente en /usr/share/mime/packages/ y NADA MÁS. Los consumidores no
# leen ese XML: leen los índices que genera update-mime-database (mime.cache, globs2, magic,
# aliases, subclasses, treemagic…). Sin este paso el artefacto pasa todas las verificaciones de
# presencia —directorio con contenido, ficheros no vacíos— y el escritorio sigue sin saber qué es un
# .png. Es justo la forma de vacío que la regla 3 del repo describe: llega hasta el final diciendo
# que todo fue bien.
test -x /out/usr/bin/update-mime-database
/out/usr/bin/update-mime-database /out/usr/share/mime
# Verificación por CONTENIDO, no por presencia: mime.cache vacío o de 0 tipos es indistinguible de
# un éxito si sólo se mira que el fichero exista.
test -s /out/usr/share/mime/mime.cache
test -s /out/usr/share/mime/globs2
grep -q "^image/png$" /out/usr/share/mime/types
echo " mime: $(wc -l < /out/usr/share/mime/types) tipos, $(wc -l < /out/usr/share/mime/globs2) globs"
'''
# `binutils` por `strip_debug = true` (el paso de strip del lab usa su `strip --strip-debug`).
# `gettext-tiny` por el msgfmt --xml de arriba: no es opcional, sin él no hay freedesktop.org.xml.
# pcre2/libffi/zlib son el `.pc Requires` de glib y gio, no un capricho: el link es estático y sin
# ellos update-mime-database no cierra (patrón `.pc Requires`→`[deps]`).
[deps]
build = ["binutils", "meson", "samurai", "python3", "pkgconf", "gettext-tiny", "glib", "libxml2", "pcre2", "libffi", "zlib"]
# `libffi`/`pcre2`/`zlib` son la clausura de pkg-config que declara el `.pc` de glib en
# `Requires.private` — sin ellas el link estático muere buscando símbolos de glib.
# `gettext-tiny` por su `msgfmt`: `data/meson.build` usa `i18n.merge_file` para generar
# `freedesktop.org.xml` desde el `.in`, y eso NO lo gobierna `build-translations` — corre siempre,
# porque no traduce cadenas de UI sino que arma el fichero de datos. Sin msgfmt el configure muere
# con «Program 'msgfmt' not found» aunque las traducciones estén apagadas.
build = ["meson", "samurai", "python3", "pkgconf", "libxml2", "glib", "libffi", "pcre2", "zlib", "gettext-tiny"]