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 /
Los añadí durante el diagnóstico y luego los verifiqué uno a uno quitándolos:
la receta construye igual sin ellos. Dejarlos era cargo-cult, y encima el
comentario afirmaba cosas que mis propias pruebas ya habían desmentido.
La causa real es UNA y las dos únicas piezas necesarias siguen ahí: quitar la
dep `linux-headers` (Linux 6.16 tapando los headers 7.1 del rootfs) y el
cherry-pick de upstream para el `io_uring_buf_reg` de 7.1.
Ambos descartes quedan escritos en la receta para que nadie los re-intente:
`--enable-bundled=yes` no puede ganar porque zig-cc impone sus headers por
delante de cualquier `-isystem`, y la versión de zig es irrelevante porque los
headers que mandan son los del ROOTFS.
Verificado tras la limpieza: sella, y `strace -c /bin/true` traza 30 syscalls.
Dos cambios, una causa: el sandbox sirve headers UAPI MÁS NUEVOS de lo que
strace 6.19 espera, y la receta traía una dep que los ensombrecía con otros
más VIEJOS.
1) Fuera `linux-headers` de [deps]. Esa receta instala Linux 6.16 en
/usr/include y TAPA los headers del rootfs (7.1). Con ella faltaban 35
constantes —18 de btrfs.h, 17 de input-event-codes.h— y como los xlat de
strace son `#unconditional` (sin guardas #ifdef), una constante ausente NO
degrada la traza: rompe la compilación. Comprobado que no aporta NI UN
header que el rootfs/zig no traigan ya (0 ficheros exclusivos).
2) `strace-io-uring-7.1.patch`: Linux 7.1 añadió `min_left` a
`struct io_uring_buf_reg` y cambió `__u64 resv[3]` por `__u32 resv[5]`, así
que `CHECK_TYPE_SIZE(arg.resv, sizeof(uint64_t)*3)` saltaba como
`static assertion failed`. El cambio es el de UPSTREAM (strace master ya lo
trae), mismo criterio que `linux-headers-7.0.patch`, que también es un
cherry-pick.
⚠ El fallo se destapa POR CAPAS: make abortaba en btrfs.o, así que las 17
constantes de evdev ni se compilaban, y al arreglar btrfs "aparecían" las de
evdev como si el arreglo no hubiera servido. Y sólo tras resolver las 35 se
llegó a compilar io_uring.c y salió el static_assert. Una causa, tres caras.
⚠ `--enable-bundled=yes` NO sirve acá aunque el compilador lo sugiera: zig-cc
impone sus headers por delante de cualquier `-isystem`, así que los bundled de
strace no pueden ganar. Se probó: la opción se aplica (`checking whether to use
bundled linux kernel headers... yes`) y el assert sigue.
Verificado: sella, 0 undeclared, 0 asserts, y el binario TRAZA de verdad —
`strace -c /bin/true` cuenta 30 syscalls.
═══ LA CORRECCIÓN DE FONDO: no es `pack`, son las IMÁGENES ═══
El SDD 19 y el 20 decían «inyectar el texto de la licencia en `hammer pack`, que es aguas
abajo del ArtifactHash y sale gratis». La conclusión sobre el coste era correcta pero el
SITIO estaba mal, y por una razón que sólo se ve leyendo el código: `pack` produce un
`.swm`, que es una RECETA DE TRANSFORMACIÓN sobre fuente pública y por diseño explícito
«NUNCA transporta binarios cocidos»; e `install` REPRODUCE construyendo, con cache-hit del
corpus, en vez de bajar binarios. O sea que **el canal de paquetes de hammer no distribuye
binarios** y la obligación de acompañar-el-binario ahí casi no aplica.
Donde sí aplica, con toda su fuerza, es en la IMAGEN INSTALABLE: su rootfs se puebla con
`hammer install` sobre un prefix y de ahí sale un USB/ISO lleno de binarios que se le da a
alguien. Ése es el punto de entrega. (La obligación del espejo de FUENTES es otra y sigue
entera: las recetas apuntan a URLs de terceros que se caen.)
═══ LO QUE ENTRA ═══
· `scripts/licencias-textos.sh` + `licenses/`: los 44 textos CANÓNICOS de SPDX
(spdx/license-list-data), uno por identificador realmente en uso — la lista se saca de las
recetas, no de un fichero escrito a mano que se desincroniza. 764K.
· `scripts/licencias-rootfs.sh`: escribe /usr/share/licenses/<pkg>/ con el texto de CADA
licencia de la expresión (`Unlicense OR MIT` ⇒ los DOS textos: en un OR el destinatario
elige, y entregar uno solo le quita una opción que el autor le concedió), más un
MANIFEST.tsv. Medido: 1,0 MB para el perfil `cli` de 44 paquetes.
═══ Y SOBRE TODO: ES UN VETO ═══
Sale ≠0 si algún paquete del rootfs no declara licencia. Un informe que no puede bloquear no
cambia lo que ocurre; esto corta el paso. Y se ganó el sueldo al primer intento: reveló que
los perfiles `base` y `cli` —los dos más simples, los que primero se publicarían— llevaban
10 y 12 paquetes con binarios y licencia desconocida. Curados los 10 que se podían afirmar
(doas, iputils, less, mandoc, procps-ng, rsync, strace, sudo, tree, usbutils); ambos perfiles
bajan a 2.
Esos 2 NO se rellenan a propósito, y quedan vetando:
· lsof — licencia propia del proyecto, sin identificador SPDX. Toca `LicenseRef-lsof` con
su texto, que ya viaja en el tarball (la receta instala su COPYING).
· tzdata — dominio público por declaración de sus autores, y SPDX no tiene identificador
para eso (es una AUSENCIA de licencia, no una licencia). Toca
`LicenseRef-PublicDomain` documentado, no forzar uno de la lista.
De paso: normalizado `GPL-3.0+` (sufijo antiguo) a `GPL-3.0-or-later`, misma equivalencia
documentada que la barra de Cargo. Y el caso especial que puse para `Linux-syscall-note`
(«las excepciones viven en exceptions/») era una suposición razonable y FALSA: SPDX las
publica en el mismo `text/`; ese directorio no existe.
1063 de 1141 (93%). Hashes verificados: 0 movidos.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).
Recetas:dhcpcd strace
No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a tandas/needs-review-harkaq.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>