Commit Graph
3183 Commits
Author SHA1 Message Date
Sergio de71be94ac estado: cosecha granja 2026-09-19T11:01:26Z — avance del árbol KDE 2026-09-19 11:01:26 +00:00
Sergio d10700592f estado: cosecha granja 2026-09-19T10:31:23Z — avance del árbol KDE 2026-09-19 10:31:24 +00:00
Sergio e3ef36a478 estado: cosecha granja 2026-09-19T10:01:26Z — avance del árbol KDE 2026-09-19 10:01:26 +00:00
Sergio ec850187cc estado: cosecha granja 2026-09-19T09:31:23Z — avance del árbol KDE 2026-09-19 09:31:23 +00:00
Sergio b1b8eb00ef estado: cosecha granja 2026-09-19T09:01:23Z — avance del árbol KDE 2026-09-19 09:01:23 +00:00
Sergio bc9919ae08 estado: cosecha granja 2026-09-19T08:31:24Z — avance del árbol KDE 2026-09-19 08:31:24 +00:00
Sergio d50850304c estado: cosecha granja 2026-09-19T08:01:34Z — avance del árbol KDE 2026-09-19 08:01:34 +00:00
Sergio 563e7faf2f estado: cosecha granja 2026-09-19T07:31:23Z — avance del árbol KDE 2026-09-19 07:31:23 +00:00
Sergio f71a00876b estado: cosecha granja 2026-09-19T07:01:24Z — avance del árbol KDE 2026-09-19 07:01:24 +00:00
Sergio 29f9c3fc68 estado: cosecha granja 2026-09-19T06:31:23Z — avance del árbol KDE 2026-09-19 06:31:23 +00:00
Sergio 879393d866 estado: cosecha granja 2026-09-19T06:01:26Z — avance del árbol KDE 2026-09-19 06:01:26 +00:00
Sergio cf1052b769 estado: cosecha granja 2026-09-19T05:31:24Z — avance del árbol KDE 2026-09-19 05:31:24 +00:00
Sergio 9be8bdf332 estado: cosecha granja 2026-09-19T05:01:23Z — avance del árbol KDE 2026-09-19 05:01:23 +00:00
Sergio e4e82365a1 estado: cosecha granja 2026-09-19T04:31:23Z — avance del árbol KDE 2026-09-19 04:31:24 +00:00
Sergio a52fce2452 estado: cosecha granja 2026-09-19T04:01:25Z — avance del árbol KDE 2026-09-19 04:01:25 +00:00
Sergio ccd1f5f8a1 estado: cosecha granja 2026-09-19T03:31:22Z — avance del árbol KDE 2026-09-19 03:31:22 +00:00
Sergio 8bdafd8a6f estado: cosecha granja 2026-09-19T03:01:24Z — avance del árbol KDE 2026-09-19 03:01:24 +00:00
Sergio 40e58f1151 estado: cosecha granja 2026-09-19T02:31:22Z — avance del árbol KDE 2026-09-19 02:31:22 +00:00
Sergio 145e70900d estado: cosecha granja 2026-09-19T02:01:22Z — avance del árbol KDE 2026-09-19 02:01:22 +00:00
Sergio 7870e5ae20 estado: cosecha granja 2026-09-19T01:31:22Z — avance del árbol KDE 2026-09-19 01:31:22 +00:00
Sergio 2970fd3610 estado: cosecha granja 2026-09-19T01:01:27Z — avance del árbol KDE 2026-09-19 01:01:27 +00:00
Sergio fac9f64037 estado: cosecha granja 2026-09-19T00:31:33Z — avance del árbol KDE 2026-09-19 00:31:33 +00:00
Sergio 72745a5cbc estado: cosecha granja 2026-09-19T00:01:34Z — avance del árbol KDE 2026-09-19 00:01:34 +00:00
Sergio 9abe58d460 estado: cosecha granja 2026-09-18T23:31:34Z — avance del árbol KDE 2026-09-18 23:31:34 +00:00
Sergio 9772e466d2 estado: cosecha granja 2026-09-18T23:01:27Z — avance del árbol KDE 2026-09-18 23:01:27 +00:00
Sergio baa2fb4c3c estado: cosecha granja 2026-09-18T22:31:22Z — avance del árbol KDE 2026-09-18 22:31:22 +00:00
Sergio ebcec33ed3 estado: cosecha granja 2026-09-18T22:01:23Z — avance del árbol KDE 2026-09-18 22:01:23 +00:00
Sergio cc25d90209 estado: cosecha granja 2026-09-18T21:31:32Z — avance del árbol KDE 2026-09-18 21:31:32 +00:00
Sergio 96703f4870 estado: cosecha granja 2026-09-18T21:01:44Z — avance del árbol KDE 2026-09-18 21:01:44 +00:00
SergioandClaude Opus 5 5df1f86a0a la sesión extra moría por un BYTE 0x01 donde debía ir la retroreferencia del sed
Abrir una segunda sesión fallaba con «Error: ninguna imagen empieza por "\u{1}" — traela con hammer
qorpa pull». El `\u{1}` no era un misterio: la línea que extrae el sha de la imagen tenía un `sed`
con `\1` de reemplazo, y el fichero terminó guardando el BYTE 0x01 literal en su lugar. O sea que
`qorpa create --base` recibía el carácter de control.

