tawasuyu

sergio/takana

> 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 co…

TOML 1572Shell 203Rust 109Markdown 993728 Definitions

⎇ bbab5a204d57d43d9e01f6fb4252dddd04c4d5a1 docs/06-swm-format.md Markdown · 130 lines · 5.5 KB History raw

Fase 4 — formato .swm: verify, apply (config_edit/file_drop/source_patch) y export 09d50f9e6 · Sergio ·

1# SDD 06 — Formato `.swm` (Software Mutación)
2
3El `.swm` es la unidad de intercambio de `hammer`. **No es un paquete binario** (`.deb`,
4`.rpm`, ni un `PKGBUILD` que compila quién-sabe-qué). Es un **manifiesto de la mutación**: la
5receta de transformación sobre código fuente público, más las ediciones de configuración. El
6receptor reproduce y verifica localmente; **nunca ejecuta tu binario** (ver
7[SDD 09](09-trust-model.md)).
8
9## 1. Esquema
10
11```yaml
12# my-grep-tweak.swm
13swm_version: 1
14
15base:
16  distro_version: "2026-06-06"      # versión del set base de hammer
17  pins:                              # commits fijados de los upstreams relevantes
18    kernel: "a1b2c3d…"
19    musl:   "e4f5a6b…"
20  # base_hash deriva de pins+distro_version; el receptor verifica compatibilidad
21
22mutations:
23  - type: source_patch              # recompilar una herramienta desde su fuente parcheada
24    repo: "git://git.savannah.gnu.org/grep.git"
25    commit: "a1b2c3d…"              # commit fijado sobre el que aplica el patch
26    patch: |                         # parche .patch de git, embebido o por URL (patch_url)
27      --- a/src/main.c
28      +++ b/src/main.c
29      @@ ...
30    build:
31      compiler: "zig-cc"
32      target: "x86_64-linux-musl"
33      link: "static"
34      flags: ["--enable-perl-regexp"]
35    target_bin: "/bin/grep"
36
37  - type: config_edit               # editar un archivo de config en texto plano
38    file: "/etc/network.conf"
39    inline_diff: |
40      - DHCP=yes
41      + IP=192.168.1.100
42
43  - type: init_rule                 # añadir/ajustar una regla del init (ver SDD 07)
44    action: "watchdog"
45    service: "web"
46    command: "/bin/myweb -p 8080"
47
48signature:                           # opcional pero recomendado (ver SDD 09)
49  by: "sergio"
50  alg: "ed25519"
51  sig: "base64…"
52```
53
54## 2. Tipos de mutación
55
56| `type` | Qué describe | Cómo lo aplica el receptor |
57|---|---|---|
58| `source_patch` | recompilar una herramienta desde fuente parcheada | clona repo@commit → aplica patch → `hammer build` → hidrata en overlay |
59| `config_edit` | edición de un archivo de config | aplica el `inline_diff` (3-way) sobre el archivo objetivo |
60| `init_rule` | regla del bus de init | inyecta la regla vía `/run/init.control` / receta de servicio |
61| `file_drop` | depositar un archivo de datos no compilable | escribe el archivo (con su hash declarado) en la ruta |
62
63`file_drop` admite dos modos para el contenido, mutuamente excluyentes:
64
65- `content_b64` (RFC 4648, sin saltos): inline en el `.swm`. Útil para `.swm`s
66  autocontenidos (tests, snapshots offline, datos pequeños).
67- `content_url`: el receptor lo descarga. En ambos casos se verifica `content_hash`
68  (BLAKE3) antes de escribir nada.
69
70Cada `source_patch` es, en esencia, una `Recipe` ([SDD 02](02-build-lab.md)) serializada para
71viajar. El `build` lleva el **compilador por mutación** (no global).
72
73## 3. Aplicación (`hammer apply`)
74
75```
76hammer apply my-grep-tweak.swm
77```
78
791. **Verifica la base.** ¿Los `pins`/`distro_version` son compatibles con el sistema local?
80   Si no, avisa qué difiere y se detiene (o `--force` bajo tu responsabilidad).
812. **Verifica la firma** (si existe) contra las claves de confianza locales.
823. **Reproduce.** Para cada `source_patch`: clona el repo al commit, aplica el patch, compila
83   en el lab local → obtiene un `artifact_hash`.
844. **Aísla.** Hidrata todo en un **overlay temporal** ([SDD 04](04-overlay.md)); aplica
85   `config_edit`/`init_rule`/`file_drop` en esa capa. **No toca el sistema base.**
865. **Valida.** Corres/pruebas en caliente. Si bien → `hammer commit`. Si mal → `hammer discard`.
87
88Nunca se ejecuta un binario ajeno: sólo se transforma código fuente público con una receta que
89tu propio laboratorio compila.
90
91## 4. Determinismo y verificación cruzada
92
93Como el lab es determinista ([SDD 02](02-build-lab.md)), el `artifact_hash` que produce tu
94máquina debe coincidir con el del autor (si declara `expected_hash`). Coincidencia ⇒ obtuviste
95exactamente el mismo binario, sin haberlo descargado. Discrepancia ⇒ algo difiere (toolchain,
96pin, patch) y `hammer` te dice qué. Esto es "verificar, no confiar" en la práctica.
97
98## 5. No-objetivos del formato
99
100- **No** transporta binarios cocidos (salvo `file_drop` para datos no compilables, con hash).
101- **No** es Turing-completo: es declarativo *para el intercambio*, aunque el sistema que
102  describe se viva imperativamente. (Lo declarativo aquí es honesto: describe una
103  transformación, no aprisiona tu sistema.)
104- **No** asume una arquitectura: `target` viaja en cada `source_patch`.
105
106## 6. Interfaz
107
108```rust
109// hammer-core
110#[derive(Serialize, Deserialize)]
111pub struct Swm { /* swm_version, base, mutations, signature */ }
112impl Swm {
113    pub fn from_yaml(s: &str) -> Result<Swm>;
114    pub fn to_yaml(&self) -> Result<String>;
115    pub fn verify_base(&self, local: &BaseRef) -> BaseCompat;
116    pub fn verify_signature(&self, trust: &TrustStore) -> SigStatus;
117}
118```
119
120CLI:
121
122- `hammer apply <file.swm>` — abre un overlay por defecto y aplica las mutaciones. Con
123  `--prefix DIR` opera directamente bajo `DIR` sin overlay (tests, staging). Con
124  `--base-ref base.json` aborta si la base local no es compatible.
125- `hammer swm-verify <file.swm>` — chequea schema, hashes de los `file_drop` inline y,
126  con `--base-ref`, la compatibilidad de base.
127- `hammer export --journal DIR > out.swm` — lee el diario y emite un `.swm` con un
128  `file_drop` por archivo modificado (estado final actual; los `Delete` se omiten). El
129  receptor reproduce byte-a-byte; la provenance vía `source_patch` queda para más adelante
130  (necesita un mapa artefacto→receta).

06-swm-format.md

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).

1. Esquema

# 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

typeQué describeCómo lo aplica el receptor
source_patchrecompilar una herramienta desde fuente parcheadaclona repo@commit → aplica patch → hammer build → hidrata en overlay
config_editedición de un archivo de configaplica el inline_diff (3-way) sobre el archivo objetivo
init_ruleregla del bus de initinyecta la regla vía /run/init.control / receta de servicio
file_dropdepositar un archivo de datos no compilableescribe el archivo (con su hash declarado) en la ruta

file_drop admite dos modos para el contenido, mutuamente excluyentes:

Cada source_patch es, en esencia, una Recipe (SDD 02) 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); 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), 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

6. Interfaz

// 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: