Arranque del proyecto hammer (distro AI-nativa: laboratorio funcional en el sótano, terminal mutable clásica arriba, integración de IA programadora). - Workspace Rust (compila, tests verdes): hammer-core, hammer-build, hammer-cli (bin `hammer`), hammerd. - SDDs 00-10 + 6 ADRs en docs/ con toda la arquitectura. - Esqueletos navegables mapeados a las fases del roadmap; Fase 0/1 listas para implementar el sandbox real. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
114 lines
4.6 KiB
Markdown
114 lines
4.6 KiB
Markdown
# SDD 06 — Formato `.swm` (Software Mutación)
|
|
|
|
El `.swm` es la unidad de intercambio de `hammer`. **No es un paquete binario** (`.deb`,
|
|
`.rpm`, ni un `PKGBUILD` que compila quién-sabe-qué). Es un **manifiesto de la mutación**: la
|
|
receta de transformación sobre código fuente público, más las ediciones de configuración. El
|
|
receptor reproduce y verifica localmente; **nunca ejecuta tu binario** (ver
|
|
[SDD 09](09-trust-model.md)).
|
|
|
|
## 1. Esquema
|
|
|
|
```yaml
|
|
# my-grep-tweak.swm
|
|
swm_version: 1
|
|
|
|
base:
|
|
distro_version: "2026-06-06" # versión del set base de hammer
|
|
pins: # commits fijados de los upstreams relevantes
|
|
kernel: "a1b2c3d…"
|
|
musl: "e4f5a6b…"
|
|
# base_hash deriva de pins+distro_version; el receptor verifica compatibilidad
|
|
|
|
mutations:
|
|
- type: source_patch # recompilar una herramienta desde su fuente parcheada
|
|
repo: "git://git.savannah.gnu.org/grep.git"
|
|
commit: "a1b2c3d…" # commit fijado sobre el que aplica el patch
|
|
patch: | # parche .patch de git, embebido o por URL (patch_url)
|
|
--- a/src/main.c
|
|
+++ b/src/main.c
|
|
@@ ...
|
|
build:
|
|
compiler: "zig-cc"
|
|
target: "x86_64-linux-musl"
|
|
link: "static"
|
|
flags: ["--enable-perl-regexp"]
|
|
target_bin: "/bin/grep"
|
|
|
|
- type: config_edit # editar un archivo de config en texto plano
|
|
file: "/etc/network.conf"
|
|
inline_diff: |
|
|
- DHCP=yes
|
|
+ IP=192.168.1.100
|
|
|
|
- type: init_rule # añadir/ajustar una regla del init (ver SDD 07)
|
|
action: "watchdog"
|
|
service: "web"
|
|
command: "/bin/myweb -p 8080"
|
|
|
|
signature: # opcional pero recomendado (ver SDD 09)
|
|
by: "sergio"
|
|
alg: "ed25519"
|
|
sig: "base64…"
|
|
```
|
|
|
|
## 2. Tipos de mutación
|
|
|
|
| `type` | Qué describe | Cómo lo aplica el receptor |
|
|
|---|---|---|
|
|
| `source_patch` | recompilar una herramienta desde fuente parcheada | clona repo@commit → aplica patch → `hammer build` → hidrata en overlay |
|
|
| `config_edit` | edición de un archivo de config | aplica el `inline_diff` (3-way) sobre el archivo objetivo |
|
|
| `init_rule` | regla del bus de init | inyecta la regla vía `/run/init.control` / receta de servicio |
|
|
| `file_drop` | depositar un archivo de datos no compilable | escribe el archivo (con su hash declarado) en la ruta |
|
|
|
|
Cada `source_patch` es, en esencia, una `Recipe` ([SDD 02](02-build-lab.md)) serializada para
|
|
viajar. El `build` lleva el **compilador por mutación** (no global).
|
|
|
|
## 3. Aplicación (`hammer apply`)
|
|
|
|
```
|
|
hammer apply my-grep-tweak.swm
|
|
```
|
|
|
|
1. **Verifica la base.** ¿Los `pins`/`distro_version` son compatibles con el sistema local?
|
|
Si no, avisa qué difiere y se detiene (o `--force` bajo tu responsabilidad).
|
|
2. **Verifica la firma** (si existe) contra las claves de confianza locales.
|
|
3. **Reproduce.** Para cada `source_patch`: clona el repo al commit, aplica el patch, compila
|
|
en el lab local → obtiene un `artifact_hash`.
|
|
4. **Aísla.** Hidrata todo en un **overlay temporal** ([SDD 04](04-overlay.md)); aplica
|
|
`config_edit`/`init_rule`/`file_drop` en esa capa. **No toca el sistema base.**
|
|
5. **Valida.** Corres/pruebas en caliente. Si bien → `hammer commit`. Si mal → `hammer discard`.
|
|
|
|
Nunca se ejecuta un binario ajeno: sólo se transforma código fuente público con una receta que
|
|
tu propio laboratorio compila.
|
|
|
|
## 4. Determinismo y verificación cruzada
|
|
|
|
Como el lab es determinista ([SDD 02](02-build-lab.md)), el `artifact_hash` que produce tu
|
|
máquina debe coincidir con el del autor (si declara `expected_hash`). Coincidencia ⇒ obtuviste
|
|
exactamente el mismo binario, sin haberlo descargado. Discrepancia ⇒ algo difiere (toolchain,
|
|
pin, patch) y `hammer` te dice qué. Esto es "verificar, no confiar" en la práctica.
|
|
|
|
## 5. No-objetivos del formato
|
|
|
|
- **No** transporta binarios cocidos (salvo `file_drop` para datos no compilables, con hash).
|
|
- **No** es Turing-completo: es declarativo *para el intercambio*, aunque el sistema que
|
|
describe se viva imperativamente. (Lo declarativo aquí es honesto: describe una
|
|
transformación, no aprisiona tu sistema.)
|
|
- **No** asume una arquitectura: `target` viaja en cada `source_patch`.
|
|
|
|
## 6. Interfaz
|
|
|
|
```rust
|
|
// hammer-core
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct Swm { /* swm_version, base, mutations, signature */ }
|
|
impl Swm {
|
|
pub fn from_yaml(s: &str) -> Result<Swm>;
|
|
pub fn to_yaml(&self) -> Result<String>;
|
|
pub fn verify_base(&self, local: &BaseRef) -> BaseCompat;
|
|
pub fn verify_signature(&self, trust: &TrustStore) -> SigStatus;
|
|
}
|
|
```
|
|
|
|
CLI: `hammer apply <file.swm>` · `hammer export … > out.swm` · `hammer swm verify <file.swm>`.
|