Files
Sergio 97ceb72411 takana etapa 5b: los 59 docs de diseño, runbooks y ADR
645 líneas. Los ADR entran porque en este repo SON documentos vivos, no
registros inmutables: el 0013 tiene 5 commits, el 0009 dos. Eso se comprobó
antes de decidir, no se asumió por convención general.

EXCLUIDOS por ser REGISTRO o generado: docs/evidencia/ (6), el HANDOFF de la
noche de KDE (1) y docs/state/ (24, se regenera solo). Reescribir un comando
dentro de una evidencia la falsifica.

Y el ADR 0016 se excluye de todo barrido, con un aviso adentro para el próximo
que barra: habla SOBRE el renombre, así que necesita seguir diciendo 'hammer'.
El barrido se lo llevó puesto y lo dejó titulado 'Renombre del sistema: takana
→ takana'; revertido.

Congelados, verificados uno por uno con controles: /opt/hammer, /var/lib/hammer,
/usr/bin/hammer, /mnt/vvv/hammer, la URL de gitea, hammer-farm.service,
hammer-live-install.sh, BRIEFING-hammer.md, hammerd, hammer-recover y
HAMMER_LIVE.
2026-09-09 19:25:51 +00:00

86 lines
4.2 KiB
Markdown

# 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/<id>/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 `<id>`), 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<OverlayId>;
pub fn overlay_commit(id: OverlayId, journal: &Journal) -> Result<CommitReport>;
pub fn overlay_discard(id: OverlayId) -> Result<()>;
pub fn overlay_status() -> Result<Vec<OverlayState>>;
```
CLI: `takana try` · `takana commit` · `takana discard` · `takana status`.