Commit Graph
1301 Commits
Author SHA1 Message Date
sergio 3fb85f23ee estado: cosecha granja 2026-08-09T11:44:40Z — avance del árbol KDE 2026-08-09 07:44:40 -04:00
sergioandClaude Opus 5 3856e84e71 los cuatro escritorios al día: KDE 162/162 · sway 121/121 · COSMIC 88/89 · GNOME 122/125
Cierre de la reparación. Lo que faltaba eran cuatro recetas que caían todas por `libsndfile`
—cuyo configure de autotools sólo busca python2.x— y `gnome-shell`, que había que rehacer.
Selladas en el hub: wireplumber, xdg-desktop-portal, xdg-desktop-portal-cosmic,
xdg-desktop-portal-gnome y gnome-shell.

ESTADO FINAL DE LOS PERFILES:
  base 51/51 · cli 74/74 · escritorio-sway 121/121 · escritorio-kde 162/162
  escritorio-cosmic 88/89 · escritorio-gnome 122/125
Lo que queda NO es deuda técnica sino decisiones ya tomadas:
  · gdm, gnome-session, gnome-settings-daemon → CERRADAS por decisión (GTK3, 2026-08-08);
  · portal-probe → git privado por SSH, HUB-ONLY estructural.

⚠ HALLAZGO EN LA GOLDEN NUEVA, que hay que arreglar antes de confiar en ella: el volumen
persistente `harkaq-cosecha` se monta ENCIMA de `/opt/hammer/store` y **tapa el store horneado
en la imagen**. El worker nuevo arrancó con 2 artefactos en vez de los ~900 que trae el
snapshot, así que la caché de la golden es hoy inútil: el bind del volumen la esconde. El
toolchain sí se heredó bien (cargo/rustc 1.96.0, go 1.26.4 verificados en el arranque).
⇒ O el volumen deja de montarse sobre esa ruta, o la golden no necesita traer store. Hoy hace
las dos cosas y se anulan.

Por eso estas cinco se construyeron en el hub y no en la granja: para cinco recetas no valía la
pena resolver el solapamiento, y el hub las tenía todas cacheadas.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 07:34:44 -04:00
sergio ad3c761f8b estado: cosecha granja 2026-08-09T08:43:09Z — avance del árbol KDE 2026-08-09 04:43:09 -04:00
sergio 5fbe85580b estado: cosecha granja 2026-08-09T06:41:34Z — avance del árbol KDE 2026-08-09 02:41:34 -04:00
sergio fa319a59c0 estado: cosecha granja 2026-08-09T06:10:25Z — avance del árbol KDE 2026-08-09 02:10:25 -04:00
sergio 458afec6db estado: cosecha granja 2026-08-09T05:39:24Z — avance del árbol KDE 2026-08-09 01:39:24 -04:00
sergioandClaude Opus 5 0ac421b516 libsndfile: su configure sólo busca python2.x — tumbaba CUATRO recetas y parecía fallo de cada una
COSMIC cerró 25 de 30 raíces. De los 5 fallos, CUATRO daban el mismo mensaje —
«error: no suitable Python interpreter found»— en wireplumber, xdg-desktop-portal,
xdg-desktop-portal-cosmic y cosmic-settings-daemon.

NO ERA DE ELLAS, Y NI SIQUIERA ERA DE MESON. El error viene de un `configure` de AUTOTOOLS que
prueba `python2.2`, `python2.1`, `python2.0` —literalmente— y aborta al no hallarlos. Se
identificó por las flags del comando en el log (`--disable-mpeg --disable-full-suite`), que son
inconfundibles de **libsndfile**: una dep común a las cuatro.

Y declarar `python3` en `[deps]` NO ayuda —dos de las cuatro ya lo tenían—: el problema no es
que falte el intérprete, es que el script no reconoce ese NOMBRE. Autoconf respeta la variable
de entorno `PYTHON`, así que se le pasa `PYTHON=python3` y sella.

LA LECCIÓN, que hoy ya se repitió con `dbus-shared`: cuando varias recetas fallan con el MISMO
mensaje raro, el fallo está en una dep común — y **la forma de identificarla es mirar QUÉ
configure/meson.build lo emite**, no la receta que se estaba construyendo. Las flags del comando
y el número de línea del meson.build son la firma del paquete que realmente muere.

