SergioandClaude Opus 5 29897ab2ba gtk4: el --export-dynamic venia del .pc de gmodule, y estatico destapo un bug de upstream
Los 8 ejecutables decian static y enlazaban musl dinamicamente. La huella que lo
delata sin mirar el build: `readelf --dyn-syms` daba 21475 entradas contra ~2700
de un binario dinamico normal — eso es --export-dynamic, no un enlace corriente.

NO venia del meson de gtk (ahi no aparece la palabra) sino de un .pc DE
DEPENDENCIA: `gmodule-2.0.pc` trae literalmente `Libs: -Wl,--export-dynamic`, y
`meson.build:426` pedia `dependency('gmodule-2.0')`. El wrapper de cc del lab
(`sandbox.rs:597`) tira el `-static` ante --export-dynamic ⇒ lo ponia el lab y
lo sacaba el lab, por un flag heredado de una dep.

No hace falta parchear el .pc de glib: upstream ya publica la misma libreria sin
el flag. `gmodule-no-export-2.0.pc` trae el `-lgmodule-2.0 -pthread` de verdad y
los otros dos solo hacen Requires sobre el añadiendo --export-dynamic. Es la
palanca prevista, no un apaño — de hecho `gio-2.0.pc` de la propia glib ya usa
la variante no-export.

REGLA GENERAL: cualquier receta que enlace gmodule hereda --export-dynamic y
pierde el -static SIN AVISO. Si link=static no pega y hay glib de por medio,
mirar los .pc de las deps antes que el build del proyecto.

Y entonces aparecio un bug que SOLO existe en estatico: los 8 morian con SIGSEGV
hasta en `--help`. Backtrace con gdb:
    g_module_symbol (module=0x0, symbol_name="gtk_progress_get_type")
    _gtk_module_has_mixed_deps (module_to_check=0x0) at gtk/gtkmain.c:474
    do_pre_parse_initialization () at gtk/gtkmain.c:498
    gtk_init_check () at gtk/gtkmain.c:635
`_gtk_module_has_mixed_deps(NULL)` hace `g_module_open(NULL,0)` y pasa el
resultado a `g_module_symbol` sin comprobarlo. En musl ESTATICO `dlopen(NULL)`
devuelve NULL siempre ⇒ deref de nulo en el offset 8, en el arranque. Con libc
dinamica el bug no se ve nunca. Cuarto parche de la receta: la comprobacion que
falta. Devolver FALSE es correcto ademas de seguro — en un estatico no hay
modulos cargables, asi que no puede haber simbolos de GTK 2/3 mezclados.

Control: 423 ficheros intactos, NEEDED=0 en los ocho, .dynsym de 21475 a 0, los
ocho arrancan, gtk4-path-tool hace trabajo real, y `builder-tool validate`
devuelve EXACTAMENTE el mismo «Could not initialize windowing system» que daba
el binario dinamico anterior.

Cae en cascada el re-hash de 7 dependientes; se reconstruyen a continuacion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
2026-08-31 16:11:50 +00:00

hammer

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 comparta el sistema.

hammer no es otro gestor de paquetes inmutable. Es una arquitectura de dos mundos:

  • El laboratorio compila desde fuentes upstream (commits fijados), de forma determinista y aislada (bubblewrap + zig cc + musl estático), y direcciona cada artefacto por su hash (BLAKE3) en un content-addressed store.
  • El userland es un Linux clásico, mutable, con FHS de verdad (/bin, /lib, /etc). Los binarios se hidratan desde el store por hardlinks. Puedes pisar archivos en caliente, romper cosas con un rm -rf, y revertir cuando quieras.

Entre ambos mundos viven las tres piezas que hacen a hammer distinto:

  1. Overlay de experimentación — prueba cambios sobre el sistema real con red de seguridad; hammer try / commit / discard.
  2. Diario de mutaciones — un daemon fanotify registra todo lo que tú (o la IA) cambiáis a mano. Vives imperativamente; el sistema genera el delta contra la base limpia. El diario es tu configuración — sin ser declarativa.
  3. Manifiesto .swm — compartes la receta de la mutación (parche de fuente + flags + ediciones de config), no el binario cocinado. El receptor reproduce y verifica; no confía en tu binario.

Encima de todo corre el bus de agente (/run/agent.sock): la IA habla un protocolo pequeño y legible, dispara compilaciones, inyecta en el overlay, escucha fallos y reacciona. Tú tienes la última palabra.

Estado

Fase de arranque. Validamos la capa AI-nativa sobre Alpine (musl + FHS ya cocidos) antes de bajar a distro propia. Ver docs/10-roadmap.md.

Documentación de diseño (SDD)

Toda la arquitectura está en docs/. Empieza por docs/00-vision.md y docs/01-architecture.md.

Estructura

crates/
  hammer-core   tipos compartidos: Recipe, Swm, hashing CAS, store
  hammer-build  el laboratorio: sandbox + compilación + hidratación
  hammer-cli    el binario `hammer` (build, hydrate, try, commit, apply, export…)
  hammerd       daemon: bus de agente + diario de mutaciones
docs/           SDDs y ADRs

Stack

Capa Decisión
Base de validación Alpine (musl + FHS mutable)
Tooling / daemons Rust (estático-musl)
Compilador del lab zig cc por defecto, pluggable por receta
Sandbox de build bubblewrap (namespaces)
Direccionamiento BLAKE3 content-addressed store
Despliegue Hidratación por hardlinks + patchelf

Filosofía

La automatización es mi empleada en el sótano, pero en el piso de arriba mando yo.

Eficiencia matemática en la manufactura, libertad biológica en la ejecución.

S
Description
No description provided
Readme MIT
128 MiB
Languages
Rust 39.4%
Shell 25.8%
Python 20.6%
HTML 10.4%
C 2.1%
Other 1.6%