libglvnd b3:e27d3b2833a6aa6a6b4a4caad5ef2121e7be31a3c7ae59d0db22b01d696ffc99 obs-studio b3:29d95ddf50ef79692b48cae493758def564202ef81eba236b6cb279757621403 ── libglvnd: se apagan egl, gles1, gles2 y headers ───────────────────────────────────────────── La receta se escribió para la campaña completa —glvnd toma libEGL y mesa pasa a ser vendor detrás— y la campaña NO SE HIZO: las tres mesa siguen con -Dglvnd=false. El resultado, medido en /mnt/cosecha/escritorios/kde-rootfs ya hidratado, era el cuadro que la propia receta anunciaba: /usr/lib/libEGL.so.1 -> libEGL.so.1.0.0 1.440.624 B (mesa: el driver) /usr/lib/libEGL.so.1.1.0 323.144 B (glvnd: despacho, HUÉRFANO) Dos libEGL.so.1 distintos en la MISMA ruta, más libGLESv2.so.2 y los headers GL/, EGL/ y GLES2/ duplicados y con BYTES DISTINTOS (gl.h: 79.877 vs 80.393). Quién gana depende del orden de hidratación y nada lo guarda. Y no hacía falta: OBS, que es la razón de que la receta exista, NO usa glvnd en runtime. libobs-opengl.so sale con NEEDED libEGL.so.1 y nada más, y sus indefinidos son todos egl* —ni un gl[A-Z] sin resolver— o sea que su glad resuelve por eglGetProcAddress contra la EGL de mesa. Lo único que glvnd le da es satisfacer el OpenGL::GL de CMake AL ENLAZAR. Ahora sella libGLdispatch.so.0 + libOpenGL.so.0 + opengl.pc y nada más: CERO ficheros en común con mesa. Radio medido: 1 dependiente. ⚠ Esto quita el DAÑO, no cierra el muro: libOpenGL.so.0 enlaza y en runtime sigue sin haber vendor (no hay libEGL_mesa.so.0 ni egl_vendor.d). Cerrarlo es re-sellar las TRES mesa con -Dglvnd=true en un movimiento, y el precio está medido: `yupana radio mesa` = 148 directos, 154 transitivos, 153 sellados que caen a deuda, las CINCO imágenes. Decisión de distro, no arreglo de paso. ── obs-studio: el cache-hit tapaba una regresión ─────────────────────────────────────────────── Al forzar su rebuild, el configure murió pidiendo `qrcodegencpp`, que no es receta de ninguna cola. La causa NO era libglvnd. La receta dice «[source] de takana NO clona submódulos ⇒ sus directorios llegan VACÍOS» y por eso hacía `touch plugins/obs-websocket/CMakeLists.txt`. Esa premisa dejó de ser cierta: los submódulos YA se materializan, así que `touch` no vacía nada —sólo toca la mtime de un fichero que existe— y el CMakeLists de verdad entra pidiendo su dependencia. Corregido a `mkdir -p` + `: >` (truncar), que funciona con submódulos y sin ellos: la receta deja de depender de una premisa que puede cambiarle bajo los pies. Construye y sella en el hub.
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 unrm -rf, y revertir cuando quieras.
Entre ambos mundos viven las tres piezas que hacen a hammer distinto:
- Overlay de experimentación — prueba cambios sobre el sistema real con red de
seguridad;
hammer try/commit/discard. - Diario de mutaciones — un daemon
fanotifyregistra 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. - 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.