Aplicado a las tres copias (incoming-gnome, -cosmic, -kde), que dan el mismo hash. Y de paso
`cosmic-settings-daemon` sí necesitaba `python3` en deps, que no lo declaraba: dos causas
distintas bajo un mensaje idéntico.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 01:17:01 -04:00
sergio 1c33075d6c estado: cosecha granja 2026-08-09T04:37:26Z — avance del árbol KDE 2026-08-09 00:37:26 -04:00
sergio fd1305c4f8 estado: cosecha granja 2026-08-09T04:06:27Z — avance del árbol KDE 2026-08-09 00:06:27 -04:00
sergio 0242df154f estado: cosecha granja 2026-08-09T03:35:24Z — avance del árbol KDE 2026-08-08 23:35:24 -04:00
sergio c6ee752742 estado: cosecha granja 2026-08-09T03:04:24Z — avance del árbol KDE 2026-08-08 23:04:24 -04:00
sergio 68f0e64f94 estado: cosecha granja 2026-08-09T02:02:13Z — avance del árbol KDE 2026-08-08 22:02:13 -04:00
sergio 5262aa5494 estado: cosecha granja 2026-08-09T00:59:56Z — avance del árbol KDE 2026-08-08 20:59:56 -04:00
sergio 9dba9bbfb7 estado: cosecha granja 2026-08-09T00:28:43Z — avance del árbol KDE 2026-08-08 20:28:43 -04:00
sergio ee2cab7328 estado: cosecha granja 2026-08-08T23:57:27Z — avance del árbol KDE 2026-08-08 19:57:27 -04:00
sergio 2ec3ac2ce8 estado: cosecha granja 2026-08-08T23:25:49Z — avance del árbol KDE 2026-08-08 19:25:49 -04:00
sergio ea2d974163 estado: cosecha granja 2026-08-08T22:52:25Z — avance del árbol KDE 2026-08-08 18:52:25 -04:00
sergio 83cbb52dcb estado: cosecha granja 2026-08-08T22:20:55Z — avance del árbol KDE 2026-08-08 18:20:55 -04:00
sergio 7d79ce234c estado: cosecha granja 2026-08-08T21:49:47Z — avance del árbol KDE 2026-08-08 17:49:47 -04:00
sergioandClaude Opus 5 889720cac0 granja: golden NUEVA con Rust y Go — desbloquea el 76% del catálogo
Imagen 417847948 («hammer-golden-rust-go-2026-08-08») reemplaza a 408909310 como default de
farm-up.

EL PROBLEMA QUE CIERRA: hammer invoca `cargo vendor` y el toolchain Go en el HOST, no dentro
del sandbox — el vendoreo pasa ANTES de entrar a la caja. La golden vieja no los traía, así que
la granja no podía construir NINGUNA receta Rust ni Go: COSMIC entero, las 228 Rust y las 362
Go del corpus. El 76% del catálogo dependía de UNA SOLA máquina, el hub — justo lo que el
respaldo de ayer intentaba dejar de asumir.

VERIFICADO ANTES DE SNAPSHOTEAR, no después: `cosmic-bg` —que minutos antes moría con
`spawn cargo vendor: No such file`— sella en el worker. Un snapshot de una máquina a medio
arreglar es peor que ninguno.

MISMAS VERSIONES QUE EL HUB (cargo/rustc 1.96.0, go 1.26.4) a propósito: introducir un skew de
toolchain nuevo mientras se arregla otro es cómo se fabrican los fallos que nadie reproduce. Y
1.96 es además el techo MSRV del sandbox ya documentado.

NO RELAJA LA HERMETICIDAD: cargo/go son herramientas de FETCH, del mismo orden que `git` para
clonar. El build sigue ocurriendo dentro del sandbox con el árbol ya vendoreado. Es lo contrario
del caso «no engordar el rootfs del worker», que habla del rootfs DEL SANDBOX.

El PATH queda persistido en /etc/profile.d/hammer-toolchain.sh para que sobreviva a los logins
no interactivos de la granja. Y la imagen trae el store del worker al momento del snapshot (KDE
y GNOME reconstruidos hoy), así que los workers nuevos arrancan con más caché.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 17:33:57 -04:00
sergio c7dd6652c0 estado: cosecha granja 2026-08-08T21:18:22Z — avance del árbol KDE 2026-08-08 17:18:22 -04:00
sergioandClaude Opus 5 dff8409660 granja: el worker NO TIENE Rust ni Go — el 76% del catálogo sólo construye en el hub
Al lanzar COSMIC, sus 30 raíces fallaron de golpe con «spawn cargo vendor: No such file».
Medido:
    worker:  cargo AUSENTE · rustc AUSENTE · go AUSENTE
    hub:     cargo ✓ · rustc ✓ · go ✓