Se reemplaza por un `awk` que parte por comillas: no tiene retroreferencias ni nada que otra
herramienta pueda reinterpretar al escribir el fichero. Y si la extracción sale vacía, ahora corta
con un mensaje que nombra el fichero, en vez de pasarle basura a qorpa.

Comprobado: la segunda sesión se crea y arranca (claude-sergio-3, Claude 2.1.240) con la primera
todavía abierta.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 20:54:42 +00:00
Sergio 9b222a6aa3 estado: cosecha granja 2026-09-18T20:31:55Z — avance del árbol KDE 2026-09-18 20:31:55 +00:00
Sergio b9e5423064 granja: el git del corpus no tiene remote-https — el espejo de GitHub no se empuja desde la jaula 2026-09-18 20:21:23 +00:00
Sergio fd065720f5 granja: el -i ~/.ssh/github5 de todos los scripts es un no-op — entra el fallback a id_ed25519 2026-09-18 20:20:37 +00:00
Sergio 317ce48c16 estado: cosecha granja 2026-09-18T20:01:41Z — avance del árbol KDE 2026-09-18 20:01:41 +00:00
SergioandClaude Opus 5 3b3056428f shuma-tui no encontraba a su agente: nadie exportaba XDG_RUNTIME_DIR
El síntoma era «no hay agente atendiendo» y después «arranqué shuma-daemon y en 10 s no atendió
ningún socket», con un daemon de sergio VIVO al lado. La causa: esta caja no tiene logind, así que
nadie crea /run/user/<uid> ni exporta XDG_RUNTIME_DIR, y entonces cada programa elige su propio
repliegue y dejan de encontrarse — el tui buscaba en `$XDG_RUNTIME_DIR/shuma.sock`, o sea en la nada,
mientras el daemon abría `/tmp/shuma-<uid>.sock`. Dos repliegues distintos para el mismo acuerdo.

Ahora /etc/profile.d exporta XDG_RUNTIME_DIR y la card de arranque crea /run/user/<uid> para cada
cuenta con home. Comprobado en una sesión de login de verdad: XDG=/run/user/1001, el tui levanta su
agente ahí y lista los conjuntos guardados (shuma 4 puestos, telefono-864, los diag…), que estaban en
disco y no se perdieron al reiniciarlo.

Entra también la card del volumen de trabajo —esta caja no tiene fstab y el init no monta discos
nuevos— y quedan versionados /etc/profile y los dos profile.d, que hasta ayer no los leía nadie
porque /etc/profile no existía.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 19:45:46 +00:00
SergioandClaude Opus 5 2f9253886f tres arreglos que pidió el agente de adentro, y uno era mío
1) `publicar-webs.sh` corría como root y hacía el `git pull` igual: git dejó 24 entradas de root
dentro del .git de /work/sergio/tawasuyu —refs, logs, config, directorios de objetos— y el dueño se
quedó sin poder ni hacer `fetch` («unable to append to .git/logs/refs/remotes/origin/main»). El clon
quedó congelado 21 commits atrás sin que nada fallara del lado de root. Ahora el pull va COMO EL
DUEÑO, y los cuatro clones quedaron con sus permisos.

