# SDD 04 — Overlay de experimentación El overlay es la red de seguridad que convierte la mutabilidad total en algo que también es seguro: la capacidad de **cometer errores sin perder el control imperativo**. Es donde la IA prueba sus cambios antes de tocar el sistema real, y donde tú experimentas a mano sin miedo. ## 1. El mecanismo Usa `overlayfs` nativo del kernel, gestionado dinámicamente desde la terminal: ``` montaje overlay sobre /bin (y /etc, /lib…) upperdir → /var/lib/hammer/overlays//upper (tmpfs o dir oculto, MUTABLE) lowerdir → el /bin real (read-only de facto bajo el overlay) merged → /bin (lo que ve el sistema) ``` Mientras el overlay está montado, el sistema y tú veis `/bin` como **el sistema real modificado en caliente**. Pero toda escritura cae en el `upperdir`; el `/bin` real (lowerdir) nunca se toca. ## 2. El ciclo de vida ``` takana try # monta un overlay sobre los directorios del sistema ... experimentas / la IA inyecta binarios y edita configs ... ... pruebas en caliente: ejecutas, rompes, observas ... takana commit # fusiona upperdir → FHS real (rsync inteligente) y registra en el diario — o — takana discard # desmonta y borra el upperdir: el sistema vuelve al estado base, instantáneo ``` - **`try`** → estado base limpio + capa mutable encima. Riesgo cero. - **`discard`** → desmonta el overlay; el sistema vuelve a su base **instantáneamente**. No hay que deshacer cambios uno por uno. - **`commit`** → fusiona la capa al FHS real y anota cada archivo tocado en el diario ([SDD 05](05-journal.md)). A partir de aquí el cambio es permanente y rastreable. ## 3. Por qué overlay y no contenedor Un contenedor (docker/chroot) te aísla de tus dispositivos y procesos reales — pierdes el acceso al sistema vivo. El overlay hace lo contrario: **modificas la "realidad" del sistema operativo** (mismos PIDs, mismos `/dev`, misma red) pero con una red de seguridad. Es la diferencia entre "probar en una maqueta" y "probar en la casa real con un seguro de vida". ## 4. Composición con el resto del sistema - **La IA** (ver [SDD 08](08-ai-integration.md)) opera **siempre** dentro de un overlay: clona el repo, compila en el lab, hidrata en el `upperdir`, edita configs en el `upper`. Tú validas en caliente. La IA nunca escribe en el FHS real hasta que tú haces `commit`. - **Múltiples overlays** pueden coexistir (distintos ``), p. ej. un experimento por hipótesis. Cada uno es independiente. - **El diario** sólo registra en `commit` — el ruido del experimento no contamina la historia. ## 5. Estados y reglas | Estado | Significado | Transiciones | |---|---|---| | `none` | sin overlay activo | `try` → `active` | | `active` | overlay montado, capa mutable encima | `commit` → `none` (+diario), `discard` → `none` | Reglas: - `commit`/`discard` sin overlay activo: no-op con aviso. - Un `try` anidado sobre un target ya cubierto crea un overlay nuevo **apilado**: el kernel toma el merged view de la capa de abajo como `lowerdir` de la nueva. El orden de apilamiento es total y determinista (`created_at`, desempatado por `id`, que ahora lleva un `seq` por proceso para que ráfagas en el mismo segundo no colisionen). `commit`/`discard` **exigen LIFO**: si una capa más joven aún sombrea alguno de tus targets, la operación falla con `Error::Shadowed` listándolas — resuelve primero las de arriba. (La unicidad de orden entre procesos concurrentes apilando sobre el mismo target en el mismo segundo no la garantiza el `seq`; queda para el track posterior junto al init propio.) - Si el sistema se apaga con overlays activos, al arranque `hammerd` los reporta y deja que el humano decida (no auto-commit, no auto-discard — eso sería declarativo). ## 6. Interfaz ```rust // takana-cli (con helpers de takana-core) pub fn overlay_try(targets: &[PathBuf]) -> Result; pub fn overlay_commit(id: OverlayId, journal: &Journal) -> Result; pub fn overlay_discard(id: OverlayId) -> Result<()>; pub fn overlay_status() -> Result>; ``` CLI: `takana try` · `takana commit` · `takana discard` · `takana status`.