hammer invoca `cargo vendor` en el HOST, no dentro del sandbox — el vendoreo pasa ANTES de
entrar a la caja. El worker no trae toolchain de Rust ni Go ⇒ la granja no puede construir
NINGUNA receta Rust o Go: COSMIC entero, las 228 Rust del corpus y las 362 Go. **El 76% del
catálogo sólo puede construirse en el hub**, que es UNA SOLA MÁQUINA — justo lo que el respaldo
de ayer intentaba dejar de asumir.

ESTO EXPLICA HACIA ATRÁS todos los «no construyó» de esta campaña (amp, anew, apko, atlas, bom,
broot, cargo-audit, cargo-hack, git-absorb). Yo lo atribuí a «necesitan red para sus módulos» y
lo escribí así en el SDD 23 y en memoria. Era falso: **falta el binario**, no la red.

Y ARREGLARLO NO ROMPE LA HERMETICIDAD: cargo/go aquí son herramientas de FETCH, del mismo orden
que `git` para clonar — se usan para traer y fijar deps ANTES del build, no dentro del sandbox.
Instalarlos en la imagen golden no relaja el aislamiento; el build sigue ocurriendo en la caja
con el árbol ya vendoreado. Es lo contrario del caso «no engordar el rootfs del worker», que
habla del rootfs DEL SANDBOX.

⇒ Decisión de aprovisionamiento, no de arquitectura, y desbloquea tres cuartas partes del
catálogo para la granja.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 17:03:55 -04:00
sergioandClaude Opus 5 0f1f2e9ef6 dbus-shared: la misma flag ausente tumbaba GNOME y COSMIC enteros
`mutter`, `gnome-shell` y `xdg-desktop-portal-gnome` fallaban las tres con «ERROR: Unhandled
python exception». Las tres YA tenían `--wrap-mode=nodownload` en su propia receta, así que no
era eso — hasta que el log mostró la línea culpable:

    meson.build:372:11: ERROR: Unhandled python exception
    <urlopen error unknown url type: https>
    WARNING: failed to download with error: name 'ssl' is not defined

La misma línea 372 que el fallo de `dbus` de hace unas horas. No fallaban ellas: fallaba una
DEP que arrastran, `dbus-shared`, cuya sombra en incoming-gnome e incoming-cosmic no tenía la
flag. La canónica del corpus y la sombra de KDE sí la tenían; estas dos no.

⇒ UNA flag ausente en una sombra tumbaba TRES raíces de perfil en GNOME y bloqueaba COSMIC de
paso. Y el mensaje nunca nombra la red: «Unhandled python exception» se lee como un bug de
meson y es que el sandbox es hermético a propósito.

Lección de método: cuando tres recetas fallan con el MISMO error y las tres ya tienen el
arreglo obvio, el fallo está en una dep común, no en ellas. La línea de meson.build en el
mensaje es lo que lo identifica — es la firma del paquete que realmente muere.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 16:46:40 -04:00
sergio e5888a271d estado: cosecha granja 2026-08-08T20:43:28Z — avance del árbol KDE 2026-08-08 16:43:28 -04:00
sergio 2c0fb26955 estado: cosecha granja 2026-08-08T20:10:04Z — avance del árbol KDE 2026-08-08 16:10:04 -04:00
sergio f1f7760879 estado: cosecha granja 2026-08-08T19:37:11Z — avance del árbol KDE 2026-08-08 15:37:11 -04:00
sergio c860a3d3e7 estado: cosecha granja 2026-08-08T19:05:46Z — avance del árbol KDE 2026-08-08 15:05:46 -04:00
sergio fcdcf5207f estado: cosecha granja 2026-08-08T18:33:46Z — avance del árbol KDE 2026-08-08 14:33:46 -04:00
sergio 6e51e9fb48 estado: cosecha granja 2026-08-08T18:02:06Z — avance del árbol KDE 2026-08-08 14:02:06 -04:00
sergioandClaude Opus 5 245a425031 estado: KDE 76→83/162 tras reconstruir las 7 recetas de la FRONTERA
perl-xml-parser, libpcap, libnl, lm-sensors, libxkbcommon, vulkan-loader y dbus — las siete
sombras de incoming-kde cuyas deps sí estaban al día, o sea el origen de la deriva. 7 de 7
selladas, sin un solo fallo: confirma el diagnóstico de que no había muro técnico, sólo
artefactos que nadie había reconstruido.

Quedan 79, todas aguas abajo. En vez de ir ola por ola se lanzó la construcción de las 11
RAÍCES del perfil y hammer resuelve la clausura solo — que es para lo que sirve el grafo de
deps y evita adivinar el orden a mano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 13:48:18 -04:00
sergioandClaude Opus 5 9273880745 docs: por qué KDE está en 76/162 — los artefactos NO EXISTEN, y la causa es estructural
Diagnóstico completo. No es daño de la campaña del split ni un fallo de store-gc.

LO MEDIDO, en orden:
1. 86 nodos del perfil sin artefacto en su hash vigente.
2. NO lo causó el split: revertidas una por una todas las recetas tocadas hoy (3 bibliotecas
   base, 30 hojas, dbus, 38 de la 2ª tanda) el número NO se movió de 198 en ningún caso.
3. La FRONTERA son 7 recetas —las únicas cuyas deps sí están al día—: dbus, libnl, libpcap,
   libxkbcommon, lm-sensors, perl-xml-parser, vulkan-loader. Las otras 79 cuelgan de ellas.
4. Las 7 son SOMBRAS de incoming-kde, no las canónicas. Las del corpus están al día, y por eso
   el problema es INVISIBLE desde el grafo del corpus — que es justo el que yo miraba.
5. No fue store-gc: sus hashes vigentes no figuran en ningún manifiesto de borrado, y tres nunca
   se podaron. (Lo sospeché porque la regla de «superado» es por NOMBRE y una sombra comparte
   nombre con la canónica; la sospecha era razonable y los manifiestos la descartan.)
6. Ni el hub ni el worker los tienen. No están en otro sitio: NO ESTÁN.

LA CAUSA DE FONDO, que importa más que KDE: la cola se construyó en workers EFÍMEROS, el sync
del store es unidireccional (worker→hub) y esos workers ya no existen. Cuando algo del sustrato
compartido cambió después, las sombras se re-hashearon y nadie las reconstruyó, porque el hub
nunca fue la máquina donde vivía ese escritorio.

⇒ Con flota efímera y sync unidireccional, un escritorio puede dejar de ser
reconstruible-desde-el-store SIN QUE NINGÚN INDICADOR LO DIGA. El grafo seguía reportando
162/162 desde un JSON generado semanas antes.

Coste de arreglarlo: 86 reconstrucciones en la granja, empezando por las 7 de la frontera. No
hay muro técnico conocido — son recetas que ya construyeron. Es cómputo, no investigación.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 12:25:31 -04:00
sergioandClaude Opus 5 7a3444a36f docs: el «KDE 162/162» del SDD 20 salía de un grafo VIEJO — son 76/162, y no es culpa de la campaña
Al desplegar la 2ª tanda de hojas noté 198 recetas de las colas de escritorio sin artefacto
vigente (KDE 133, GNOME 37, COSMIC 24) y asumí que las había roto yo. **No.**

LO VERIFIQUÉ REVIRTIENDO, una causa por vez: las 3 bibliotecas base (expat, zstd, ncurses), las
30 hojas de la 1ª tanda, `dbus`, y las 38 de la 2ª. **El número no se movió de 198 en ningún
caso.** Y mirando el histórico, `escritorio-kde` está en 76/162 en TODOS los commits recientes
—09:10, 09:41, 10:12, 10:44, 11:16, 11:49— o sea desde antes de que la campaña empezara.

EL ERROR FUE MÍO Y DE MÉTODO: escribí «KDE cierra 162/162» leyendo
`docs/state/build-state-kde.json` **sin regenerarlo**. Es un fichero GENERADO, y un generado que
no se regenera es una foto vieja con aspecto de dato fresco. El mismo tipo de fallo que citar el
«79%» midiendo otra unidad: el dato existía, lo que fallaba era de cuándo era.

⇒ Y hay un aviso de fondo para toda la sesión: **medí «cero daño colateral» sobre el grafo
`--wlr`, que sólo carga corpus + incoming-wlr.** Las colas de escritorio son INVISIBLES ahí, así
que ese «cero» era cierto en el grafo que miraba y no decía nada del catálogo completo. Para
juzgar impacto hay que cargar TODAS las colas.

Las 38 de la 2ª tanda quedan revertidas: hasta entender los 198 no conviene añadir cambios
encima. Las 30 de la 1ª y las 5 del piloto siguen puestas y verificadas.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 12:12:51 -04:00
sergio f879a802cb estado: cosecha granja 2026-08-08T15:49:28Z — avance del árbol KDE 2026-08-08 11:49:34 -04:00
sergioandClaude Opus 5 56d4de5fb0 estado: grafo wlr tras la tanda de 30 hojas — los tres perfiles cierran al 100%
base 51/51 · cli 74/74 · escritorio-sway 121/121. Cosecha verificada: cero artefactos en el
worker que el hub no tenga.

De la tanda: 25 de 30 selladas. Los 5 fallos, ninguno causado por el split:
· cargo-audit, cargo-hack, git-absorb — 'spawn cargo vendor': el grafo las clasifica como clase
  `c` porque declaran compiler=gcc para sus deps de C, pero por dentro son Cargo. Filtrar por la
  clase del grafo NO basta.
· hammerd — git privado por SSH (HUB-ONLY, como las de tawasuyu).
· coreutils — 'you should not run configure as root'. Esto NO lo causó el split: es DERIVA. La
  receta llevaba tiempo sin poder construirse en el lab actual y nadie lo sabía porque su
  artefacto viejo seguía en el store. Es exactamente lo que la campaña destapa.

⚠ Y de ahí sale un riesgo que conviene nombrar: cada receta que deja de reconstruir convierte su
artefacto viejo en un REHÉN — store-gc no puede podarlo (es el único ejemplar) y nadie puede
regenerarlo. Hoy son ~12 G inmovilizados, y crecen con cada receta que se rompe en silencio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 11:47:37 -04:00
sergio 5ed64aa44a estado: cosecha granja 2026-08-08T15:16:41Z — avance del árbol KDE 2026-08-08 11:16:41 -04:00
sergioandClaude Opus 5 c56fd373a1 etapa 4: tanda de 30 HOJAS — cero daño colateral, que era el punto
Primera tanda con el orden nuevo (por impacto en el grafo, no alfabético). 30 recetas C de
clase HOJA: bash, coreutils, git, gnupg, grep, gzip, jq, e2fsprogs, libarchive, htop…

LA MEDIDA QUE JUSTIFICA EL CAMBIO DE ORDEN: activar estas 30 dejó 41 recetas sin artefacto
vigente = las 12 que ya estaban en deuda + las 30 tocadas (una ya estaba entre las 12). **Cero
colateral.** Contra la tanda anterior, donde tocar TRES bibliotecas base (expat, zstd, ncurses)
dejó 54 sin artefacto y tumbó la cadena wlroots/sway entera.

Mismo esfuerzo de build, diez veces menos destrozo. El orden no era un detalle de comodidad.

Selección: clase `c` + `dependientes_total == 0` + estado sellado, excluyendo las de tawasuyu
(git privado ⇒ no construyen en el worker, que es sin secretos por diseño) y las Go/Rust, que
necesitan sus módulos y fallan ahí. Quedan 73 hojas C elegibles; van 30.

La tanda corre DESASIDA con nohup en el worker — la lección de ayer, cuando un drenaje murió a
las 14 de 54 al caerse la sesión ssh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 11:14:37 -04:00
sergioandClaude Opus 5 15e34cb257 dbus: una flag ausente bloqueaba TRES perfiles — --wrap-mode=nodownload
`base`, `cli` y `escritorio-sway` bajaron a 50/51, 73/74 y 120/121 después de la cascada del
split, y los tres fallaban por LA MISMA receta: dbus.

EL ERROR NO MENCIONABA LA RED POR NINGÚN LADO:
    meson.build:372:11: ERROR: Unhandled python exception
Y arriba, enterrado entre reintentos:
    <urlopen error unknown url type: https>
    WARNING: failed to download with error: name 'ssl' is not defined
dbus declara subproyectos con `.wrap` y meson intenta DESCARGARLOS. En el sandbox no hay red y
python no trae ssl ⇒ «Unhandled python exception», que se lee como un bug de meson y es
simplemente que no hay salida a internet. Y no debe haberla: el build es hermético a propósito.

