SergioandClaude Opus 5 1d9ddcee37 qorpa D10: Steam en la mano, y los tres muros que sólo se ven así
Paso 6 del ADR 0015, PARCIAL y dicho como parcial. Steam 1.0.0.87 instalado de
verdad desde el multilib de Arch —las libs de 32 bits que la F2 del plan de
juegos daba por «una campaña entera»—, su cliente i386 bajado y desempacado por
el bootstrap de Valve junto con el Steam Runtime, y el BWRAP ANIDADO VERIFICADO
EXPLÍCITAMENTE (24 montajes propios dentro de la instancia), que es lo que este
paso pedía. Lo que NO se pudo: la máquina no tiene sesión gráfica, y el runtime
sniper sólo se baja al instalar un juego, que exige credenciales ⇒
pressure-vessel con un juego real sigue sin ejercitarse. Se dice, no se insinúa.

Tres muros, ninguno en el ADR:

1. LA JAULA MATABA TODOS LOS BINARIOS DE 32 BITS. El filtro seccomp comprueba
   arch == x86_64 y MATA lo que no lo sea; para un build es la defensa clásica y
   correcta, para el montón B es fatal porque el cliente de Steam es un ELF i386.
   El síntoma fue `ldd: exited with unknown exit code (159)` = 128+31 = SIGSYS,
   que no se parece en nada a la causa. La salida no es aflojar el check sino
   darle a i386 su propia tabla con la MISMA política. Los 25 números se
   verificaron uno por uno contra /usr/include/asm/unistd_32.h: 24 bien y UNO
   MAL — kexec_file_load no existe en i386 y su número de x86_64 (320) es ahí
   `utimensat`, o sea que habríamos denegado algo que usa cualquier cosa que
   toque una marca de tiempo. Es la diferencia entre una tabla de memoria y una
   verificada.

2. STEAM SE NIEGA A CORRER COMO ROOT, y cambiar el mapa para evitarlo CORROMPE
   la instancia: un fichero creado bajo un mapa aparece con otro uid bajo el
   otro, así que el useradd de la preparación deja un /home que su propio dueño
   no puede escribir. ⇒ el mapa es parte de la IDENTIDAD de la instancia. La vía
   correcta es la de cualquier runtime de contenedores: un solo mapa y se BAJA de
   privilegio adentro — campo `run_as`, setpriv, con el CAP_SETUID que ya
   tenemos en el namespace.

3. EL XDG_RUNTIME_DIR ES DEL USUARIO QUE CORRE, no del uid del mapa: con
   `run_as`, apuntarlo al de root deja al Steam Runtime sin poder crear su
   temporal. Se lee como un aviso menor hasta que algo deja de andar sin decir
   por qué.

Lo que sí quedó probado, y es el corazón del ADR: un userland glibc ajeno con su
cadena de 32 bits completa corre enjaulado sobre nuestro kernel, con seccomp y
no_new_privs puestos, y un contenedor anidado funciona adentro — la forma exacta
en que Valve prueba Proton.

1 test nuevo (run_as resuelve uid/gid/home del passwd de la imagen, y un run_as
inexistente NO cae a root). 48/48.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U5cQtQrYNjWJVXVE6aEpQ2
2026-09-03 12:01:32 +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%