tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1411Shell 141Markdown 85Rust 842918 Definiciones

nautilus y gvfs: el censo de frontera decía 26 recetas y son 6

`targets.toml` declaraba `nautilus` (15 de frontera) y `gvfs` (11) como «el trabajo REAL que esta
tanda le da a la granja». Leídos los `meson.build` de verdad en vez del seed de nixpkgs, son SEIS
recetas, y dos de las de gvfs ni existen como problema.

gvfs: CERO recetas nuevas. Sus 11 fronteras son backends OPCIONALES con perilla propia
(samba/libmtp/libnfs/avahi/libcdio/libgphoto2/libimobiledevice/libbluray + goa/google/onedrive), y
`fuse` es `fuse3`, que ya está en el corpus. El núcleo —papelera, archive, dav, sftp, admin— sólo
pide glib + gsettings-desktop-schemas + dbus-1. La única frontera de verdad es `udisks`, o sea el
montaje automático de medios extraíbles, y queda declarada como hueco EN la receta.

nautilus: cuatro deps duras sin perilla (gnome-autoar, gnome-desktop ya sellada, libportal +
libportal-gtk4, tracker-sparql-3.0) ⇒ tres recetas, porque libportal publica las dos librerías
desde un solo source y tinysparql publica `tracker-sparql-3.0.pc` además del suyo
(src/libtinysparql/meson.build:146 y :155, verificado en la fuente).

La sexta es `libarchive-shared`, y sale de una medición: `libarchive.a` del corpus NO es PIC
—3205 reubicaciones R_X86_64_32 fuera de .debug, contra 0 de libcap/dbus/json-glib— así que no
entra en la `.so` de gnome-autoar. Mismo caso que sqlite, que ya tenía su `-shared`.

Las tres apps con `po/` traen la mina conocida del msgfmt de gettext-tiny: ar.po con 86 (nautilus),
7 (tinysparql) y 1 (gvfs) `msgstr[5]`. Sale el `sed` del LINGUAS en las tres, con el diagnóstico
escrito en cada receta.

Lo que estas recetas NO traen, dicho con nombre en cada encabezado: el montaje automático de USB
(udisks), el indexador de búsqueda (localsearch ⇒ búsqueda por nombre, sin contenido) y las
pestañas de metadatos EXIF/multimedia de Propiedades (gexiv2 + gstreamer).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

fadeaa03572fb81b13ccc00d520a70a6282f61a8 · por Sergio · (hace 29 d) · padre 4500a9ba1 · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

6 archivos · +401 −0