`--wrap-mode=nodownload` obliga a usar las deps del sistema (nuestros artefactos, vía
pkg-config) y deja los wraps inertes. Mismo caso que `wl-clipboard` anoche.

⇒ base 51/51 · cli 74/74 · escritorio-sway 121/121. Los tres cierran otra vez.

ESTADO DE LA REPARACIÓN DE LA CASCADA: de las 54 que quedaron sin artefacto, 42 reconstruidas.
Las 12 restantes son EXACTAMENTE las que ya estaban en deuda antes de la campaña:
  · 6 el muro del PIC (gtk4 y su cadena estática — duplicado superado de la dinámica de GNOME);
  · 3 HUB-ONLY (mirada-*, llimphi-counter: git privado / commit en ceros);
  · dwarves (libdw/musl), y adwaita-hello (error 39 = la carrera del ADR 0012).
O sea que la campaña no dejó deuda nueva.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 10:58:05 -04:00
sergioandClaude Opus 5 040d174bbe desplegar-strip: ordenar por IMPACTO EN EL GRAFO, no alfabéticamente
Medido sobre el corpus: **686 de 779 recetas son HOJAS** (cero dependientes transitivos) ⇒ el
88% se puede desplegar sin provocar UNA SOLA reconstrucción extra. Las caras son pocas y
conocidas: make 416 · pkgconf 360 · go 359 · binutils 343 · zlib 315 · python3 287 ·
samurai 272 · meson 257.

El orden alfabético anterior era activamente malo: la primera tanda de la etapa 4 tocó expat,
zstd y ncurses —tres bibliotecas base— y dejó 54 recetas sin artefacto vigente, incluida la
cadena wlroots/sway sellada la noche anterior. Sin este orden, cada tanda pequeña provoca una
cascada grande y la campaña avanza hacia atrás.

Hojas primero; las ~93 con dependientes, en una ola coordinada y con la granja arriba.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 10:49:50 -04:00
sergio d55e7c6e61 estado: cosecha granja 2026-08-08T14:44:57Z — avance del árbol KDE 2026-08-08 10:44:57 -04:00
sergio a920b7aa3d estado: cosecha granja 2026-08-08T14:12:32Z — avance del árbol KDE 2026-08-08 10:12:32 -04:00
sergio 57ebfcaf19 estado: cosecha granja 2026-08-08T13:41:25Z — avance del árbol KDE 2026-08-08 09:41:25 -04:00
sergio 75a572ea71 estado: cosecha granja 2026-08-08T13:10:01Z — avance del árbol KDE 2026-08-08 09:10:01 -04:00
sergioandClaude Opus 5 f12303e3ab docs: SDD 23 §8 — el orden de las tandas importa más que su tamaño, y ADR 0012 acaba de morder
Activar strip_debug en tres bibliotecas BASE (expat, zstd, ncurses) re-hasheó 54 recetas en
cascada, incluida la cadena wlroots/sway. Tocar cincuenta HOJAS no habría costado ninguna
reconstrucción extra. El desplegador ordena alfabéticamente y debe ordenar por profundidad en
el grafo, de hoja a raíz.

Y ADR 0012 —la carrera del árbol de fuentes, 'pendiente sin decidir' desde hace meses— acaba de
morder: adwaita-hello murió con error 39 (Directory not empty). Una reconstrucción masiva es
exactamente el escenario que lo dispara, así que decidirlo deja de ser opcional si la etapa 4
va a correr en paralelo.

Más dos lecciones de operación: un drenaje largo no puede vivir dentro del ssh (se cortó a las
14 de 54), y la flota efímera reusa IPs, así que la clave de host cambia y cada conexión grita
MITM — conviene que farm-up lo limpie solo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 09:04:20 -04:00
sergioandClaude Opus 5 b38db3f35d respaldo: .dmerge tumbó la subida 40 veces seguidas y el mensaje nunca lo dijo
El respaldo se detuvo en 79 G de 127 G con «40 intentos y sigue cayéndose». El código era 23
(«some files/attrs were not transferred»), que está en la lista de reintentables — así que el
bucle lo reintentó cuarenta veces contra la misma pared y se rindió.

