Pedido del usuario: «el catálogo de todo lo que falta hasta decir la distro está publicable, y lo de más hasta la distro está completa. Y un tipo manual, todos los pasos que tengo que ir haciendo en las tres etapas que marcan esos dos codos.» SDD 20 = el inventario, medido contra el repo (grafo, no recuento a mano). SDD 21 = el manual de a pie, un comando por vez, marcando qué puede hacer el agente y qué es del usuario. LO QUE APARECIÓ AL MEDIR, y que no se sabía: · La deuda de construcción NO son 12+12+13+12 recetas: es UNA lista de 12 vista desde cuatro grafos (la cadena GUI de la cascada de mesa). Un solo arreglo —declarar python3 y cmake en `[deps]`, no engordar el rootfs del worker— las destraba todas. `base` y `cli` ya están al 100%, KDE cierra 162/162. · De WMs Wayland ligeros no hay NINGUNO: sólo `foot` y `mako`. Falta wlroots entero, los compositores y todos los accesorios (waybar, fuzzel, swaybg, grim, slurp, wl-clipboard). · De aplicaciones gráficas de terceros hay CERO. Ni visor de imágenes ni lector de PDF. · Firefox no es «una receta más»: su cadena de `*-sys` con C++ es justo la frontera que el techo MSRV del sandbox (1.96) no cruza. Antes de Firefox hay que subir el techo; empezar por la receta es empezar por el final. · El texto de la licencia va inyectado en `hammer pack`, NO en la fase install: las fases entran al ArtifactHash, así que hacerlo en la receta re-hashearía las 1141. Pack es aguas abajo y sale gratis. Misma lógica que hizo pagable el campo `license`. Dos correcciones al SDD 19, que escribí yo ayer y tenía mal: · «5 de 771 recetas declaran licencia» — falso por partida doble. El número real era 0 de 1141; los «5» eran falsos positivos de `grep license` (nombres de paquete, una línea de install, un comentario) y 771 son los nodos del grafo del corpus, no las recetas. · «El repo no declara licencia» — falso: hay LICENSE (MIT) en la raíz y en Cargo.toml. No lo miré antes de escribirlo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
257 lines
12 KiB
Markdown
257 lines
12 KiB
Markdown
# SDD 21 — Manual del piloto: qué hago yo, paso a paso
|
|
|
|
Escrito 2026-08-07, a pedido del usuario: «un tipo manual, todos los pasos que tengo que ir haciendo
|
|
en las tres etapas que marcan esos dos codos».
|
|
|
|
El inventario de lo que falta está en el [SDD 20](20-catalogo-publicable-y-completa.md). **Esto es lo
|
|
otro**: lo que hace el humano, en orden, con el comando al lado y el motivo debajo. Un comando por
|
|
vez — nada de bloques largos para pegar a ciegas.
|
|
|
|
**Convención**: `$` = lo tecleás vos. Si un paso puede hacerlo el agente solo, dice **[agente]** y
|
|
sólo tenés que pedirlo.
|
|
|
|
---
|
|
|
|
# ETAPA 0 — La rutina, siempre
|
|
|
|
Esto no es una etapa con final: es lo que se hace cada vez que se enciende la máquina. Si algo de
|
|
acá falla, todo lo demás corre sobre arena.
|
|
|
|
### 0.1 Después de CADA reinicio: dos comprobaciones
|
|
|
|
```
|
|
$ git -C ~/hammer fsck
|
|
```
|
|
Un crash puede dejar el `.git` corrupto. Si esto grita, **parar y avisar antes de seguir trabajando**:
|
|
un commit encima de un repo roto empeora el problema.
|
|
|
|
```
|
|
$ pgrep -x crond
|
|
```
|
|
Si no imprime un número, **el latido está muerto y no se nota**: la cosecha del worker, la siembra de
|
|
recetas y la regeneración del grafo dejan de correr en silencio. arje-zero como PID 1 no arranca
|
|
cronie, así que pasa en cada arranque. Se revive con:
|
|
|
|
```
|
|
$ sudo /usr/bin/crond -s
|
|
```
|
|
Tiene que ser esa ruta y ese flag. **`rc-service` FALLA** — ya se probó.
|
|
|
|
### 0.2 El disco, una vez al día
|
|
|
|
```
|
|
$ df -h /home
|
|
```
|
|
Por debajo de **50 G libres**, actuar. La válvula es:
|
|
|
|
```
|
|
$ cd ~/hammer && ./scripts/store-gc.sh --aplicar
|
|
```
|
|
⚠️ **En PRIMER PLANO, mirando la pantalla.** No en segundo plano, no con `&`, no con `nohup`. El
|
|
2026-08-07 este script informó «364 artefactos borrados, 24G liberados» **sin haber borrado ninguno**
|
|
— corriendo en segundo plano el borrado no se materializaba y el `echo` se creía el `rm`. Ahora lleva
|
|
un guardián que recuenta sobre el disco y sale con error si sobrevivió algo, pero la regla de correrlo
|
|
en primer plano sigue en pie.
|
|
|
|
Recupera ~24 G por ciclo de trabajo (los artefactos *superados*). Si hace falta más, el orden de
|
|
reservas, de barata a cara, está en la nota `capacidad-disco-proyeccion`.
|
|
|
|
### 0.3 El respaldo
|
|
|
|
```
|
|
$ cd ~/hammer && ./scripts/respaldo-storagebox.sh
|
|
```
|
|
**Es interrumpible y continuable**: podés cortarlo con Ctrl-C o apagar el laptop cuando quieras, y al
|
|
relanzarlo sigue donde quedó — incluso a mitad de un fichero grande. Corré esto siempre que vayas a
|
|
tener la máquina encendida un rato largo.
|
|
|
|
Dato medido en la oficina el 2026-08-07: el uplink da **8 Mbps de subida, iguales por cable y por
|
|
wifi** ⇒ el cuello está en la conexión del local, no en tu laptop, y **enchufar el cable no cambia
|
|
nada**. Los 128 G del store no caben en una sentada; por eso el script sube primero el *cerebro*
|
|
(estado + repo, que es lo que no se puede perder) y después el store.
|
|
|
|
### 0.4 El worker
|
|
|
|
```
|
|
$ hcloud server list
|
|
```
|
|
Si `hworker-1` aparece, está facturando. Se apaga solo: lleva un *dead-man* propio que lo **borra**
|
|
(no lo apaga — apagado seguiría facturando) tras 1 hora sin builds. Para ver si está trabajando de
|
|
verdad **mirá los procesos, no la carga**: durante el `sleep 180` del bucle la carga marca 0 y parece
|
|
idle sin estarlo.
|
|
|
|
---
|
|
|
|
# ETAPA 1 — De hoy a «la distro está PUBLICABLE»
|
|
|
|
El orden está elegido para que lo bloqueante vaya primero y lo caro después. **La trampa clásica es
|
|
invertirlo**: pasarse meses con el navegador y descubrir el día del anuncio que no se puede publicar.
|
|
|
|
### Paso 1 — Destrabar las 12 recetas en deuda
|
|
**[agente]** Es un solo agujero visto desde cuatro grafos: la cadena GUI de la cascada de mesa. No se
|
|
pueden construir en el laptop (zig-skew rompe cairo) y fallan en el worker porque su rootfs no trae
|
|
python3 ni cmake.
|
|
|
|
El arreglo correcto es **declarar las herramientas en `[deps]` de cada receta, NO engordar el rootfs
|
|
del worker**. Engordarlo parece más rápido y es justo lo que rompe la reproducibilidad: el build
|
|
pasaría a depender de qué hay instalado en una máquina concreta.
|
|
|
|
Vos: pedirlo, y tener el worker arriba.
|
|
|
|
### Paso 2 — Terminar las licencias
|
|
**[agente]** Quedan 913 de 1141, casi todas CLIs Go/Rust. Se automatiza con evidencia real y sin red:
|
|
`Cargo.toml` trae el campo `license` y los módulos Go traen su `LICENSE` en el árbol.
|
|
|
|
Para ver dónde estamos en cualquier momento:
|
|
```
|
|
$ cd ~/hammer && ./scripts/licencias.sh
|
|
```
|
|
|
|
**Lo que te toca decidir a vos**: cuando una licencia sea ambigua, se deja vacía. No se rellena a
|
|
ojo. Un hueco contado es deuda; un hueco rellenado a ojo es una mentira sobre la que alguien va a
|
|
construir.
|
|
|
|
### Paso 3 — El texto de la licencia dentro del paquete
|
|
**[agente]** Va en `hammer pack`, **no** en la fase `install` de las recetas. Las fases entran al
|
|
`ArtifactHash`, así que hacerlo ahí re-hashearía las 1141; pack es aguas abajo y sale gratis.
|
|
|
|
### Paso 4 — El espejo de fuentes
|
|
**[agente]** construye; **vos** decidís dónde vive y pagás el alojamiento.
|
|
|
|
Es la obligación de la GPL que más se malinterpreta: no es «que el código exista en internet», es que
|
|
quien recibe el binario pueda obtener **de nosotros** la fuente correspondiente. Como cada receta
|
|
pinea `tarball` + `sha256`, es mecánico y encima verificable. **Tiene que existir antes de la primera
|
|
descarga pública.**
|
|
|
|
Decisión tuya: el Storage Box ya tiene 1 TiB y sobra sitio — puede servir de espejo de fuentes sin
|
|
gastar un euro más, pero no está pensado para servir tráfico web. Conviene decidirlo antes.
|
|
|
|
### Paso 5 — Las claves de firma 🔑 **esto es tuyo, no delegable**
|
|
Hoy hay firma de índice; falta el nivel de arriba. Hace falta:
|
|
|
|
1. Generar una **clave raíz fuera de línea** — en una máquina que no esté en internet, y que **nunca**
|
|
toque este laptop ni el worker.
|
|
2. Guardar el respaldo de esa clave **en papel o en un medio que no esté conectado**, en otro sitio
|
|
físico.
|
|
3. Generar claves de firma intermedias, rotables, firmadas por la raíz.
|
|
4. Escribir el procedimiento de qué hacer si se filtra una.
|
|
|
|
**Por qué te toca a vos**: una clave raíz que un agente puede leer no es una clave raíz. Y firma sin
|
|
gestión de claves es teatro — peor que no firmar, porque da confianza falsa.
|
|
|
|
### Paso 6 — La imagen en metal
|
|
Falta **re-quemar el USB** (está a medias).
|
|
|
|
```
|
|
$ lsblk -o NAME,SIZE,TRAN,MODEL
|
|
```
|
|
⚠️ **Identificá el disco por tamaño/modelo/transporte, NUNCA por nombre.** Los nombres bailan entre
|
|
arranques. Y **jamás quemar a un NVMe**: ahí vive tu sistema.
|
|
|
|
Al validar imágenes de escritorio, **con pantalla, nunca sólo `-nographic`**. Dos trampas ya pagadas
|
|
caro: `/dev/console` es el serial, así que cada capa tiene que escribir a `/dev/tty0` para que la
|
|
veas; y para COSMIC en QEMU `-vga none` es **obligatorio** (virtio-gpu suma una VGA ⇒ dos salidas, y
|
|
el panel se ancla en la que no estás capturando), con `-smp 8` porque el panel tiene deadline de
|
|
arranque.
|
|
|
|
### Paso 7 — Probar la actualización de verdad
|
|
**[agente]** monta el ensayo; **vos** mirás el resultado. Instalar N, actualizar a N+1, que arranque.
|
|
Y **rollback**, que con un store direccionado por contenido debería ser barato — es la ventaja
|
|
natural de esta arquitectura, y conviene que sea función de primera clase antes de publicar, no
|
|
después.
|
|
|
|
### Paso 8 — `cups` y `bluez`
|
|
**[agente]**. Impresión y bluetooth. Sin esto la distro se siente incompleta aunque todo lo demás ande.
|
|
|
|
### Paso 9 — La infraestructura pública
|
|
- Espejo de paquetes: **~30 G** separando los `-debug` en paquetes aparte (el 79% del store es
|
|
información de depuración). **Vos**: contratar el alojamiento.
|
|
- Sitio de descarga con sumas y firmas, y las instrucciones para verificarlas.
|
|
- **Publicar la evidencia de reproducibilidad**: los `ArtifactHash` de la clausura de cada imagen.
|
|
Esto es *el* diferenciador — es lo que convierte «somos reproducibles» en algo que un extraño puede
|
|
comprobar. No lo dejes para después: es lo único que nadie más está ofreciendo.
|
|
- Un canal de reportes y una dirección para avisos de seguridad.
|
|
|
|
### Paso 10 — Antes de anunciar: el ensayo general
|
|
Ensayar el ciclo completo de seguridad **con un CVE de mentira**: detectar, construir, firmar,
|
|
publicar, y que le llegue a una máquina instalada. Si esto no está ensayado, el primer CVE real te
|
|
encuentra improvisando.
|
|
|
|
---
|
|
|
|
# ETAPA 2 — De PUBLICABLE a «la distro está COMPLETA»
|
|
|
|
Acá ya estás publicado y tenés usuarios. Cambia el modo de trabajo: **cada cosa que agregues tiene
|
|
que llegarles por el canal de actualización**, así que la Etapa 1 §7 tiene que estar sólida.
|
|
|
|
### Paso 1 — Los WMs Wayland ligeros (empezá por acá)
|
|
Es la mejor relación esfuerzo/resultado que queda: no hay una torre de C debajo. En orden:
|
|
|
|
1. **`wlroots`** — la base de la que cuelgan casi todos. Sin esto no hay nada más.
|
|
2. Los compositores: **`sway`**, `labwc`, `river`, `niri`.
|
|
3. Los accesorios, **sin los cuales un WM no se usa de verdad**: `waybar`, `fuzzel`/`wofi`, `swaybg`,
|
|
`swayidle`, `swaylock`, `grim`, `slurp`, `wl-clipboard`.
|
|
|
|
Hoy de toda esa familia sólo existen `foot` y `mako`.
|
|
|
|
### Paso 2 — Las aplicaciones baratas, que son las que más se notan
|
|
`imv` (imágenes), `zathura` (PDF), `mpv` (vídeo), un gestor de archivos, un editor gráfico. Cada una
|
|
es una tarde, y juntas cambian por completo la sensación de la distro. **Medido: hoy no hay ninguna
|
|
aplicación gráfica de terceros.**
|
|
|
|
### Paso 3 — La deuda de fondo, antes de crecer más
|
|
- Las **16 recetas con `compiler = "gcc"`**. Las 12 de Rust son un solo problema: falta el unwinder
|
|
de libgcc.
|
|
- El **no-determinismo de 92 paquetes** (rutas `/src` en secciones `.debug_*`). El arreglo global
|
|
re-hashea ~720 recetas ⇒ **es una decisión tuya de arquitectura**, y conviene tomarla cuando el
|
|
corpus sea lo más chico posible. Cada mes que pasa es más caro.
|
|
- **ADR 0012, la carrera del árbol de fuentes**: pendiente y sin decidir. Aviso registrado: *un lock
|
|
sólo en la extracción parece correcto y NO lo es.*
|
|
|
|
### Paso 4 — LibreOffice
|
|
Caro pero acotado. Antes que el navegador.
|
|
|
|
### Paso 5 — El navegador 🏔️
|
|
**Presupuestalo como un frente propio, no como una receta.** Firefox es Rust + C++ + su propio
|
|
sistema de build, y arrastra cbindgen, nasm, nodejs y una cadena de `*-sys` con C++ — que es justo la
|
|
frontera que el techo MSRV del sandbox (1.96) no cruza todavía. O sea que **antes de Firefox hay que
|
|
subir el techo del sandbox**; empezar por la receta es empezar por el final.
|
|
|
|
**Decisión tuya y de las primeras**: marca. Redistribuir Firefox con su nombre y logo exige cumplir
|
|
la política de Mozilla (por eso Debian tuvo Iceweasel). Cumplir o rebrandear — pero decidido antes de
|
|
construir, no después.
|
|
|
|
---
|
|
|
|
# ETAPA 3 — Después de COMPLETA: que siga viva
|
|
|
|
La distro deja de ser un proyecto de construcción y pasa a ser uno de **mantenimiento**. Lo que hay
|
|
que sostener:
|
|
|
|
1. **Cadencia de release** escrita y cumplida. Una distro sin ritmo previsible pierde usuarios aunque
|
|
sea técnicamente mejor.
|
|
2. **Seguridad continua**: seguir CVEs de lo empaquetado y publicar actualizaciones. Esto no se
|
|
pausa. Es el compromiso real que asumís al publicar.
|
|
3. **La reconstrucción desde cero, cronometrada, en una máquina limpia.** Repetirla periódicamente:
|
|
es la prueba de que el proyecto no depende de este laptop — que es exactamente la preocupación que
|
|
originó el respaldo del 2026-08-07. Si un día deja de funcionar, te enterás por el ensayo y no por
|
|
una desgracia.
|
|
4. **El reconstructor independiente**: otra máquina, idealmente de otra persona, que reconstruya y
|
|
compare hashes en continuo. Es el objetivo final del invariante de hammer — el día que un tercero
|
|
confirme bit a bit lo que publicamos, la promesa deja de ser nuestra palabra.
|
|
5. **Contribuciones de fuera**: si llega gente, hace falta cómo aceptar recetas sin bajar el listón
|
|
(revisión, firma, y que el aporte no rompa la reproducibilidad).
|
|
|
|
---
|
|
|
|
## Lo que yo haría el lunes que viene
|
|
|
|
En este orden, y sin saltarse:
|
|
|
|
1. `pgrep -x crond` y revivirlo. Sin latido no hay cosecha.
|
|
2. Dejar corriendo el respaldo mientras trabajás.
|
|
3. Pedir el arreglo del rootfs del worker → caen las 12 recetas en deuda.
|
|
4. Pedir la automatización de las 913 licencias.
|
|
5. **Generar la clave raíz fuera de línea.** Es lo único de la lista que no puede hacer nadie más que
|
|
vos, y es el que más tarda en poder empezarse si se posterga.
|