diff --git a/recipes/incoming-gnome/gnome-autoar.toml b/recipes/incoming-gnome/gnome-autoar.toml
new file mode 100644
index 00000000..6ba8367b
--- /dev/null
+++ b/recipes/incoming-gnome/gnome-autoar.toml
@@ -0,0 +1,54 @@
+# gnome-autoar 0.4.5 — extraer y comprimir archivos desde GIO. Es dep DURA de nautilus:
+# `meson.build:114` la pide `dependency('gnome-autoar-0', version: '>= 0.4.4')`, sin perilla que la
+# apague. Es lo que hace que «extraer aquí» exista en el menú contextual del gestor de ficheros.
+#
+# ── `-Dgtk=false` Y NO ES UNA PODA: SU OPCIÓN `gtk` ES GTK3 ─────────────────────────────────────
+# La tentación es encenderla «porque el escritorio es GTK». Medido en el `meson.build:94-99` de esta
+# versión, la dep que pide esa opción es `gtk+-3.0`, no `gtk4`:
+#
+#     gtk_req_version = '>= 3.2'
+#     gtk_dep = dependency('gtk+-3.0', version: gtk_req_version, required: get_option('gtk'), …)
+#
+# GTK3 es una de las tres deudas que el frente GNOME aparcó a propósito (GTK3 / X11 / PAM), así que
+# encenderla dejaría esta receta en `never` para siempre. Y no cuesta nada: lo que esa opción
+# construye es `libgnome-autoar-gtk`, un par de widgets de diálogo que **nautilus no usa** — lo que
+# nautilus enlaza es `gnome-autoar-0` a secas (la línea de arriba). El día que se autore GTK3, esto
+# es una bandera.
+#
+# ── `-Dintrospection=disabled`: no hay consumidor todavía ───────────────────────────────────────
+# La isla SÍ sabe hacer introspección (es su razón de ser, ver [[gnome-introspection-dinamica]]), y
+# encenderla acá sería correcto el día que algo la mire por typelib — file-roller, o una extensión
+# JS. Hoy el único consumidor es nautilus, que es C y la enlaza. Se apaga para no arrastrar a
+# `gobject-introspection` + `gi-foreign-girs` + `py3-setuptools` a un build que no los necesita, y
+# se deja dicho para que encenderla sea una línea y no una arqueología.
+#
+# ⚠ `default_library=shared` y no `both`: el mismo criterio que `libadwaita` en esta cola. El único
+# consumidor está en la isla y enlaza la `.so`; producir además una `.a` invita a que un consumidor
+# futuro la monte y reintroduzca el doble estado.
+#
+# ⚠ SIN `gettext-tiny` en deps, y es un hecho comprobado, no un descuido: este tarball NO TRAE `po/`
+# (`ls gnome-autoar-0.4.5` ⇒ COPYING NEWS README.md docs gnome-autoar gnome-autoar.doap meson.build
+# meson_options.txt tests). No hay traducciones que compilar ⇒ no hay `msgfmt` que reviente.
+name    = "gnome-autoar"
+version = "0.4.5"
+license = "LGPL-2.1-or-later"
+
+[source]
+tarball = "https://download.gnome.org/sources/gnome-autoar/0.4/gnome-autoar-0.4.5.tar.xz"
+sha256  = "838c5306fc38bfaa2f23abe24262f4bf15771e3303fb5dcb74f5b9c7a615dabe"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "dynamic"
+
+[build.phases]
+configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Dgtk=false -Dintrospection=disabled -Dvapi=false -Dtests=false -Dgtk_doc=false -Dc_args=-Wno-error=date-time"
+compile   = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
+install   = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
+
+[deps]
+# `libarchive-shared` y no `libarchive`: la canónica es estática y NO es PIC (3205 reubicaciones
+# `R_X86_64_32` fuera de `.debug`) ⇒ no entra en una `.so`. Ver el encabezado de esa receta.
+# glib + su cierre .pc (libffi/pcre2/zlib-shared) porque la hidratación es DIRECTA, no transitiva.
+build = ["meson", "samurai", "python3", "pkgconf", "glib", "libarchive-shared", "zlib-shared", "libffi", "pcre2"]
diff --git a/recipes/incoming-gnome/gvfs.toml b/recipes/incoming-gnome/gvfs.toml
new file mode 100644
index 00000000..25854e80
--- /dev/null
+++ b/recipes/incoming-gnome/gvfs.toml
@@ -0,0 +1,82 @@
+# gvfs 1.58.5 — el sistema de ficheros virtual de GIO: la papelera, los archivos comprimidos como
+# carpeta, el `dav://` y el `sftp://`. Es la MITAD QUE NADIE VE del gestor de ficheros: sin esto,
+# nautilus abre y navega, pero la papelera que dibuja no existe y «conectar a un servidor» no lleva
+# a ningún lado. Un gestor de ficheros que enseña una papelera que no funciona miente más que no
+# traerla — por eso `targets.toml` las declara PEGADAS.
+#
+# ── EL CENSO DE FRONTERA DECÍA 11 RECETAS NUEVAS. SON CERO, Y ESTÁ MEDIDO ───────────────────────
+# `docs/state/seed-gnome.json` lista `avahi fuse libbluray libcdio libcdio-paranoia libgphoto2
+# libimobiledevice libmtp libnfs samba udisks` como frontera de gvfs. Leído así, gvfs es una
+# campaña. Leído el `meson.build`, **todas menos una son backends OPCIONALES con su propia perilla**
+# (`meson_options.txt` líneas 5-31), y el núcleo —trash, archive, computer, admin, dav, sftp— sólo
+# pide `glib`, `gsettings-desktop-schemas` y `dbus-1`, que están sellados desde hace meses.
+# `fuse` aparecía como frontera y es `fuse3`, que YA está en el corpus. Es el seed avisando de lo
+# que avisa en su propia cabecera: sobreestima 5-10×.
+#
+# ── LO QUE SÍ FALTA, Y SE LLAMA `udisks` ────────────────────────────────────────────────────────
+# `-Dudisks2=false`. Ese backend es el monitor de volúmenes: **enchufar un USB y que aparezca**.
+# Pide `udisks2 >= 1.97` (`meson.build:344`) y el demonio `udisksd` del otro lado, que arrastra
+# `libblockdev` + `libatasmart` detrás. Es su propia unidad de trabajo, no una línea de esta receta.
+# ⇒ **Esta imagen monta lo que el `fstab` diga y lo que el usuario monte a mano; el montaje
+# automático de medios extraíbles NO existe todavía.** Escrito acá, en la receta, porque un hueco
+# escrito se ve y uno omitido se descubre con el pendrive en la mano.
+#
+# ── LOS BACKENDS, UNO POR UNO — todos DECLARADOS a propósito ────────────────────────────────────
+# ⚠ Los defaults de este proyecto son `true`: no declarar un backend NO es «apagado», es «encendido
+# si encuentra la lib». Se nombran los 18 para que el artefacto no dependa de qué haya en el
+# sysroot el día que se construya.
+#
+#   ENCENDIDOS (todo su cierre está sellado)
+#     admin     → abrir un fichero como root desde el gestor. libcap + polkit-gobject-1 (:306-307).
+#     archive   → un `.tar.gz` se navega como carpeta. libarchive.
+#     http      → `dav://` y `davs://`. libsoup-3.0 + libxml2 (:315, con `assert(have_libxml)`).
+#     sftp      → `sftp://`. **CERO deps de build**: habla con el binario `ssh`, que `base` ya trae.
+#                 El backend de red más barato que existe, y el que de verdad se usa.
+#     fuse      → `gvfsd-fuse`: expone los montajes a las apps que NO hablan GIO (todo lo que no es
+#                 GTK). Sin esto, un `dav://` montado es invisible para `cat`. fuse3 >= 3.0.
+#     gudev, gcr, gcrypt, keyring, logind → device, certificados, cifrado, contraseñas, sesión.
+#
+#   APAGADOS POR FALTA DE RECETA (cada uno = una frontera con nombre)
+#     dnssd(avahi) · smb(samba) · mtp(libmtp) · gphoto2 · afc(libimobiledevice) · nfs(libnfs) ·
+#     cdda(libcdio-paranoia) · bluray(libbluray) · goa+google+onedrive(gnome-online-accounts,
+#     libgdata, msgraph) · udisks2 — ver arriba.
+#
+#   APAGADOS POR DECISIÓN, con la lib disponible
+#     libusb  → sólo sirve para interrumpir operaciones de `mtp`/`gphoto2`, que están apagados.
+#     wsdd    → descubrimiento de equipos Windows; es el compañero de `smb`, que no está.
+#     afp     → protocolo de Apple anterior a 2013, reemplazado por SMB hasta en macOS. No cuesta
+#               deps; se apaga porque nadie lo va a hablar y cada backend es superficie de red.
+#     burn    → ya viene `false` de fábrica.
+#
+# ── `systemduserunitdir=no` / `tmpfilesdir=no` ──────────────────────────────────────────────────
+# No hay systemd (ADR 0007). Sin esto, meson busca el `.pc` de systemd para decidir dónde instalar
+# unidades que nadie va a leer. Los demonios de gvfs los levanta D-Bus por activación de sesión
+# —por eso esta receta NO declara `[[service]]`—; el fichero `.service` de D-Bus sí se instala.
+#
+# ⚠ EL `sed` DEL `ar`: `po/ar.po` de este tarball trae 1 `msgstr[5]`, y con uno alcanza para que el
+# `msgfmt` de gettext-tiny muera con SIGILL dejando un `.mo` de 0 bytes
+# ([[gettext-tiny-msgfmt-plural-arabe]]). Cuesta la traducción al árabe de gvfs.
+name    = "gvfs"
+version = "1.58.5"
+license = "LGPL-2.0-or-later"
+
+[source]
+tarball = "https://download.gnome.org/sources/gvfs/1.58/gvfs-1.58.5.tar.xz"
+sha256  = "be175df39c3ed48de7dce88c7ed72af7524dedc7119b1ff6bb2ac1566b912ce4"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "dynamic"
+
+[build.phases]
+configure = "sed -i '/^ar$/d' po/LINGUAS && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Dsystemduserunitdir=no -Dtmpfilesdir=no -Dadmin=true -Darchive=true -Dhttp=true -Dsftp=true -Dfuse=true -Dgudev=true -Dgcr=true -Dgcrypt=true -Dkeyring=true -Dlogind=true -Dafc=false -Dafp=false -Dburn=false -Dcdda=false -Ddnssd=false -Dgoa=false -Dgoogle=false -Dgphoto2=false -Dmtp=false -Dnfs=false -Donedrive=false -Dsmb=false -Dudisks2=false -Dwsdd=false -Dbluray=false -Dlibusb=false -Ddeprecated_apis=false -Ddevel_utils=false -Dinstalled_tests=false -Dman=false -Dunit_tests=false -Dc_args=-Wno-error=date-time"
+compile   = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
+install   = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
+
+[deps]
+# `dbus` (la estática) entra por el `.pc`, no por el link: gvfs le pregunta
+# `session_bus_services_dir` (:253) para saber dónde dejar sus ficheros de activación.
+# `libarchive-shared` y no la canónica: gvfs instala `libgvfscommon.so` y la canónica no es PIC.
+# `libelogind` es la que responde al `dependency('libsystemd')` fallido de :350-352.
+build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "glib", "gsettings-desktop-schemas", "dbus", "libxml2-shared", "libsoup", "libpsl", "nghttp2", "libarchive-shared", "fuse3", "libgudev", "gcr", "p11-kit", "polkit", "libcap", "libsecret", "libgcrypt-shared", "libgpg-error-shared", "libelogind", "udev-pc", "sqlite-shared", "icu4c", "zlib-shared", "libffi", "pcre2"]
diff --git a/recipes/incoming-gnome/libarchive-shared.toml b/recipes/incoming-gnome/libarchive-shared.toml
new file mode 100644
index 00000000..4c3ed87b
--- /dev/null
+++ b/recipes/incoming-gnome/libarchive-shared.toml
@@ -0,0 +1,58 @@
+# libarchive-shared 3.8.1 — variante DINÁMICA de libarchive para la isla de GNOME.
+#
+# POR QUÉ EXISTE, y está MEDIDO, no supuesto. `gnome-autoar` produce `libgnome-autoar-0.so` y
+# enlaza libarchive adentro. La canónica (`recipes/libarchive.toml`) es `--disable-shared` y su
+# `.a` NO es PIC:
+#
+#     readelf -r libarchive.a | awk '/^Relocation section/{s=$3}
+#                                    /R_X86_64_32/{if (s !~ /debug/) n++} END{print n+0}'
+#     ⇒ 3205                                   (control: libcap.a=0, dbus-1.a=0, json-glib.a=0)
+#
+# O sea exactamente el cuadro de `fontconfig` que documenta `libadwaita.toml`: el link de la `.so`
+# muere con `relocation R_X86_64_64 cannot be used against local symbol`. El awk excluye las
+# secciones `.rela.debug_*` a propósito — la regla corta (`grep R_X86_64_32`) miente, y la memoria
+# [[gnome-introspection-dinamica]] tiene el caso de libepoxy que lo prueba.
+#
+# NO se toca la canónica: `yupana radio libarchive` la comparte el corpus (bsdtar/bsdcpio son el
+# extractor de referencia cruzada del plan-freebsd) y cambiarla re-hashearía a sus consumidores por
+# nada. El sufijo `-shared` NO sombrea al padre — sólo la consume quien la declara explícito, que es
+# el mismo patrón de `zlib-shared`/`libgcrypt-shared` en esta misma cola.
+#
+# MISMO CONJUNTO DE FORMATOS que la canónica (sólo zlib), a propósito: esta variante existe por el
+# PIC, no para ampliar el alcance. Si mañana `gvfsd-archive` quiere leer un `.tar.zst`, eso es una
+# línea en las dos recetas y un re-sellado — no se adelanta acá.
+#
+# -fno-sanitize=undefined: zig cc inyecta el runtime UBSan y la `.so` queda con referencias a
+# `__ubsan_handle_*` que nadie define, que `--no-allow-shlib-undefined` rechaza. Lo documentan ya
+# `zlib-shared` y `libgcrypt-shared`; la canónica lo lleva por la razón simétrica (no arrastrar esas
+# llamadas a todo consumidor estático).
+name    = "libarchive-shared"
+version = "3.8.1"
+license = "BSD-2-Clause"
+
+[source]
+tarball = "https://github.com/libarchive/libarchive/releases/download/v3.8.1/libarchive-3.8.1.tar.xz"
+sha256  = "19f917d42d530f98815ac824d90c7eaf648e9d9a50e4f309c812457ffa5496b5"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "dynamic"
+
+[build.phases]
+# Sin `--enable-bsdtar/--enable-bsdcpio`: los ejecutables ya los da la canónica y dos `bsdtar` en el
+# mismo store serían dos proveedores del mismo nombre. Esta receta publica la librería y nada más.
+configure = """
+CFLAGS='-O2 -fPIC -fno-sanitize=undefined' ./configure --build=$CBUILD --host=$CHOST --prefix=/usr \
+  --enable-shared --disable-static --with-pic \
+  --disable-bsdtar --disable-bsdcpio --disable-bsdcat --disable-bsdunzip \
+  --with-zlib --without-bz2lib --without-lzma --without-zstd --without-lz4 \
+  --without-lzo2 --without-libb2 --without-iconv --without-xml2 --without-expat \
+  --without-openssl --without-nettle --without-cng --disable-acl --disable-xattr
+"""
+compile = 'make -j"$(nproc)"'
+install = 'make DESTDIR=/out install'
+
+[deps]
+# `zlib-shared` y no `zlib`: la canónica es estática y el mismo argumento del PIC vale para ella.
+build = ["make", "zlib-shared"]
diff --git a/recipes/incoming-gnome/libportal.toml b/recipes/incoming-gnome/libportal.toml
new file mode 100644
index 00000000..e81e4cc3
--- /dev/null
+++ b/recipes/incoming-gnome/libportal.toml
@@ -0,0 +1,57 @@
+# libportal 0.9.1 — la librería cliente de los portales XDG. Es dep DURA de nautilus, y DOS VECES:
+#
+#     meson.build:123  libportal      = dependency('libportal',      version: '>= 0.7')
+#     meson.build:124  libportal_gtk4 = dependency('libportal-gtk4', version: '>= 0.5')
+#
+# ── UNA RECETA DA LAS DOS LIBRERÍAS, y por eso el censo de frontera contaba de más ──────────────
+# `targets.toml` listaba `libportal-gtk4` como una frontera aparte. No lo es: sale del MISMO source.
+# `libportal/meson.build:186` construye el backend GTK4 desde esta misma compilación
+# (`gtk4_dep = dependency('gtk4', required: get_option('backend-gtk4'))`), y el tarball publica
+# `libportal.pc` y `libportal-gtk4.pc` juntos. Es la misma forma que el seed de nixpkgs ya avisa que
+# tiene (sobreestima 5-10×): un `.pc` extra se lee como un paquete extra.
+#
+# ── QUÉ ES, para que el apagado de abajo se entienda ────────────────────────────────────────────
+# El portal es el camino por el que una app pide al escritorio algo que no puede hacer sola: abrir
+# el selector de ficheros del sistema, abrir un URI, pedir una captura. En nautilus es lo que hace
+# que «abrir con otra aplicación» y el diálogo de ficheros de otras apps hablen el mismo idioma.
+# El servidor del otro lado —`xdg-desktop-portal` + `xdg-desktop-portal-gnome`— YA está sellado en
+# esta cola. Esta receta es el lado cliente.
+#
+# ── LOS CUATRO BACKENDS, y por qué sólo uno ─────────────────────────────────────────────────────
+#   backend-gtk4  = enabled   ← el que pide nautilus. `gtk4` es la isla dinámica de esta cola.
+#   backend-gtk3  = disabled  ← GTK3 está aparcado por diseño en este frente (ver gnome-autoar).
+#   backend-qt5   = disabled  ┐ son el camino de KDE, que vive en OTRA cola y es estático. Con
+#   backend-qt6   = disabled  ┘ `auto` meson los buscaría y encenderlos acá mezclaría los dos mundos.
+# ⚠ Las cuatro son `feature` con valor `auto`: dejarlas sin declarar NO es neutral, es «encendé lo
+# que encuentres». Se declaran las cuatro a propósito para que el artefacto no dependa de qué haya
+# en el sysroot el día que se construya.
+#
+# `-Ddocs=false` saca `gi-docgen` (default `true`, y no está en el catálogo).
+# `-Dintrospection=false` / `-Dvapi=false`: mismo criterio que gnome-autoar — el consumidor de hoy
+# es C. Encenderlas es una línea el día que una extensión JS quiera Portal por typelib.
+#
+# ⚠ SIN `gettext-tiny`: este tarball tampoco trae `po/` (comprobado: sus subdirs son `libportal`,
+# `portal-test`, `tests` y `doc`).
+name    = "libportal"
+version = "0.9.1"
+license = "LGPL-3.0-only"
+
+[source]
+tarball = "https://github.com/flatpak/libportal/releases/download/0.9.1/libportal-0.9.1.tar.xz"
+sha256  = "de801ee349ed3c255a9af3c01b1a401fab5b3fc1c35eb2fd7dfb35d4b8194d7f"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "dynamic"
+
+[build.phases]
+configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Dbackend-gtk4=enabled -Dbackend-gtk3=disabled -Dbackend-qt5=disabled -Dbackend-qt6=disabled -Dintrospection=false -Dvapi=false -Ddocs=false -Dtests=false -Dportal-tests=false -Dc_args=-Wno-error=date-time"
+compile   = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
+install   = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
+
+[deps]
+# gtk4 + su cierre `.pc` completo: la hidratación es DIRECTA, no transitiva, así que lo que
+# `gtk4.pc` declara en `Requires` tiene que estar nombrado acá. La lista es la de `gtk4.toml`
+# (misma cola) menos lo que sólo hace falta para construir gtk4 en sí.
+build = ["meson", "samurai", "python3", "pkgconf", "glib", "gtk4", "cairo-shared", "pango", "gdk-pixbuf", "graphene", "libepoxy", "wayland", "wayland-protocols", "libxkbcommon", "libdrm", "fontconfig-shared", "harfbuzz", "fribidi", "libpng-shared", "pixman", "freetype-shared", "expat", "libffi", "pcre2", "zlib-shared", "libtiff-shared", "libjpeg-turbo-shared", "mesa"]
diff --git a/recipes/incoming-gnome/nautilus.toml b/recipes/incoming-gnome/nautilus.toml
new file mode 100644
index 00000000..408b8c8e
--- /dev/null
+++ b/recipes/incoming-gnome/nautilus.toml
@@ -0,0 +1,78 @@
+# nautilus 48.7 — el gestor de ficheros de GNOME. Es el `dolphin` de este escritorio: hasta hoy el
+# perfil `escritorio-gnome` tenía shell, terminal, portales y llavero, y **ninguna forma de ver una
+# carpeta**. Va PEGADO a `gvfs` (misma tanda, receta hermana): sin gvfs esta app abre y navega, pero
+# la papelera que dibuja no existe.
+#
+# ── LAS CUATRO DEPS QUE NO SE PUEDEN APAGAR, con su línea ───────────────────────────────────────
+# El `meson.build` de esta versión las pide sin `required: false` — no hay perilla:
+#     :114  gnome-autoar-0   >= 0.4.4     ← extraer/comprimir desde el menú contextual
+#     :115  gnome-desktop-4  >= 43        ← ya sellada en esta cola (44.5)
+#     :123  libportal        >= 0.7    ┐  ← las dos salen de UNA receta, ver libportal.toml
+#     :124  libportal-gtk4   >= 0.5    ┘
+#     :129  tracker-sparql-3.0           ← la da `tinysparql` (publica ese `.pc` además del suyo)
+# Y `gtk4 >= 4.17.5` (:116), que la isla cumple con 4.18.6 — comprobado antes de elegir la versión,
+# porque un nautilus 48 sobre un gtk4 viejo no configura.
+#
+# ── `-Dextensions=false`: LO QUE SE PIERDE, DICHO CON NOMBRE ────────────────────────────────────
+# Es la perilla más cara de esta receta y conviene no disfrazarla. Con `extensions=true` (el
+# default) el bloque `:104-109` exige CUATRO deps de golpe: `gexiv2`, `gdk-pixbuf`,
+# `gstreamer-tag-1.0` y `gstreamer-pbutils-1.0`. De ésas sólo `gdk-pixbuf` está sellada; `gexiv2`
+# arrastra exiv2 (C++ grande) y las dos de gst arrastran gstreamer + gst-plugins-base enteros.
+#
+# ⇒ **Lo que NO va a estar: las pestañas de metadatos en «Propiedades».** Nada de EXIF de una foto
+# (cámara, apertura, fecha de disparo) ni de etiquetas de un MP3/vídeo (artista, duración, códec).
+# El resto de Propiedades —tamaño, permisos, tipo, abrir-con— es del núcleo y sí está. Es una app
+# completa con una pestaña menos, no una app mutilada; y el día que entre gstreamer al catálogo
+# —que es un frente propio, con las apps de usuario final detrás— esto es UNA bandera.
+#
+# ── LAS OTRAS PERILLAS ──────────────────────────────────────────────────────────────────────────
+#   -Dpackagekit=false     (default `true`) → PackageKit es el gestor de paquetes de las distros
+#                           rpm/deb; esta distro tiene el suyo (`takana install`, Etapa F). Sirve
+#                           para «este fichero no se abre con nada, ¿instalo algo?» y acá no hay del
+#                           otro lado a quién preguntarle. Dejarlo en `true` no rompe el build (habla
+#                           por D-Bus) pero deja un diálogo que nunca puede contestar.
+#   -Dcloudproviders=false (default `true`) → `libcloudproviders`, la barra lateral de Dropbox y
+#                           compañía. No está en el catálogo y no hay cliente que la pueble.
+#   -Dintrospection=false  → el typelib de `libnautilus-extension`, para extensiones en Python/JS.
+#                           No hay ninguna todavía; la isla sabe hacerlo cuando la haya.
+#   -Dselinux=false        → ya es el default; se declara porque el seed lo listaba como frontera y
+#                           no lo es: no hay SELinux en esta distro (musl, sin systemd).
+#   -Dtests=headless→none  → el default COMPILA tests; ninguno se instala.
+#
+# ── LA BÚSQUEDA, Y POR QUÉ NO ES LA COMPLETA ────────────────────────────────────────────────────
+# `tinysparql` da la librería y el almacén, pero el INDEXADOR (`localsearch`, ex tracker-miners) no
+# está en el catálogo. Sin él, nautilus usa `NautilusSearchEngineSimple`: encuentra por NOMBRE
+# recorriendo directorios, sin índice y sin mirar dentro de los ficheros. Está escrito también en el
+# encabezado de `tinysparql.toml`; se repite acá porque es lo que el usuario nota.
+#
+# ⚠ EL `sed` DEL `ar`, y acá es el caso más grosero de todos: `po/ar.po` trae **86** `msgstr[5]`.
+# El `msgfmt` de gettext-tiny muere con SIGILL ante el primero ([[gettext-tiny-msgfmt-plural-arabe]]).
+# Cuesta la traducción al árabe del gestor de ficheros; el arreglo real es autorar el gettext de GNU
+# y es una campaña de 108 recetas.
+name    = "nautilus"
+version = "48.7"
+license = "GPL-3.0-or-later"
+
+[source]
+tarball = "https://download.gnome.org/sources/nautilus/48/nautilus-48.7.tar.xz"
+sha256  = "60a7a371b5536fe329ced90cce46fff9b7b3ae256d448e1cb796df29d32ee235"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "dynamic"
+
+[build.phases]
+configure = "sed -i '/^ar$/d' po/LINGUAS && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Dextensions=false -Dintrospection=false -Dpackagekit=false -Dcloudproviders=false -Dselinux=false -Ddocs=false -Dtests=none -Dc_args=-Wno-error=date-time"
+compile   = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
+install   = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
+
+[deps]
+# La lista es el cierre `.pc` COMPLETO, no las deps directas: la hidratación de takana es directa y
+# no transitiva, y `pkg-config` aborta si falta un `.pc` nombrado en `Requires.private` aunque el
+# link sea dinámico. Los tres que la gente olvida, verificados leyendo los `.pc` del store:
+#   libadwaita-1.pc     Requires.private: … appstream   ⇒ appstream + libxmlb + libyaml-shared +
+#                                                          curl + openssl + zstd
+#   gnome-desktop-4.pc  Requires.private: … xkeyboard-config, iso-codes, libseccomp
+#   libsoup-3.0.pc      Requires.private: sqlite3, libpsl, zlib, libnghttp2
+build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "glib", "gtk4", "libadwaita", "gnome-desktop", "gsettings-desktop-schemas", "gnome-autoar", "libarchive-shared", "libportal", "tinysparql", "json-glib", "libsoup", "libpsl", "nghttp2", "sqlite-shared", "icu4c", "libxml2-shared", "dbus", "appstream", "libxmlb", "libyaml-shared", "curl", "openssl", "zstd", "xkeyboard-config", "iso-codes", "libseccomp", "pango", "gdk-pixbuf", "cairo-shared", "graphene", "harfbuzz", "fribidi", "fontconfig-shared", "freetype-shared", "pixman", "libpng-shared", "expat", "libjpeg-turbo-shared", "libtiff-shared", "libepoxy", "wayland", "wayland-protocols", "libxkbcommon", "libdrm", "mesa", "pcre2", "libffi", "zlib-shared"]
diff --git a/recipes/incoming-gnome/tinysparql.toml b/recipes/incoming-gnome/tinysparql.toml
new file mode 100644
index 00000000..65e3598d
--- /dev/null
+++ b/recipes/incoming-gnome/tinysparql.toml
@@ -0,0 +1,72 @@
+# tinysparql 3.9.2 — el motor SPARQL que antes se llamaba Tracker. Es dep DURA de nautilus:
+# `meson.build:129` pide `dependency('tracker-sparql-3.0')` a secas, sin `required: false`.
+#
+# ── EL NOMBRE CAMBIÓ Y EL `.pc` NO: verificado en la fuente, no supuesto ────────────────────────
+# El proyecto se renombró Tracker → TinySPARQL, y la duda razonable es si nautilus 48 (que sigue
+# pidiendo `tracker-sparql-3.0`) encuentra a un paquete que se llama distinto. Lo encuentra, porque
+# esta versión publica LOS DOS nombres desde el mismo `pkgconfig.generate`:
+#
+#     src/libtinysparql/meson.build:146    name: 'tinysparql-3.0',
+#     src/libtinysparql/meson.build:155    name: 'tracker-sparql-3.0',
+#
+# ── QUÉ COMPRA, y qué NO — para no vender búsqueda que no hay ───────────────────────────────────
+# Esto es la LIBRERÍA y el almacén: la base de datos SPARQL sobre sqlite y la API con la que
+# nautilus consulta. **No es el indexador.** Quien recorre el disco y puebla el índice es
+# `localsearch` (el ex `tracker-miners`), que NO está en el catálogo y que esta tanda no trae.
+#
+# ⇒ Con esto, nautilus construye y su búsqueda cae en `NautilusSearchEngineSimple`, que enumera
+# directorios a mano: encuentra por NOMBRE y sólo donde mira, sin contenido y sin índice. Es una
+# búsqueda de verdad, más lenta y más ciega. La alternativa era declarar `localsearch` ahora y
+# arrastrar gexiv2 + gstreamer + poppler detrás de una app que todavía no existía. Queda escrito
+# acá para que «falta el indexador» sea una frase que alguien pueda leer, y no un misterio de por
+# qué buscar dentro de un PDF no devuelve nada.
+#
+# ── LAS PERILLAS, con lo que cada una evita ─────────────────────────────────────────────────────
+#   -Dintrospection=disabled  (default `enabled`) → g-i; el consumidor de hoy (nautilus) es C.
+#   -Dvapi=disabled           (default `enabled`) → `valac`, que NO existe en el catálogo. Sin esta
+#                              línea el configure aborta: es la que de verdad bloquea, no un ahorro.
+#   -Dman=false               (default `true`)    → `a2x`/asciidoc (`meson.build:81`).
+#   -Ddocs=false              (default `true`)    → gi-docgen.
+#   -Dtests=false             (default `true`)    → el módulo Python `gi` en el sandbox (:86).
+#   -Dstemmer=disabled        → `libstemmer`: lematización al indexar. No está en el catálogo, y sin
+#                              indexador propio todavía no tiene a quién servir.
+#   -Davahi=disabled          → descubrimiento de endpoints SPARQL en la red local. Es la misma
+#                              `avahi` que gvfs apaga en esta tanda; el día que entre, son dos líneas.
+#   -Dbash_completion=false -Dsystemd_user_services=false → ficheros que esta distro no consume
+#                              (no hay systemd; ver ADR 0007).
+#   -Dunicode_support=icu     → EXPLÍCITO y no `auto`. `meson.build:240` elige icu si la encuentra y
+#                              si no cae a `libunistring`; con `auto`, el artefacto dependería de qué
+#                              haya en el sysroot. `icu4c` ya está sellada y trae 18 `.so`.
+#
+# ⚠ `sqlite-shared` y no `sqlite`: `libsqlite3.a` de la canónica NO es PIC (5952 reubicaciones
+# `R_X86_64_32` fuera de `.debug`, medido) y esto produce `libtinysparql-3.0.so`. Mismo caso que
+# libarchive en `gnome-autoar`.
+#
+# ⚠ EL `sed` DEL `ar`: es la mina conocida de `gettext-tiny`, no una manía. Su `msgfmt` revienta con
+# SIGILL ante un mensaje de SEIS formas plurales y deja un `.mo` de 0 bytes
+# ([[gettext-tiny-msgfmt-plural-arabe]]). Medido en ESTE tarball: `po/ar.po` trae **7** `msgstr[5]`.
+# Cuesta la traducción al árabe de esta pieza; el arreglo de verdad es autorar el gettext de GNU, que
+# es una campaña (108 recetas lo declaran) y no se hace de paso.
+name    = "tinysparql"
+version = "3.9.2"
+license = "GPL-2.0-or-later AND LGPL-2.1-or-later"
+
+[source]
+tarball = "https://download.gnome.org/sources/tinysparql/3.9/tinysparql-3.9.2.tar.xz"
+sha256  = "14ce039024135e181022bcce4b1aad2e00377dd9c7d812b98391ccfc756dad8e"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "dynamic"
+
+[build.phases]
+configure = "sed -i '/^ar$/d' po/LINGUAS && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Dintrospection=disabled -Dvapi=disabled -Dman=false -Ddocs=false -Dtests=false -Dstemmer=disabled -Davahi=disabled -Dbash_completion=false -Dsystemd_user_services=false -Dunicode_support=icu -Dc_args=-Wno-error=date-time"
+compile   = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
+install   = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
+
+[deps]
+# `libsoup` es OBLIGATORIA acá, no opcional: `meson.build:63` la pide con `required: true` (sirve el
+# endpoint SPARQL sobre HTTP). Va con su cierre — libpsl, nghttp2, sqlite-shared, icu4c, zlib-shared.
+# `dbus` entra por el `.pc`: tinysparql lee de él dónde van los servicios de sesión.
+build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "glib", "json-glib", "libxml2-shared", "sqlite-shared", "icu4c", "dbus", "libsoup", "libpsl", "nghttp2", "zlib-shared", "libffi", "pcre2"]