LA CAUSA, al mirar los errores de verdad en vez del código de salida: todos eran rutas
`/home/hammer/store/.dmerge/...`. Son directorios TRANSITORIOS de fusión del store, que aparecen
y desaparecen mientras hammer sella. rsync los empieza a copiar, se esfuman a media
transferencia, y falla. `cosecha-cron.sh` ya los excluía; este script no, y ésa era toda la
diferencia.

⇒ Añadido `--exclude /.dmerge`.

Y una lección para el propio bucle de reintentos: **un error reintentable que se repite 40 veces
no es un corte de red, es algo estructural**. Cuarenta reintentos idénticos deberían haber
gritado «esto no se arregla esperando» en vez de agotarse en silencio. Queda anotado; el bucle
todavía no distingue «se cayó una vez» de «falla siempre igual».

De paso, `appstream` —la única de las cinco del split que se perdió al borrarse el worker— se
reconstruyó en el hub: 18 M, 0 secciones .debug_. Las cinco quedan consistentes (hash vigente
con artefacto presente): bison 3M · appstream 18M · zstd 2M · expat 1M · ncurses 2M.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 08:41:28 -04:00
sergio 693938bed2 estado: cosecha granja 2026-08-08T12:38:32Z — avance del árbol KDE 2026-08-08 08:38:32 -04:00
sergioandClaude Opus 5 102aabd1ff SEGUNDA corrección: lo que medía el test era DERIVA, no no-determinismo — el corpus SÍ reproduce
El §1.bis dijo «sí hay no-determinismo» porque appstream y bison divergían. También estaba mal,
y por un fallo de diseño del propio test.

`verificar-repro.sh` compara el artefacto GUARDADO contra una reconstrucción de hoy. Pero el
guardado puede tener meses: se construyó con OTRO estado del lab. El test conflaba dos cosas:
  · NO-DETERMINISMO — mismas entradas, mismo lab, salidas distintas (rompe el invariante);
  · DERIVA — el artefacto viejo no es lo que el lab de hoy produce (el mundo se movió).

LA PRUEBA QUE LAS SEPARA es construir DOS VECES HOY, y se dio sin querer: al reejecutar el
verificador sobre recetas ya reconstruidas, TODAS pasaron a reproducir.
    anew  ✗ diverge → ✓ REPRODUCE
    gron  ✗ diverge → ✓ REPRODUCE
    age   ✗ diverge → ✓ REPRODUCE   (y en la 1ª ni instalaba los mismos ficheros: faltaba age-inspect)

⇒ EL CORPUS ES DETERMINISTA HOY. Lo que hay es deriva contra artefactos viejos.

QUÉ SIGNIFICA, sin adornos:
· El argumento de reproducibilidad para el split de debug SE CAE. El split se justifica por
  ESPACIO (~60%), que sigue siendo real y grande. Nada más.
· Pero la DERIVA es un problema por derecho propio y mayor: el store contiene artefactos que el
  lab de hoy no reproduciría, así que «nuestros artefactos son verificables por terceros» es
  falso para parte del corpus — quien reconstruya no obtendrá lo publicado. `age` es el caso
  feo: la reconstrucción ni siquiera instala los mismos ficheros.
· ⇒ La reconstrucción masiva SIGUE valiendo la pena, pero por otra razón: no para arreglar el
  determinismo sino para PONER EL STORE AL DÍA CON EL LAB y que la promesa sea cierta.

Y otro hallazgo del mismo experimento: en el hub las recetas Go SÍ reconstruyen (0 fallos). Lo
que fallaba en el worker era la RED para bajar los módulos, no las recetas. Eso cambia el
bloqueante de la etapa 4: no es «Go no reconstruye», es «el worker no tiene red para módulos».

LA LECCIÓN, que es la misma tres veces en este documento: un test hay que diseñarlo contra la
PREGUNTA, no contra lo que es fácil de comparar. Comparar con lo que hay en el store es cómodo;
comparar dos builds de hoy es lo que contesta. El script queda anotado con esto en la cabecera.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 08:34:15 -04:00
sergio ca83c2ae6e estado: cosecha granja 2026-08-08T05:24:30Z — avance del árbol KDE 2026-08-08 01:24:30 -04:00
sergioandClaude Opus 5 b344c5803b etapa 4: primera tanda desplegada y verificada (3/3) + el desplegador por tandas
zstd 12M→2M (−83%) · ncurses 6M→2M (−67%) · expat 2M→1M (−50%). Cero ficheros vacíos y
**las tres REPRODUCEN**. La maquinaria de la etapa 4 queda validada de punta a punta:
activar → construir en la granja → verificar con why-differs.

