# SDD 01 — Arquitectura general ## 1. El modelo de dos mundos ``` EL SÓTANO (laboratorio) EL PISO DE ARRIBA (userland) determinista · hermético mutable · clásico · FHS real ┌──────────────────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ │ │ │ │ [ Upstreams: git, commits FIJADOS ] │ │ /bin /sbin /lib /etc (FHS clásico) │ │ │ │ │ ▲ │ │ ▼ │ │ │ hardlinks normalizados │ │ ┌───────────────────────┐ │ │ │ │ │ │ hammer-build (lab) │ │ │ ┌───┴──────────────┐ │ │ │ bubblewrap + zig cc │ compila musl │ │ │ HIDRATACIÓN │ patchelf / copy │ │ │ recetas + grafo deps │ estático │ │ └───┬──────────────┘ │ │ └──────────┬────────────┘ │ │ │ │ │ ▼ │ │ │ │ │ ┌───────────────────────┐ │ │ ┌───┴───────────────┐ │ │ │ CAS store (BLAKE3) │ ────────────────────┼───┼─▶│ overlay try/commit │ red de seguridad │ │ │ /store/- │ │ │ └───┬───────────────┘ │ │ └───────────────────────┘ │ │ │ │ │ │ │ ┌───┴───────────────┐ │ └──────────────────────────────────────────────┘ │ │ diario fanotify │ delta vs base │ │ └───┬───────────────┘ │ ┌───────────────────────────────────────────────┐ │ │ │ BUS DE AGENTE /run/agent.sock (JSON-líneas) │◀┘ /run/init.control (FIFO humano) │ │ COMPILE · INJECT · QUERY · eventos │ │ └───────────────────────────┬────────────────────┘ │ │ └─────────────────────────────────────┘ ▼ [ IA programadora ] intención NL → .swm → overlay → test → aprobar ``` **Regla de oro:** los dos mundos nunca se mezclan. El lab jamás escribe directamente en el FHS real; siempre pasa por el store y luego por hidratación. El userland jamás compila contra el host; siempre delega al lab. ## 2. Componentes y su responsabilidad | Componente | Crate | Responsabilidad única | |---|---|---| | **Laboratorio** | `hammer-build` | Compilar una receta de forma hermética → artefacto en el store | | **Store CAS** | `hammer-core` | Guardar/recuperar artefactos por hash BLAKE3; garbage collection | | **Hidratación** | `hammer-build` | Proyectar artefactos del store al FHS real (hardlink + patchelf) | | **Overlay** | `hammer-cli` | Montar/fusionar/descartar capa de experimentación en caliente | | **Diario** | `hammerd` | Vigilar mutaciones (fanotify), log append-only, exportar `.swm` | | **Bus de agente** | `hammerd` | Socket de control para IA/scripts; eventos del sistema | | **CLI** | `hammer-cli` | El binario `hammer` que orquesta todo lo anterior | | **Tipos compartidos** | `hammer-core` | `Recipe`, `Swm`, `Hash`, `Store`, formatos serializables | ## 3. Flujo de datos canónico (de la intención al sistema vivo) 1. **Intención** — el humano (o la IA) expresa un cambio: *"que grep ignore binarios por defecto y use regex Perl"*. 2. **Receta** — se traduce a una `Recipe`: repo + commit fijado + patch + flags + compilador. 3. **Build** — `hammer-build` levanta el sandbox, compila con `zig cc`, produce un binario musl estático, lo deposita en el store bajo `BLAKE3(...)`. 4. **Overlay** — el artefacto se hidrata, pero **en una capa overlay temporal**, no en el sistema real. El humano/IA prueba en caliente. 5. **Validación** — corre el test harness; los eventos van por el bus (`BUILD_READY`, `CRASHED`). Si falla, se descarta el overlay; el sistema base intacto. 6. **Promoción** — si pasa, se fusiona al FHS real. El diario registra la mutación. 7. **Compartir** — `hammer export` empaqueta el delta como `.swm`: base-hash + patch + config. Otro usuario lo `apply`-ea: su IA reproduce y verifica localmente; nunca ejecuta tu binario. ## 4. Estado en disco (layout) ``` /store/ el content-addressed store (inmutable, append-only) -/ un artefacto: árbol de archivos resultante de un build /var/lib/hammer/ recipes/ recetas conocidas (caché de definiciones) pins.toml lockfile: nombre → commit fijado del upstream journal/ diario de mutaciones append-only overlays/ upperdirs de overlays activos /run/ init.control FIFO de control humano (texto crudo) agent.sock socket de control de agente (JSON-líneas, SO_PEERCRED) hammerd.pid ``` > Nota: en la fase Alpine, `/store` y `/var/lib/hammer` viven dentro del rootfs de Alpine. > En la distro propia se decidirá su partición/montaje. Ver [SDD 10](10-roadmap.md). ## 5. Límites del sistema (qué corre dónde) - **`hammer-build`** corre privilegiado lo justo para crear namespaces (vía `bubblewrap`, que usa user-namespaces sin root real cuando es posible). - **`hammerd`** corre como servicio bajo el init; expone el bus y vigila el diario. - **`hammer` (CLI)** corre como el usuario; es el punto de entrada de todo flujo manual. - **La IA** es un cliente del bus como cualquier otro proceso — sin privilegios especiales más allá de los que el humano le conceda explícitamente (ver [SDD 08](08-ai-integration.md)). ## 6. Decisiones transversales - Reproducibilidad ⇒ commits fijados, no HEAD ([ADR 0006](adr/0006-pinned-commits.md)). - No reescribir el motor de build ([ADR 0004](adr/0004-no-custom-nix.md)). - Validar el concepto sobre Alpine primero ([ADR 0002](adr/0002-alpine-first.md)).