Barrido de TEXTO puro: 1427 líneas de comentario TOML. Cero ArtifactHash
movidos, y eso está MEDIDO, no deducido: hasheé las 741 antes y después y los
ficheros de hashes son idénticos byte a byte (723 con hash real + 18 que ya no
hasheaban de antes).
El guardián valió la pena: el primer barrido, filtrando por 'la línea empieza
con #', movió el hash de helix, lsof y steam-runtime-sniper. La causa es que una
fase se escribe como compile = <triple> ... <triple> y sus comentarios de SHELL
también empiezan con #, pero viven dentro del VALOR — y las fases sí entran en
hash_inputs. El barrido ahora calcula los rangos de las cadenas multilínea de
TOML y no entra ahí.
Quedan intactos a propósito: .hammer-zig-cc y .hammer-cargo-vendor (literales
dentro de fases), hammerd, hammer-recover y toda ruta que empiece por /
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>
Cierra el segfault mudo de iris. El intento anterior (`-Wl,--build-id=sha1`) NO prendió:
meson lo registra pero `zig cc` 0.13 lo ignora en silencio — el configure lo dice
(«supports link arguments -Wl,--build-id=sha1: NO») y la .so sale sin ninguna nota.
zig 0.16 sí la emite (verificado a mano), pero `zig_version` está pineada a 0.13.0 como
escotilla contra la regresión de zig 0.14: subirlo cambia un muro por otro.
Tampoco había escape por entorno, y esta vez medido sobre el fuente en vez de deducido:
el retorno temprano es `if (INTEL_DEBUG(DEBUG_DISK_CACHE_DISABLE_MASK))` y en 24.0.9 esa
máscara está definida como 0 ⇒ el `if` no dispara nunca. Por eso el desensamblado no
tenía ni un salto condicional: el compilador lo dobló.
`-Dshader-cache=disabled` lo garantiza el preprocesador — el cuerpo entero de
`iris_disk_cache_init` vive en un `#ifdef ENABLE_SHADER_CACHE`. Verificado en el
artefacto: la función es ahora un único `ret`.
MEDIDO EN METAL (OptiPlex 3060 / UHD 630), bibliotecas desplegadas por SSH sobre la
máquina viva, sin re-quemar el USB: sesión COSMIC completa arriba — cosmic-comp, panel
con applets, bg, launcher, term, toplevel, workspaces — y CERO segfaults nuevos.
Confirmado en pantalla por el usuario.
Costo aceptado: sin caché en disco los shaders se recompilan en cada arranque.
Re-sella mesa: b3:6d443d9f… → b3:f43c41d1…
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Causa raíz del escritorio COSMIC que no arrancaba en metal, medida en el OptiPlex 3060
(UHD 630). cosmic-comp moría sin panic y con RUST_BACKTRACE=full; el dmesg tenía la
respuesta que ningún log de usuario podía dar:
cosmic-comp[1266]: segfault at 10 ip ... error 4 in iris_dri.so[9626c0,...]
El offset resuelve a `_mesa_sha1_format` (bytes del desensamblado idénticos al `Code:`
del kernel), y su llamador `iris_disk_cache_init` es tres llamadas seguidas sin un solo
salto condicional entre medio:
build_id_find_nhdr_for_addr → NULL (ninguna .so de mesa traía nota)
build_id_data → NULL+0x10 (offsetof del campo)
_mesa_sha1_format → lee 0x10 ⇒ SIGSEGV
El `assert(note && ...)` que cazaba esto lo borra -Db_ndebug=true.
Tres decisiones razonables por separado que juntas dan un cuelgue mudo: meson no pide
build-id, lld no lo pone solo (37 de 40 .so del corpus SÍ lo traen — era exclusivo de
mesa) y el assert no existe en release. No lo salva MESA_SHADER_CACHE_DISABLE: la
desreferencia va antes de consultar si la caché está habilitada. Y no se ve en QEMU,
donde el userland es swrast/llvmpipe y esta ruta es de iris.
Fix: -Dc_link_args/-Dcpp_link_args con -Wl,--build-id=sha1.
Re-sella mesa: b3:6d443d9f… → b3:c3c18cde…
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Mesa sellada: store/607a513c…-mesa con dri/iris_dri.so + libEGL/libgbm/libGLESv2/
libglapi + egl/gbm/glesv2.pc. El stack gráfico para el escritorio tawasuyu (Iris Xe)
queda completo: libdrm✓ wayland✓ wayland-protocols✓ seatd✓ mesa✓.
Decisiones/fixes clave:
- PIN 24.0.9 (no 26.1.1): desde Mesa 24.1 iris REQUIERE intel-clc (kernels OpenCL-C
internos) ⇒ libclc + clang/LLVM, lo que rompe el plan iris-sin-LLVM. Bisección: 24.0.9
es el último donde with_clc=FALSE con iris-only sin Vulkan/rusticl. (Decisión del usuario:
pinear Mesa viejo en vez de construir LLVM.)
- recorte iris-only: -Dllvm=disabled -Dintel-clc=disabled, sin Vulkan/glx/rusticl/codecs/tools.
- packaging (módulo Python puro): el chequeo de versión de mako usa packaging.version y
Python 3.12 ya no trae distutils ⇒ sin packaging fallaba con el engañoso «mako required».
- PYTHONPATH al site-packages en configure Y compile (el codegen mako corre en ninja).
- libffi en deps: lo pide wayland-client.pc (Requires: libffi) al resolver cflags.
- mesa-version-script-comma.patch: el target DRI emitía «-Wl,--version-script dri.sym»
(token separado) que zig cc reordena ⇒ «cannot find version script --end-group» al ligar
libgallium_dri.so. La forma coma «-Wl,--version-script,dri.sym» (un token) lo arregla.
Runtime pendiente (ensamblado de rootfs): iris_dri.so/libEGL necesitan libz.so.1, libzstd.so.1
(de la base), libdrm.so.2, wayland .so. mirada-greeter (Cargo, link dinámico a Mesa) ya desbloqueado.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>