Files
hammer/docs/21-manual-del-piloto.md
T
sergioandClaude Opus 5 e79b26970a docs: SDD 20 (catálogo hasta publicable y hasta completa) + SDD 21 (manual del piloto)
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>
2026-08-07 10:28:37 -04:00

12 KiB

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