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

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

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

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

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

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

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 10:24:11 -04:00

102 lines
7.2 KiB
TOML

# accountsservice 23.13.9 — el servicio D-Bus de cuentas de usuario (nombre, avatar, idioma, si es
# administrador). Lo pide gnome-shell desde JAVASCRIPT, no desde C: por eso no aparecía en el
# meson.build de la cima ni en su cierre de build, y sólo se destapó ARRANCANDO la sesión:
#
# Gjs-CRITICAL: JS ERROR: Requiring AccountsService, version 1.0:
# Typelib file for namespace 'AccountsService', version '1.0' not found
# Execution of main.js threw exception
#
# Lección del método: **el cierre de BUILD no es el cierre de RUNTIME**. gnome-shell selló con
# 108/108 recetas y aun así le falta esto, porque `imports.gi.AccountsService` se resuelve en tiempo
# de ejecución. Toda dep que el shell cargue por typelib desde JS es invisible al build.
#
# -Delogind=true es la pieza que hace que esto entre gratis: accountsservice pide `libsystemd` por
# defecto (meson.build:219) y con esta opción pide `libelogind` (:217), que YA está sellada —
# arje-sdlogin-compat, con Version 255 en su .pc, por encima del >= 229.4 que exige. Es la quinta vez
# en la campaña que la C-ABI de logind aparece, y la primera que se resuelve sin esquivarla.
#
# Apagados:
# -Dvapi=false → no hay valac en el corpus.
# -Ddocbook=false -Dgtk_doc=false → xmlto/gtk-doc.
# -Dsystemdsystemunitdir=no → no instala units de systemd; acá PID1 es arje-zero. Ojo: el valor
# tiene que ser literalmente `no`, NO la cadena vacía — con vacía el meson
# interpreta "averiguá el directorio" y ASERTA pidiendo systemd.pc (:183).
# libxcrypt es `required: false` (meson.build:161) ⇒ no hace falta receta: sin ella el servicio no
# cambia contraseñas, que no es lo que el shell le pide (le pide el usuario y su avatar).
#
# `generate-version.sh` se reemplaza por un `echo` de la versión. El script del tarball deriva la
# versión del NOMBRE DEL DIRECTORIO (`basename $PWD | sed 's/^accountsservice-\(.*\)$/\1/'`), y en el
# sandbox de hammer el árbol de fuentes es `/src` ⇒ no matchea y aborta con "Version unknown". Fijarla
# además la vuelve DETERMINISTA: la otra rama del script (la de checkout git) calcula la versión con
# `date` sobre el último commit, que es exactamente lo que un store direccionable por contenido no
# puede tolerar.
#
# El otro sed borra una ASERCIÓN sobre wtmp (meson.build:107). accountsservice busca el fichero de
# histórico de logins probando `WTMPX_FILENAME` y `_PATH_WTMPX`; **musl no define ninguno de los dos**
# —no implementa wtmp—, así que cae a la rama final, que exige que `/var/log/utx.log` EXISTA en el
# constructor y aborta si no. Se borra sólo la línea del assert: la rama igual deja
# `PATH_WTMP='/var/log/utx.log'`, o sea que el servicio vigila esa ruta y, como nunca aparece, no
# reporta histórico de sesiones. Lo que el shell le pide —el usuario, su nombre y su avatar— no
# depende de wtmp. La alternativa era `touch` ese fichero en el sandbox para que el chequeo pasara,
# que es hacer verdadera una premisa falsa; preferible borrar el chequeo y decir por qué.
#
# Y un tercer sed saca `subdir('tests')` (:235), que accountsservice no expone como opción. No es por
# ahorrar tiempo de build: los tests arrastran el subproyecto `mocklibc`, que llama `fgetgrent()` —
# una extensión GNU que **musl no implementa**. No hay forma de compilarlo acá, y lo que se pierde es
# la suite del upstream, no la librería.
#
# El sed saca `subdir('po')`. QUINTA vez que el msgfmt de gettext-tiny obliga a esto (iso-codes, gcr,
# eds, gnome-shell y ahora ésta). Ya no es un gotcha: es la deuda de autorar el gettext de GNU.
#
# ISLA DINÁMICA: -Dintrospection=true + shared, porque lo que falta es justamente el TYPELIB.
#
# ══ LOS DOS HUECOS QUE HUBO QUE TAPAR, Y NINGUNO ERA DE accountsservice ═════════════════════════
# El configure pasaba entero desde el principio; lo que cortaba era el COMPILE, por dos motivos
# independientes, los dos de NUESTRA capa de compatibilidad. Se cuentan acá porque el trabajo real
# de esta receta está afuera de ella:
#
# 1. LA C-ABI DE sd-login SE QUEDABA CORTA. `libelogind` (arje-sdlogin-compat) exportaba 14 símbolos
# —los que necesitaba mutter— y accountsservice usa OCHO que no estaban:
# sd_get_sessions · sd_seat_can_multi_session · sd_session_get_display
# sd_login_monitor (el tipo) · sd_login_monitor_new · sd_login_monitor_unref
# sd_login_monitor_get_fd · sd_login_monitor_flush
# Los cinco de `sd_login_monitor_*` eran la parte con enjundia: no son getters sobre ficheros sino
# una API de NOTIFICACIÓN (un fd que se mete en un poll y despierta cuando cambia el estado de
# sesiones). Implementados con inotify sobre /run/systemd/{sessions,seats,users}, que es donde
# vive ese estado. Ahora libelogind exporta 22.
#
# 2. `fgetspent_r` NO EXISTE EN musl (extensión de glibc; la usa src/daemon.c:265). Se tapa con
# `accountsservice-fgetspent_r-musl.patch`, que la implementa sobre el `fgetspent()` que musl SÍ
# tiene, copiando el registro al buffer del llamador. La copia no es adorno: daemon.c GUARDA esos
# buffers en un GHashTable, y `fgetspent()` devuelve un struct estático que se reescribe en cada
# llamada. El parche sigue el patrón que el propio accountsservice ya usa para /etc/passwd
# (`src/fgetpwent.c` incluido bajo `#ifndef HAVE_FGETPWENT`).
#
# SELLA: b3:0328b0d0. Produce `AccountsService-1.0.typelib`, que es lo que la capa JS del shell pedía.
#
# CÓMO SE DESTAPÓ, y es la lección de método: gnome-shell selló con su cierre de build COMPLETO
# (108/108) y aun así la sesión murió pidiendo este typelib. **El cierre de build no es el cierre de
# runtime**: todo lo que el shell carga por `imports.gi.*` desde JavaScript es invisible al grafo de
# deps. Se encuentra arrancando, no compilando.
name = "accountsservice"
version = "23.13.9"
license = "GPL-3.0-or-later"
[source]
tarball = "https://www.freedesktop.org/software/accountsservice/accountsservice-23.13.9.tar.xz"
sha256 = "adda4cdeae24fa0992e7df3ffff9effa7090be3ac233a3edfdf69d5a9c9b924f"
patches = ["accountsservice-fgetspent_r-musl.patch"]
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
[build.phases]
configure = "printf '#!/bin/sh\\necho 23.13.9\\n' > generate-version.sh && sed -i \"/^subdir('po')$/d\" meson.build && sed -i '/Do not know which filename to watch for wtmp changes/d' meson.build && sed -i \"/^subdir('tests')$/d\" meson.build && 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 -Delogind=true -Dintrospection=true -Dvapi=false -Ddocbook=false -Dgtk_doc=false -Dsystemdsystemunitdir=no -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]
build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "py3-setuptools", "gi-foreign-girs", "gobject-introspection", "glib", "glib-introspected", "polkit", "dbus-shared", "libelogind", "libffi", "pcre2", "zlib-shared", "expat"]