2) `cc-por-zig.sh` elegía el rust con `ls -d …/*-rust | tail -1`, que es el último ALFABÉTICO:
certificaba `fe277b32…` mientras la jaula usaba el vigente `6441302d…`. Dos artefactos distintos, uno
certificado y otro en uso. Ahora pregunta por el hash vigente de la receta y sólo cae al más reciente
—con el nombre exacto— si no puede. Lo detectó el agente comparando los dos guiones.

3) `rustdoc` entra en `tools`: el artefacto salía con cargo y rustc y SIN rustdoc, o sea que en una
caja takana `cargo doc` no existe. `docs = false` se queda —la documentación de la std es otra
decisión, cientos de MB—. Radio medido: 0 dependientes de build.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 19:34:08 +00:00
Sergio 67f601305b estado: cosecha granja 2026-09-18T19:31:36Z — avance del árbol KDE 2026-09-18 19:31:36 +00:00
Sergio a6cefd9b5d .gitignore: /store sin barra — igual que .dev-fs, hoy es un SYMLINK
Misma causa y mismo síntoma que el `/.dev-fs` de esta tarde: `/store/` sólo ignora un directorio, y
un clon que quiera construir necesita `store -> /store` (así lo tiene /opt/takana). El enlace
aparecía como `?? store` en cada `git status`, que es ruido permanente en un repo donde varios
agentes leen ese status para separar lo suyo de lo ajeno.
2026-09-18 19:23:41 +00:00
Sergio 1a97da9839 exp-ec: tres fallos del propio arnés — sellaba basura y el veredicto no miraba el estado de salida
Los encontró la corrida en el worker, y los tres estaban disfrazados de resultado.

1. El `exit 77` se insertaba antes de la ÚLTIMA `'''` del fichero, que no siempre cierra una fase:
   una receta puede traer bloques `'''` después (un `[[service]]`, una nota larga). En `dwarves`,
   `elfutils` y `elfutils-libdw` cayó fuera de toda fase, el build corrió entero y SELLÓ — con el
   hash movido por el `set -e`, o sea tres artefactos basura. Ahora se rastrea la anidación.

2. El veredicto se leía con `grep "exit 77"` sobre el log, y takana IMPRIME el script de la fase:
   esa cadena aparece siempre porque la inyectamos nosotros. Daba SOBREVIVE hasta a un build que
   selló. Ahora se ata a `build phase falló (exit 77)`, que es el estado de salida de verdad.
   (Comprobado a posteriori que los 14 SOBREVIVE de la corrida buena sí habían salido 77.)

3. Sin `--store`, takana usa su default `/store`, que en el worker es un store de SCRATCH casi
   vacío — reconstruía el mundo en vez de reusar el de la granja (`./store`, 908 artefactos). Ahora
   el store va por `STORE`.

Y un guardián para lo que no debería volver a pasar: si un build SELLA, se clasifica
`SELLO-INDEBIDO` y se grita el hash, en vez de contarse como un resultado más. Los tres artefactos
basura ya se borraron del `/store` de scratch del worker; el store de la granja nunca se tocó.
2026-09-18 19:19:28 +00:00
Sergio 7b09e26eca jaula: los builds SÍ corren adentro — el comentario mandaba a ssh por nada
Medido desde la jaula, con el hash forzado para que no hubiera caché: `anew`
(Go, estática) sella en 6,8 s y `lz4` (C, con `make install` escribiendo /out)
en 4,4 s. Con `root = false` el bwrap anidado se levanta y /proc monta.

Lo del uid 0 sigue siendo cierto para una receta cuyo `install` fije DUEÑOS, y
así queda escrito — pero no es «los builds no corren», que es lo que se leía y
lo que mandaba a pedirle cada receta al anfitrión por ssh.
2026-09-18 19:13:35 +00:00
Sergio 785518b908 jaula: el toolchain del corpus no arrancaba adentro — faltaba el cargador musl
Los diez envoltorios daban verde porque el control se corrió EN LA CAJA, que es
musl. Adentro de la imagen de Arch, `rustc`, `cargo` y `python3` —las tres musl
DINÁMICAS— mueren con `cannot execute: required file not found`: su PT_INTERP
pide `/lib/ld-musl-x86_64.so.1` y ahí no está. `LD_LIBRARY_PATH` no puede
taparlo, actúa después de que el cargador cargue. Ahora se invoca el cargador
del lab explícitamente, y sólo si la caja no tiene el suyo: el mismo guion sirve
en los dos sitios sin ramificar.

Segundo defecto, del mismo viaje: `zig cc` a secas no sirve de `cc` para cargo.
cc-rs le pasa su propio triple y zig no lo entiende —`unable to parse target
query 'x86_64-unknown-linux-musl'`—, lo que tumba `blake3` y con él medio árbol
de tawasuyu. Los dos drivers (el de la caja y el de la jaula) lo descartan.

Las banderas de enlace van dentro del envoltorio de `rustc` y no en
/etc/profile.d: la jaula no corre shells de login, así que allá el fichero
quedaría presente, con contenido y sin efecto.

Y los controles ahora COMPILAN en vez de preguntar `--version`, que no tocaba ni
el driver de C ni el enlazador y por eso no vio ninguno de los dos defectos.

Medido con esto puesto y sin una sola variable a mano:
`cargo check -p tejido` sobre tawasuyu, verde en 1m13s.
2026-09-18 19:03:37 +00:00
Sergio 990e3ecc6b estado: cosecha granja 2026-09-18T19:02:00Z — avance del árbol KDE 2026-09-18 19:02:00 +00:00
Sergio 0f46c0976b atuq: un .pyc invisible movía el hash — el hub sellaba algo que un clon limpio no reproduce
Buscando si los cambios de atuq habían llegado a la caja apareció esto: el hub y el worker
calculaban `b3:e556024b` y un clon limpio `b3:5156cb8f`, con los 52 ficheros versionados de
`recipes/atuq/` byte a byte IGUALES en las tres máquinas y la receta con el mismo md5.

La diferencia era un fichero de más: `tools/__pycache__/rebrand.cpython-314.pyc`, bytecode que dejó
alguien al correr `rebrand.py` dentro del repo. Comprobado en los dos sentidos — metiendo y sacando
ese .pyc en un clon limpio, el hash salta de `5156cb8f` a `e556024b` y vuelve.

Lo traicionero es que `__pycache__/` está en `.gitignore`: el árbol se ve limpio en `git status`
mientras el hash ya es otro. Y el artefacto sellado en el store era el de `e556024b` — o sea uno que
un clon limpio no puede reproducir jamás. Es la regla 3 al revés: no un vacío que pasa por lleno,
sino basura invisible que pasa por fuente.

`ArtifactHash::of_tree` no sabe de `.gitignore`, y son dos cosas legítimamente distintas; pero hoy
divergen por descuido y no por decisión. Queda escrito en la receta, con la comprobación barata al
lado, para las cuatro que usan `source.dir`. El `.pyc` se barrió del hub y del worker: las tres
máquinas ya convergen en `5156cb8f`.
2026-09-18 18:52:31 +00:00
Sergio 3609b50220 exp-ec: REC apuntable a una copia — en el worker el rsync --delete borra las copias a mitad
La siembra de código hub→worker de `cosecha-cron` corre con `--delete` cada 30 minutos. Las copias
del experimento viven en `recipes/` por obligación (takana resuelve las deps relativas al directorio
de la receta), así que una tanda larga en el worker las vería desaparecer a mitad. Con `REC` se
apunta a una copia entera de `recipes/` fuera del árbol sembrado y el problema no existe.
2026-09-18 18:46:37 +00:00
Sergio 065fc4e481 exp-ec: portable al worker — el lock relativo, takana por ruta y el techo por entorno
Tres cosas mías que sólo se vieron al correrlo allá. El lock estaba cableado a `/work/.farm-build.lock`,
que es la ruta de la CAJA (donde `work` es symlink a /work); en el worker `work` es un directorio de
verdad y flock moría con `cannot open lock file`. `takana` no está en el PATH del worker, que lo
invoca por `./target/release/takana`. Y el techo de 420 s alcanza para las ligeras pero no para llvm,
firefox ni los kernels, así que ahora es `TLIMITE`.

Todas por entorno y con el valor de antes por defecto, así que la corrida de la caja no cambia.
2026-09-18 18:46:22 +00:00
Sergio 76a0f8c399 estado: cosecha granja 2026-09-18T18:31:50Z — avance del árbol KDE 2026-09-18 18:31:50 +00:00
Sergio b3500a83eb .gitignore: /.dev-fs sin barra — hoy es un SYMLINK y la barra no lo tapaba
`/.dev-fs/` sólo ignora un directorio. Desde que el lab vive fuera del árbol y se engancha con un
enlace (`.dev-fs -> /work/dev-fs`, que es como está en /opt/takana y como lo necesita cualquier clon
que quiera construir), el enlace aparecía como `?? .dev-fs` en cada `git status`. Ruido permanente
en un repo donde varios agentes leen ese status para ver qué es suyo y qué es de otro.
2026-09-18 18:17:57 +00:00
Sergio 27ec9caea0 ADR 0020: el experimento CORRIDO — 10 de 12 sobreviven a -ec, y el que cae tiene el artefacto BIEN
El diseño es la parte que vale: NO SELLA NADA. Modificar una receta le cambia el ArtifactHash, así
que medirlo a lo bruto habría dejado una docena de duplicados basura en un store que se respalda. En
vez de eso se inyecta `set -e` en cada fase Y un `exit 77` al final de la última: el build siempre
falla, nunca sella, y el veredicto se lee en el código de salida — 77 significa que todas las fases
corrieron enteras bajo set -e. Queda en scripts/farm/exp-ec.sh.

Muestra de 12 recetas ligeras (los pesos pesados quedan fuera por tiempo, y el sesgo va declarado):
10 sobreviven sin tocar nada, 1 se rompe, 1 inconcluso por timeout.

El que se rompe es `e2fsprogs`, y mirarlo de cerca cambia lo que significa: su ./configure aborta con
`external uuid library not found` pese a que la receta pasa --disable-libuuid, y hoy eso se traga
—comprobado: la misma receta sin set -e y con exit 77 LLEGA al 77—. Pero el artefacto que sella está
bien: 149 ficheros con e2fsck, mke2fs, los cuatro fsck.ext* y los mkfs.ext*. O sea que ahí `-ec` no
atrapa un bug: rompe una receta que funciona. Ése es el coste, y es el número que no se podía
adivinar leyendo: ~8%, unas 8 recetas sobre las 96 expuestas.

También se corrige el recuento: 96, no 89. El 89 salía de restar 142−53 dando por hecho que las 53
con `set -e` propio estaban todas dentro de las 142, y no lo estaban.

jaula-preparar suma lo que hizo falta para poder correr todo esto desde adentro: rsync/python3/jq/
cargo enlazados del store, y el cargador de musl, sin el cual python3 y cargo no arrancan en una
imagen glibc.
2026-09-18 18:17:42 +00:00
Sergio 6ce34e97d1 estado: cosecha granja 2026-09-18T18:01:52Z — avance del árbol KDE 2026-09-18 18:01:52 +00:00
SergioandClaude Opus 5 afdc4ffb9b el toolchain de la jaula sale del CORPUS, no de pacman
El agente de adentro reportó que le faltan cargo, rustc, make, pkg-config y python3. La salida obvia
—sumarlos a `packages` y `qorpa provision`— hoy NO funciona: con un mapa de un solo id, pacman no
puede chownear su directorio de descarga y muere en «failed to chown temporary download directory»,
que es exactamente la consecuencia que el aviso de qorpa viene anunciando.

Y no hace falta: las diez herramientas YA están selladas en el store, son musl estáticas y corren
dentro de la imagen glibc. Usarlas es además lo coherente con la distro —el corpus es el que provee,
no Arch—. Quedan como envoltorios en /work/<usuario>/bin, que el lanzador pone en el PATH junto con
el go y el zig del lab.

Dos errores míos que el propio control destapó y quedan escritos: el glob `/store/*-make` también
casa con `…-cargo-make` (eligió ése y `make` moría en un `exec` que no nombraba la causa) — ahora el
nombre se compara entero quitándole el hash; y el control daba ✓ a todo porque `cmd | head` devuelve
el estado de head, o sea siempre 0.

Probadas las diez: make 4.4.1, pkgconf 2.5.1, python3 3.12.10, jq 1.8.1, rsync 3.5.0, git 2.54.0,
curl 8.20.0, takana 0.0.1, rustc y cargo 1.97.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 17:58:58 +00:00