`recipes/protoc-gen-go.toml` estaba SELLADO y era INERTE: un plugin de protoc no hace nada sin `protoc`, y `protoc` no estaba en el catálogo. Cualquier servicio gRPC lo necesita en tiempo de build — empezando por `qdrant`, que el censo del servidor de origen encontró corriendo como binario suelto, de los que se pierden al apagar la máquina vieja. Entran dos recetas: `abseil-cpp` (que protobuf exige) y `protobuf`. Verificado corriéndolo, no por el código de salida: `protoc --version` contesta `libprotoc 36.1`, y un `.proto` de prueba se compila a `.pb.h`/`.pb.cc` reales. Único NEEDED `libc.so`, que provee `musl-shared`. Las dos REPRODUCEN bit a bit. **Dos muros, y el segundo escondía al primero.** 1. **`zig c++` se cae al enlazar los tres plugins `protoc-gen-upb*`**: `Error running link command: Segmentation fault` — un crash del linker, no un error de símbolos. Se aisló FUERA de takana y fuera del sandbox, rehaciendo el link a mano sobre los mismos `.o` y las mismas `.a`: `zig c++` vuelve a segfaultear. No es presión de memoria (corrió solo) y no es el `-Wl,-rpath,::::::::::::::` que CMake emite — se probó sin él y cae igual. `protobuf_BUILD_LIBUPB=OFF` tampoco es escapatoria: queda `OFF` en el `CMakeCache` y los plugins se construyen igual. Con `g++` y el `ld` de GNU los cuatro binarios enlazan. 2. Al pasar **sólo** protobuf a `gcc`, con abseil todavía construida por `zig-cc`, el link murió con `undefined reference to std::__1::basic_string<…>::assign(char const*, unsigned long)`. **El `__1` es el namespace inline de libc++** —la libstdc++ que trae zig— y g++ usa la de GNU, con otro mangling para los mismos tipos. O sea: **abseil y protobuf tienen que compartir runtime de C++ o no enlazan**, y el error habla de `std::string` sin nombrar a abseil ni una vez. Es la familia de las dos glib estáticas en un proceso, pero en C++ y en tiempo de link. ⇒ Las dos recetas llevan `compiler = "gcc"` y está escrito en ambas que cambiar una sin la otra vuelve a romper. `-static-libstdc++ -static-libgcc` para que `protoc` no salga pidiendo una soname que sólo vive en el lab. Y una decisión que NO es «la última versión»: abseil va pineada a `20250512.1` porque es exactamente la que protobuf 36.1 declara en `cmake/dependencies.cmake`. Abseil no promete ABI estable entre releases; el disparador para subirla es que protobuf suba la suya, no que abseil publique.
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.