LA DEP DE binutils VA EXPLÍCITA, y es la decisión de diseño de esta etapa. El paso de strip usa
`strip --strip-debug -D` de binutils. Se podría hacer que el lab lo materialice solo, sin tocar
las recetas — pero entonces la VERSIÓN de binutils sería un input INVISIBLE: dos corridas con
binutils distintos darían artefactos distintos con el mismo hash. Los `deps` sí entran en
`hash_inputs`, así que declararlo es lo único que mantiene el invariante. Cuesta una edición
mecánica por receta; el invariante no se negocia por comodidad.

EXCLUSIONES, y son exactamente dos: `binutils` y `make`. binutils provee el strip y depende de
make ⇒ activarles el split los haría necesitarse a sí mismos para construirse. No es preferencia,
es la circularidad. (Las recetas CERRADAS POR DECISIÓN tampoco se tocan.)

POR TANDAS Y NO DE GOLPE: activar re-hashea la receta a propósito y en cascada todo lo que
dependa de ella. Hacerlo sobre las 775 candidatas a la vez dejaría el corpus entero sin sellar
al mismo tiempo — días de granja antes de poder verificar NADA, y el disco aguantando artefactos
viejos y nuevos a la vez. Por tandas se mide, se verifica y se poda entre medias, que es lo que
hace la campaña reversible.

La primera tanda NO se tomó del orden alfabético que propone el script: ésas son CLIs Go/Rust
que ya vimos que no reconstruyen en el worker (necesitan red para sus módulos), y validar la
maquinaria con recetas que fallan por otro motivo no habría probado nada. Se eligieron tres
paquetes C con artefacto presente. Para las tandas grandes hay que resolver antes el acceso a
red de los módulos Go/Rust, o restringirse a lo que reconstruye.

Estado: 775 candidatas, 5 desplegadas (bison y appstream del piloto + estas 3).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 00:53:26 -04:00
sergio 0e6d84361b estado: cosecha granja 2026-08-08T04:51:57Z — avance del árbol KDE 2026-08-08 00:51:57 -04:00
sergioandClaude Opus 5 1eb469337d etapa 3: el ahorro real es ~60%, no 79% — la cifra publicada medía otra cosa
El «79%» que este plan y los SDD 19/20 venían citando era **el 79% del CONTENIDO BINARIO**,
medido sobre una muestra de .so/.a. Es cierto y es la cifra equivocada para planificar, porque un
artefacto no es sólo binarios: trae cabeceras, datos, iconos, locales, .pc y documentación, que
no encogen.

MEDIDO con `scripts/medir-debug.sh` (suma los tamaños reales de las secciones .debug_* vía
readelf -S y los compara con el tamaño del árbol, sin reconstruir nada):
    40 artefactos  ·   876 MB · 27%
   100 artefactos  ·  2955 MB · 38%   (truncada a 60 ficheros/artefacto)
   250 artefactos  ·  8874 MB · 60%   ← la que manda: sin truncar, ~7% del store

La varianza es alta porque unos pocos artefactos grandes dominan el total, así que el número
necesitaba validación independiente — y la tiene: el piloto de la etapa 2, donde se reconstruyó y
se pesó de verdad, dio bison −50% y appstream −68%. Los dos ENCIERRAN el 60% de la muestra
grande. El modelo predice lo que el rebuild produjo.

CIFRAS CORREGIDAS, con el store en 127 G:
                      se venía diciendo    medido
   reserva de disco         ~96 G          ~76 G
   store tras el split      ~30 G          ~51 G
   espejo público           ~30 G          ~51 G
Sigue siendo el mayor ahorro disponible en el proyecto —76 G no es poco— pero no es lo
prometido, y la diferencia importa para dimensionar el alojamiento del espejo, que es una
decisión con factura.

LA LECCIÓN: una cifra medida sobre una cosa (contenido binario) se citó durante semanas como si
midiera otra (tamaño de artefacto), y llegó a tres documentos. El número no era falso; LA UNIDAD
sí. Cuando un número vaya a decidir un gasto, hay que volver a la medición original y comprobar
QUÉ estaba midiendo.

Corregido en los tres sitios donde se había propagado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 00:42:08 -04:00