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 /
Tercer Lua del catálogo y hay razón para cada uno: `lua` 5.4 para wireplumber,
`lua5.2` para el OSC de mpv, y ésta porque hay consumidores que piden LuaJIT POR
NOMBRE — swayimg >=5.0 hace dependency('luajit') sin alternativa. No es la misma ABI:
LuaJIT es Lua 5.1 + FFI + JIT. Convive sin pisar: todas sus rutas ya vienen
versionadas (include/luajit-2.1, libluajit-5.1.so.2, /usr/bin/luajit-2.1.<relver>).
⚠ EL PIN DE COMMIT NO ALCANZA. Desde que 2.1 es rolling no hay tags: la versión sale
de `git show -s --format=%ct` sobre el árbol, y NO es cosmética — entra en un SÍMBOLO
EXPORTADO (luaJIT_version_2_1_ROLLING). Dos builds del mismo commit con distinto
estado de .git publican símbolos distintos y el consumidor muere con símbolo
indefinido. Se escribe .relver a mano Y se borra .git, porque la rama que consulta git
gana si el directorio existe. Verificado: nm -D da luaJIT_version_2_1_1787165859.
LIBS=-lunwind: la misma deuda que ya paga librsvg. Sin esto, nueve _Unwind_*
indefinidos desde lj_err.o — LuaJIT usa unwinding DWARF de verdad y en glibc ese
runtime vive en libgcc_s, que musl no tiene. Va por LIBS= y no LDFLAGS= porque
TARGET_ALIBS se expande DESPUÉS de los objetos, que es donde el linker resuelve.
TARGET_STRIP=true: su Makefile strippea como parte de la compilación, lo que pediría
binutils y borraría el .debug_* antes de que hammer lo parta (SDD 23).
Evidencia de que anda: NEEDED = libc.so y nada más; jit.status() da true con todas las
optimizaciones; FFI llama a C; y los cuatro caminos de unwinding responden — pcall,
error DENTRO de un trace compilado (err_unwind_jit, el que pedía _Unwind_GetIP),
metamétodo y xpcall+traceback.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo