Commit Graph
1929 Commits
Author SHA1 Message Date
Sergio e831a0fabc estado: cosecha granja 2026-09-18T06:01:29Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 36b295e0af estado: cosecha granja 2026-09-18T05:31:23Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio a2e10814c3 estado: cosecha granja 2026-09-18T05:01:23Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio fc429dcce2 estado: cosecha granja 2026-09-18T04:31:20Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio c1fa58362d estado: cosecha granja 2026-09-18T04:01:24Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 41519cd2f9 estado: cosecha granja 2026-09-18T03:31:21Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 1955b1ddac estado: cosecha granja 2026-09-18T03:01:23Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio ff999ed3c1 estado: cosecha granja 2026-09-18T02:31:22Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio a128d987c9 estado: cosecha granja 2026-09-18T02:01:22Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 4c0f32ed9d estado: cosecha granja 2026-09-18T01:31:22Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 51b61141c6 estado: cosecha granja 2026-09-18T01:01:22Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 4de64c7c77 estado: cosecha granja 2026-09-18T00:31:23Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio a8a148912a estado: cosecha granja 2026-09-18T00:01:22Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 1f6ed096ae estado: cosecha granja 2026-09-17T23:31:23Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 87446e5e57 estado: cosecha granja 2026-09-17T23:01:23Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio d7b7e288ed estado: cosecha granja 2026-09-17T22:31:26Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
Sergio 65b2469808 estado: cosecha granja 2026-09-17T22:01:24Z — avance del árbol KDE 2026-09-18 13:12:21 +00:00
SergioandClaude Opus 5 2fafb3a589 atuq: el vigésimo guardián entra a la suite, y entra TRUNCADO — con el motivo escrito al lado
`test-atuq-boveda-metal --hasta A` pasa a correr con los otros diecinueve. Corre truncado a propósito:
las etapas B..F chocan contra el muro del §7.septies —ninguna app llimphi de escritorio abre ventana
sin Vulkan— que no es de la bóveda, y un rojo permanente por una causa ajena se aprende a ignorar en
tres días. Lo que la A afirma es la medición que costó tres semanas de no ver: **sin la app dueña, el
host contesta `locked:true` con `ok:true`**, o sea que «cerrada» es una respuesta exitosa.

La cabecera del runner dice ahora 20 y avisa que un verde de éste NO dice que la bóveda ande. Es la
misma advertencia que ese fichero ya se aplicó dos veces: un número escrito como predicción envejece
callado, y un cuadro entero en verde puede ser un producto sano o un runner que no mide nada.

Probado en los dos sentidos, que es lo único que distingue un guardián de una decoración:
· en verde, 3 s, dentro del runner y sobre el sello vigente (`b3:e556024b`);
· ROJO con una rotura a propósito —invertir la aserción de la etapa A— ⇒ salida 1.

Y el tamaño que faltaba para la decisión del §7.sexies: `boveda` 22 M y `shuma-pregunta` 21 M, ~43 M
por perfil. Hoy la respuesta a «en qué imágenes se declaran» es NO, y no por el tamaño: declararlas
antes de que llimphi se destrabe sería instalar una bóveda que niega todo sin un error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 10:50:18 +00:00
SergioandClaude Opus 5 f611751f86 atuq: el diálogo de la bóveda no abre, y el muro no es de la bóveda — ninguna ventana llimphi pinta
`boveda` (b3:59ffd74b) y `shuma-pregunta` (b3:99763eca) sellaron en el worker. Ninguno de los dos abre
ventana, y el error no habla de contraseñas:

    panicked at llimphi-hal/src/lib.rs:1032: index out of bounds: the len is 0 but the index is 0

Esa línea es `caps.formats[0]`: la surface no tiene NI UN formato. La cadena, medida eslabón por
eslabón con RUST_LOG=wgpu_hal=debug:

    No (or unknown) windowing system ((None, Some(..))) present. Using surfaceless platform
    Trying native-render → No config found! · Trying presentation → No config found!

El `None` es `raw_display_handle`, y no es del arnés: es lo que llimphi hace A PROPÓSITO en su camino
de escritorio, con el comentario al lado («Sin display: este camino no tiene ventana todavía»). Sin
display handle wgpu abre el display EGL surfaceless, que no publica configs con WINDOW_BIT ⇒ la
surface no es presentable ⇒ cero formatos ⇒ panic.

No se nota en una máquina con Vulkan, porque ese camino elige Backends::PRIMARY y a Vulkan el display
no le hace falta. Y **ninguna imagen de takana tiene Vulkan**: las tres recetas de mesa se compilan
con `-Dvulkan-drivers=` vacío, y `vulkan-loader` sólo existe en incoming-kde sin que ningún perfil lo
declare (y un loader sin driver no es un driver). ⇒ toda app llimphi de escritorio cae al camino GL y
no puede abrir ventana. Reproducido en TRES binarios y dos versiones de wgpu: shuma-pregunta y boveda
(29) y llimphi-counter (27).

Los controles, porque la conclusión es fuerte: pedir Vulkan explícito da NoAdapter y no hay ICD ni
libvulkan en ninguna capa (la premisa está medida); con softpipe el fallo es OTRO y anterior —wgpu
pide compute shaders y softpipe se queda en GL 3.3—, así que llegar hasta acá ya exige llvmpipe; y el
compositor está levantado con su socket y su WAYLAND_DISPLAY.

Lo que esto dice del producto: el consentimiento de la bóveda no puede pedir permiso en ninguna imagen
de hoy, y como un lanzamiento fallido se traduce a «no» (Command::new falla ⇒ return false), el usuario
vería una bóveda que niega todo sin un solo error.

Se arregla en llimphi (que pase el display handle; la función `instancia_con` ya existe ahí al lado) o
con un driver Vulkan por software en el corpus. No se arregla en takana ni en el arnés.

Entra igual lo que sí se puede afirmar:
· `scripts/test-atuq-boveda-metal.py`, seis etapas declaradas, la A en VERDE — sin la app dueña el
  host contesta locked:true, que es la medición del §7.sexies ahora vigilada. Cada etapa dice qué
  afirma y la B nombra el muro en vez de dejar que se rediagnostique;
· `recipes/wtype.toml` — el corpus no tenía NINGUNA forma de meter una tecla en un compositor: todos
  los arneses de scripts/wlr miran, ninguno toca. Sellado y en ningún perfil: es instrumento.

⚠ Y una trampa del arnés, mía, que costó tres corridas: exportaba GALLIUM_DRIVER=softpipe, o sea que
yo mismo lo clavaba al driver débil. mesa-swrast y mesa-llvmpipe se ven como dos nombres de lo mismo
—«mesa por software»— y la diferencia decide si el arnés existe.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 10:48:06 +00:00
SergioandClaude Opus 5 589c656262 atuq: la bóveda del navegador contesta CERRADA — faltaban el dueño y el diálogo, no el guardián
El §7.quinquies.bis cerró la unidad 12 diciendo que el guardián de METAL «ahora sí se puede escribir
porque hay con qué correrlo». No se podía, y la primera pregunta que ese guardián iba a hacer lo dice
en veinte segundos, contra el artefacto sellado y por marcos de 4 bytes:

    ← {"id":1,"ok":true,"verb":"ping","version":"0.1.0"}          ← el control: el host ESTÁ
    ← {"id":2,"ok":true,"verb":"vault.status","locked":true,...}
    ← {"id":3,"ok":true,"verb":"vault.match","locked":true,"items":[]}
    stderr: puriy-costura: sin bóveda (No such file or directory): los verbos vault.* dirán «cerrada»

Lo que engaña es el `ok:true`: **«cerrada» es una respuesta exitosa**, así que ningún log, ningún
reintento y ninguna insignia la distinguen de un usuario que todavía no desbloqueó la suya. Hoy, en
las cuatro imágenes de escritorio, atuq instala la décima extensión y la función está apagada.

Las dos mediciones del §7.quinquies eran correctas y lo siguen siendo —`strings` da `vault` 10 veces,
`vigia-atuq-verbos` da cero verbos sin dueño—, pero las dos preguntan si el host CONOCE el verbo.
Ninguna pregunta quién contesta del otro lado del socket: el host no abre la bóveda nunca, a propósito
(sled toma un lock exclusivo y el proceso que lanza el navegador muere con cada pestaña), así que le
habla a un DUEÑO — y el dueño no estaba en el corpus. Saber el verbo no es poder contestarlo.

Entran las dos piezas que faltaban, las dos con el mismo efecto de «se ve apagado y nada falla»:
`boveda` (pacha-boveda-llimphi, el dueño único de la base, que levanta el socket del navegador) y
`shuma-pregunta` (el diálogo que lanza `PorDialogo`; sin él `Command::new` falla y **todo vault.fill
se deniega**, indistinguible de que el usuario haya dicho que no).

Las dos pineadas al MISMO 23a292863 que ya comparten puriy-costura, shuma-* y pacha-* —un pin
distinto es otro vendoreo de 2,4 G— y con la forma de mirada-greeter, que es el patrón de una llimphi
GUI: link dinámico (winit/wgpu dlopean EGL/Vulkan/wayland) y la inyección de LOCKSTEP_XML_PATH que
evita el panic de zbus-lockstep-macros en el subdir xml/schemas/ de atspi.

⚠ El sello TODAVÍA NO ESTÁ: las dos están encoladas en el worker detrás del build de rust, bajo
`flock -o`. Hasta que sellen, estas recetas son una hipótesis escrita, no un artefacto medido.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 10:17:38 +00:00
SergioandClaude Opus 5 a170885357 las proc-macros SÍ se pueden compilar en la caja: falta un cc, no un parche
Con rust sellado, la caja compila estáticos sin tocar nada, pero ninguna dylib —y eso incluye todas
las proc-macros—. El `-L /usr/lib` obvio EMPEORA las cosas: rompe los estáticos, porque rustc enlaza
musl static-PIE con su copia self-contained y ese camino le hace preferir la libc.a del sistema, que
no es PIC. Cuatro controles lo aíslan y el error nombra al culpable (`__malloc_size_classes`). O sea
que ningún RUSTFLAGS global sirve: apaga un caso y enciende el otro.

Quien distingue los dos casos es un driver de C. La caja no tiene gcc ni clang —clang18 en el store
son sólo cabeceras—, pero sí tiene zig: el artefacto seed-zig del bootstrap trae zig 0.16.0 y corre.
Con `cc → zig cc` y `-C linker=cc -C linker-flavor=gcc -C link-self-contained=no` la cadena completa
funciona: la proc-macro enlaza, el programa que la usa compila e imprime, y el estático sigue bien.
Las tres banderas son necesarias; la variante fina `=-linker` es inestable en este triple.

Lo que queda es una decisión, no trabajo: seed-zig no tiene receta —es producto del bootstrap—, y
volverlo el `cc` del sistema es elegir el compilador de C de la distro.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 10:08:11 +00:00
SergioandClaude Opus 5 67e61583fe estado: gcc-libs re-sellada con libgcc.a y el corpus sigue en CERO deuda
La cascada que temíamos no existía: los cinco consumidores declaran gcc-libs en `runtime`, que está
fuera de hash_inputs, así que ninguno se re-hasheó. 938 selladas, 3 ajenas, 0 en deuda, y las cinco
imágenes al 100 %.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 01:49:19 +00:00
SergioandClaude Opus 5 096c426b13 estado: CERO deuda — las cinco imágenes cierran al 100 %
rust selló en el worker (b3:6441302d…, 352 M, 17m47s de build), y con eso no queda ninguna receta en
deuda ni sin construir: base 74/74, cli 142/142, escritorio-mirada 41/41, metal-tigerlake 7/7 y
servidor 175/175.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:34:23 +00:00
SergioandClaude Opus 5 3b5330b1cd estado: el metal cierra 7/7 y sólo queda rust en deuda
linux-firmware sella por primera vez (1,9 G, 4885 ficheros y los 2415 enlaces de WHENCE),
wireless-regdb entra al corpus y firmware-tigerlake deriva sus 55 blobs (wifi=28, i915=15, sof=10).
Con eso `metal-tigerlake` pasa de 2/6 a 7/7 y `cli` sigue en 142/142.

937 selladas, 3 ajenas, 1 en deuda: rust.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:33:07 +00:00
Sergio d05fbbd931 estado: cosecha granja 2026-09-17T21:31:27Z — avance del árbol KDE 2026-09-17 21:31:28 +00:00
SergioandClaude Opus 5 36c3634542 estado: 934 selladas — zsh entra y cli cierra 142/142
Regenerado tras sellar zsh estático y traer del store de la caja los tres artefactos que sólo vivían
allá (intel-ucode, sof-firmware, linux-generic; verificados por huella de contenido, no por `du`, que
cuenta directorios y difiere entre sistemas de ficheros).

Quedan tres: linux-firmware (nunca construida, bloquea a firmware-tigerlake) y rust en deuda.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:25:58 +00:00
Sergio 13e3d9e367 estado: cosecha granja 2026-09-17T21:01:24Z — avance del árbol KDE 2026-09-17 21:23:32 +00:00
SergioandClaude Opus 5 5d16b55e14 el visor del grafo reventaba con un estado que no conocía
`build-state-view.py` traía los cuatro estados del corpus cableados (sealed/debt/never/unhashable) y
contaba TODOS los nodos contra ese diccionario. `build-state.py` emite dos más —`wanted` (hueco
declarado en targets.toml, sin receta) y `ajeno` (imagen de qorpa, que no se construye desde
fuente)—, así que el visor moría con `KeyError: 'ajeno'` y el tablero HTML llevaba sin poder
generarse. O sea: agregar un estado nuevo rompía el tablero entero, en silencio para quien no lo
corriera.

Ahora los de fuera del corpus se cuentan aparte y se NOMBRAN en la leyenda —no se cuelan a la barra,
que es sobre `totals["recipes"]` y pasaría del 100 %—, y cualquier estado que aparezca mañana cae en
esa misma rama en vez de tumbar el visor.

De paso, el grafo regenerado: 930 selladas, 2 en deuda, 5 nunca, 3 ajenas; git ya figura sellado en
su hash nuevo (b3:215742cb…) y no arrastró a nadie, como decía el radio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:00:40 +00:00
SergioandClaude Opus 5 d4896c2999 pagada la deuda: el git del corpus vuelve a clonar por HTTPS
El §6.50 quinquies dejó la caja trayendo fuentes por SSH porque su git no tenía remote-https. Eso era
el síntoma; la causa estaba un paso antes de donde mirábamos —incluida la nota que yo mismo había
escrito, que culpaba al Makefile—: el `configure` de git prueba libcurl con AC_CHECK_LIB, que enlaza
`conftest.c -lcurl` y nada más, y con libcurl estática faltan sus privadas (-lssl -lcrypto -lz).

El test falla, config.mak.autogen se lleva NO_CURL=YesPlease, el Makefile excluye los tres helpers y
conserva git-http-backend —esa asimetría en el artefacto era la firma, y estuvo a la vista desde el
14 de septiembre—. El build termina en verde.

Medido sobre el artefacto: b3:215742cb… trae git-remote-http, -https, git-http-fetch y los ftp, y
CLONA por HTTPS (clone, no ls-remote). En la caja, hidratado y con la reescritura apagada, funcionan
tanto `git clone` como `git clone --mirror`, que es el comando exacto del fetch de takana.

Y el radio, medido en vez de temido: la nota vieja decía «raíz de perfil.base ⇒ radio grande»;
`yupana radio git` dice cero dependientes directos y cero transitivos. El miedo escrito a mano había
sobrestimado el costo de arreglarlo, y eso lo mantuvo roto tres días.

Las reescrituras url.insteadOf quedan retiradas de la caja; el guion se conserva como salida de
emergencia y así lo dice su cabecera.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 20:52:47 +00:00
Sergio 51e9f885f9 estado: cosecha granja 2026-09-17T20:32:16Z — avance del árbol KDE 2026-09-17 20:32:16 +00:00
Sergio b6f885619b estado: cosecha granja 2026-09-17T20:02:36Z — avance del árbol KDE 2026-09-17 20:02:37 +00:00
SergioandClaude Opus 5 32fea6c25a el control que cierra el ssh: la caja construyó una receta de tawasuyu de punta a punta
puriy-costura era la única de las 36 que NO estaba en el store de la caja —o sea, un fallo de caché
de verdad, no un cache-hit disfrazado de éxito—. La caja la hizo entera y sola: clonó por SSH
(111,7 M de mirror), vendoreó, compiló y selló.

El hash que predice el hub y el que selló la caja son IDÉNTICOS
(b3:7d63655aa5fea3cbc08724887617d7f58b325fcb2e00ac050b1937966c2459e6), que es lo único que prueba que
el transporte no contamina el artefacto; 2,2 M con contenido y el binario corre.

Con esto la caja cumple la condición que puso el usuario para poder borrar gioser —«con capacidad de
compilar tawasuyu y las recetas de takana»— desde FUENTE y por su cuenta, no por artefactos que le
llegan del worker. Los dos negativos del guion también están probados: un repo inexistente lo hace
fallar, y una huella cambiada la rechaza.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 19:47:20 +00:00
SergioandClaude Opus 5 8d1e765bf7 las fuentes git se traen por ssh — y la raíz de 5,9 G tiró la caja entera
La caja no tiene git-remote-http, así que las 36 recetas que clonan de git.tawasuyu.net y las ~90 de
GitHub no se podían construir ahí. La salida es usar SSH, y sale gratis en hashes porque la URL es un
LOCALIZADOR y no entra en hash_inputs (ADR 0013): mismo commit por otro transporte, mismo artefacto.
No se toca ninguna receta —el worker sigue por HTTPS— sino la caja, con dos `url.insteadOf`.

Tres cosas medidas: (1) cargo vendor clona aparte y con su propio cliente ssh —se plantó por la clave
del host, que la tenía con puerto y cargo la busca sin él, y después por autenticación— y se resuelve
con `net.git-fetch-with-cli = true`; (2) la huella de github.com se PINEA contra la publicada, no se
acepta a ciegas; (3) CARGO_HOME estaba en /root/.cargo, o sea en la raíz de 5,9 G: el vendor bajó
2,7 G, la raíz llegó al 100 % y la caja NO se degradó, se cayó entera —sin HTTP, sin SSH y sin
responder al ping, con Hetzner informando «running»—. Rescate otra vez.

Rastro que deja un ENOSPC y que conviene saber leer: caddy escupiendo «no space left on device», y
mis propios `>>` dejando 105 bytes NULOS al final de /root/.ssh/config —un append que falla por
ENOSPC no deja el fichero como estaba: lo deja extendido y relleno de ceros—.

Reparado en el rescate y permanente: /root/.cargo → /work/cargo-home, poda horaria de logs
(ente-gitea.log había llegado SOLO a 114 M y nadie lo rotaba) y los dos configs reescritos. Tras el
arranque: raíz al 54 %, 18 entes corriendo, los 7 dominios de la caja en 200.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 19:33:38 +00:00
SergioandClaude Opus 5 f13f4f542d cómo se instala software de tawasuyu en la caja — y por qué no con actualizar-servidor.sh
`install-tawasuyu.sh` y `actualizar-servidor.sh` existen y siguen ahí (el monorepo está clonado en
/work/sergio/tawasuyu), pero lo que hacen es `cargo build --release` + `install -m755` a
/usr/local/bin: producen exactamente la clase de binario que la mudanza encontró irreproducible —2,7
G de sueltos que nadie provee, tres de ellos corriendo desde un inodo BORRADO— y además escriben
servicios en /etc/init.d/, que en esta caja no existe.

La forma de acá, hecha de punta a punta con shuma-tui: receta pinneada ⇒ `takana build` ⇒ sellado
b3:f795ee0f… ⇒ el artefacto viaja por rsync ⇒ symlink desde el store ⇒ `shuma-tui --help` contesta.
El camino completo es el del §6.46 (repo firmado + `takana install --require-signed`), que es lo que
convierte «copiar un binario» en «instalar un paquete».

⚠ Y el límite de hoy: el build NO se puede hacer en la caja para recetas que clonan por HTTPS,
porque su git no tiene remote-https. Las que bajan tarballs con curl sí construyen ahí (hoy sellaron
intel-ucode y sof-firmware); las de tawasuyu se construyen en el worker. Arreglarlo es re-sellar
`git` con libcurl, raíz de perfil.base: unidad propia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 19:10:26 +00:00
Sergio 53f33c3d9f estado: cosecha granja 2026-09-17T19:01:18Z — avance del árbol KDE 2026-09-17 19:01:18 +00:00
Sergio 9f9a4c3487 estado: cosecha granja 2026-09-17T18:31:19Z — avance del árbol KDE 2026-09-17 18:56:07 +00:00
Sergio f9fca5f1e5 estado: cosecha granja 2026-09-17T18:05:02Z — avance del árbol KDE 2026-09-17 18:56:07 +00:00
SergioandClaude Opus 5 c8ac57d46e sudo repuesto y el taller de trabajo: dónde se programa en la caja
sudo no andaba por DOS cosas a la vez, y una era el corte de energía: /usr/bin/sudo no tenía el bit
setuid, y /etc/sudoers.d/sergio HABÍA DESAPARECIDO — lo escribí minutos antes del reset del §6.51 y
se fue con el mismo corte que dejó el cortafuegos en NULs. Repuestos los dos, con sync, `sudo id`
devuelve uid=0. `visudo` no está instalado y no hace falta: el drop-in en /etc/sudoers.d/ es la forma
correcta. (doas sigue dando «Operation not permitted» aun setuid; queda como rareza sin explicar.)

LOS REPOSITORIOS ESTÁN EN LA CAJA: los 44 en el gitea mudado el 14-sep (sergio 939 M, tawasuyu
547 M). Lo que faltaba era un CLON DE TRABAJO: sólo estaba /opt/takana, el del hub. Ahora
`~/src → /work/sergio` con tawasuyu clonado (478 M) y su origin al gitea de la caja.

⚠ El taller va en /work y no en el home: la raíz tiene 2,4 G libres y /work 43 G.
⚠ Y clonar acá tiene dos trampas medidas: el git del corpus NO tiene remote-https (no se puede
clonar por HTTPS), y clonar por SSH exige la llave registrada en la CUENTA de gitea, no en el
authorized_keys del sistema. Mientras tanto se clona por ruta del sistema de ficheros, como root
(los dirs de organización son 0700 de gitea) y con `safe.directory`.

`PROY=/work/sergio/tawasuyu claude` abre el agente sobre ese repo — comprobado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 18:49:59 +00:00
SergioandClaude Opus 5 8db55db465 la cuenta necesitaba sus LLAVES, no su contraseña
El primer `ssh -i ~/.ssh/tawasuyu sergio@gioser.net -p 2345` dio «Permission denied (publickey)», y
era exacto: el sshd de la caja tiene `PasswordAuthentication no`, así que la clave sirve para `su` y
la consola, no para SSH. Faltaba `~/.ssh/authorized_keys`, que se creó vacío con la cuenta. Copiadas
las dos llaves de gioser (`tawasuyu` y `sergio@tatata`), entra — y `claude` abre en la misma sesión.

Dos detalles que hacen que se sienta como la máquina de siempre: `gioser.net` ya resuelve a la caja,
y la llave de host es LA MISMA que la de gioser (se copiaron en el cutover del gitea, §6.25),
comprobado: SHA256:ltSl+rgr2Uc… en las dos. Por eso no salta el aviso de «REMOTE HOST IDENTIFICATION
HAS CHANGED» al entrar al nombre de siempre.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 18:37:52 +00:00
SergioandClaude Opus 5 a3e891a601 me dejé afuera de la caja: 20 minutos caída, y las tres causas encadenadas
Crear una cuenta tiró el servidor. Ninguna de las tres causas era la que parecía:

1. La caja NUNCA tuvo /etc/shadow. Crearlo con todas las cuentas bloqueadas (!) hizo que sshd
   RECHAZARA LA LLAVE de root: este sshd no acepta login por llave de una cuenta bloqueada. La forma
   correcta acá es la vieja — el hash en el campo 2 de /etc/passwd, sin shadow.
2. La caja NO reinicia por ACPI: `hcloud server reboot` no hizo nada (arje-zero no atiende la señal).
   La única forma de reiniciarla desde fuera es `reset`, que es un corte de energía.
3. Y ese corte dejó el reglaset del cortafuegos a MEDIO ESCRIBIR — 5 KB de NULs: ext4 journaló el
   tamaño y los datos nunca llegaron al disco. Un fichero medio escrito con `policy drop` y sin los
   `accept` es exactamente una caja que arranca, corre todo y no deja entrar a nadie.
   ⇒ después de escribir algo que el arranque necesita, `sync` ANTES de cualquier reset.

Lo que el rodeo destapó y vale más que el susto:
 · EL CORTAFUEGOS NO SE APLICABA EN NINGÚN ARRANQUE (su card sale 78 si nft -c falla, y con el
   fichero corrupto fallaba siempre): la caja llevaba días arrancando SIN FILTRAR, en silencio.
   Reparado, el arranque ya deja 21 reglas dport, comprobado tras reiniciar.
 · netup es DHCP-only y falló dos veces; se le añadió al init una IP estática de respaldo con la
   forma de Hetzner (/32 + puerta scope link)… que no corría, porque su guarda miraba /sys y el init
   NO MONTA /sys. El diagnóstico que lo probó hubo que escribirlo a FICHERO: sin red, el log tiene
   que estar en el disco.
 · el mapa real de particiones: sda2 root · sda3 state · sda4 work · sdb store.

El costo, sin adornos: ~20 minutos de caída de los ocho dominios y tres resets duros, uno de ellos
disparado por mí a los 400 s mientras la caja estaba haciendo su trabajo. En esta caja cada
diagnóstico remoto cuesta un ciclo de 6-8 minutos: el primero conviene gastarlo en dejar evidencia
en disco, no en probar una corazonada.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 18:32:27 +00:00
SergioandClaude Opus 5 eb96c9219e el agente corre en la caja y puede construir — la condición que el usuario puso para borrar gioser
$ claude -p "Decí exactamente: CLAUDE CORRIENDO EN LA CAJA"
  CLAUDE CORRIENDO EN LA CAJA

Turno real —API, credenciales, respuesta— desde 2.29.29.217. El CLI es un ELF glibc de 360 M y la
caja es musl, así que va enjaulado (ADR 0015, el caso de sergioh-api). La instancia declara red,
nesting y SEIS directorios: /opt/takana, /work/dev-fs, /store, /root/.claude, /root/.ssh (ro) y el
CLI (ro). Es ANCHA y está dicho: un agente que construye, commitea y empuja necesita lo mismo que un
humano; lo que la jaula compra es que el alcance esté escrito y acotado.

⚠ El `takana` que construye NO se instala adentro: sale del store, que ya está concedido — es
estático musl y corre igual dentro de una imagen glibc.

LA CAJA CONSTRUYE: sellados hoy `intel-ucode` (156 signatures) y `sof-firmware` (2 firmware + 8
topologías). Faltaba una pieza que el lab no traía: `.dev-fs/tools` (zig 0.13/0.16 y go, 1 G) — la
imagen del lab empaqueta `alpine/` y nada más, y el primer intento murió con «zig no encontrado».

🧱 Y lo que NO anda, con su rodeo: `takana build` dentro de la jaula muere con «bwrap: Can't mount
proc on /proc» aunque `nesting = true`. No es el anidamiento —un `bwrap --proc /proc` a mano SÍ
funciona adentro— sino el userns anidado del sandbox del build; probado también con `root = false`,
que es la sospecha que el propio código documenta, y falla igual. El rodeo que sí anda, escrito en el
lanzador: pedirle el build al ANFITRIÓN por ssh a 127.0.0.1:22022. Así se selló sof-firmware desde
dentro de la jaula.

Manifiesto y lanzador versionados en scripts/servidor/: una instancia que sólo existe en la caja se
pierde con la caja.

⚠ Pendiente menor: la memoria del agente está en `-mnt-vvv-takana` y allá el repo vive en
/opt/takana ⇒ el índice POR RUTA no coincide y arranca sin memoria del proyecto aunque los 733
ficheros estén en disco.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 17:34:56 +00:00
Sergio b3f0987677 estado: cosecha granja 2026-09-17T17:31:22Z — avance del árbol KDE 2026-09-17 17:31:23 +00:00
SergioandClaude Opus 5 7295106943 lo único que queda de la mudanza son 150 decisiones sobre datos — y el último rescate
Con las ocho puertas en verde no queda trabajo técnico: queda decidir. La hoja
(`docs/state/mudanza-decisiones-pendientes.txt`) trae 150 entradas y 31,9 G, ordenadas por tamaño,
con la sugerencia entre corchetes cuando hay un HECHO que la respalde y en blanco cuando sólo lo
sabe el dueño. Se aplica en una pasada con `planear.py --decidir`, sin teclas unitarias.

Y el último rescate antes de cerrar: `/mnt/vvv/gioserv` tenía 26 entradas sin commitear y su remoto
era una RUTA LOCAL de la máquina que se borra. Lo commiteado está a salvo (su HEAD es el mismo que
el del gitea nuevo); lo que no estaba en ningún lado —el diff completo, con `api/main.py` +92/−23, y
los 4 no rastreados— quedó en takana:/work/mudanza-secretos/gioserv-pendiente/, verificado con 0
ficheros faltantes. No reapunté el remoto ni commiteé nada: eso es del dueño del repo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 17:06:19 +00:00
SergioandClaude Opus 5 d581c2c519 la hoja final: 150 entradas y 31,9 G que sólo puede decidir el usuario
Con las ocho puertas en verde, lo único que queda de la mudanza son decisiones sobre datos. Esta
hoja las junta todas, ordenadas por tamaño, con lo que la herramienta se anima a sugerir POR UN
HECHO entre corchetes (servido / usado por un proceso vivo / caché / repo limpio con remoto) y en
blanco lo que sólo sabe el dueño.

Se decide editando el fichero y aplicando en una pasada:

  python3 scripts/mudanza/planear.py --censo work/mudanza/censo-detalle.toml \
    --decidir docs/state/mudanza-decisiones-pendientes.txt --target root@2.29.29.217

⚠ Y dice qué NO cubre, porque una hoja titulada «lo que falta» que omite 329 G se lee mal: no están
`/mnt/vvv` (monorepo, repo, store, rustup — el store ya está respaldado y los repos viven en el gitea
de la caja) ni los servicios y dominios, que ya están decididos y ejecutados.

Va a `docs/state/` y no a `work/`, que está en .gitignore: el fichero donde el usuario decide no
puede vivir sólo en la máquina que la mudanza borra.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 17:05:54 +00:00
Sergio 424ad38e71 estado: cosecha granja 2026-09-17T17:01:02Z — avance del árbol KDE 2026-09-17 17:01:02 +00:00
SergioandClaude Opus 5 35fed3aa65 PUERTA 7 EN VERDE: el respaldo corre desde la caja — LAS OCHO PUERTAS ESTÁN EN VERDE
respaldados (manifiesto del Storage Box): 3686
  en el store de la caja: 1320
  de la caja, NO respaldados: 0        ← la cuenta que decide
  errores y reintentos: 0 y 0

Pero la primera corrida no terminó, y el motivo vale por sí solo: se cayó 40 veces con el MISMO
fichero porque una transferencia interrumpida el 11-sep había dejado un parcial en el destino con el
modo del origen (-r--r--r--, el store es de sólo lectura por diseño). Ningún intento posterior puede
reescribirlo: esa ruta quedaba envenenada PARA SIEMPRE, y el bucle la golpeaba cada 60 s llamándola
«corte de red». Arreglado con --chmod=Fu+w (un corte a mitad se retoma) y dando al rsync 23 tres
intentos en vez de cuarenta, nombrando la causa probable al tercero.

🪤 Y dos veces el mismo error mío en la misma tarde: `pgrep -f <patrón>` SE ENCUENTRA A SÍ MISMO —el
patrón está en la línea de comando del propio pgrep y del ssh que lo lanza—, así que «sigue
corriendo» era verdad para siempre y el vigía que armé con esa condición nunca podía dispararse. La
forma correcta es el truco del corchete: `grep "[r]espaldo-storagebox"`. Hermano del `pkill -f` que
mata tu propia shell.

Lo que separa esto del borrado de gioser ya no es técnico: es la decisión del usuario, a mano y
nunca por automatización.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 16:58:47 +00:00
Sergio bd81af9a18 estado: cosecha granja 2026-09-17T16:31:10Z — avance del árbol KDE 2026-09-17 16:31:11 +00:00
SergioandClaude Opus 5 c79c7aa9be las ocho puertas al cierre del día: siete en verde y una corriendo
2 store entero           1320 artefactos, 0 vacíos, /store al 62 % tras el gc
  4 la granja late allá    §6.43 — con el lab pineado, y la caja gana por uno en los dos grafos
  5 el host se instala de su repo  §6.46 — 171 publicados, install --require-signed en verde
  7 el respaldo desde la caja  primera corrida completa en marcha
  1,3,6,8 

Lo que separa esto del borrado de gioser ya no es técnico: es la corrida de respaldo terminando y la
decisión del usuario — a mano, con las ocho en verde, nunca por automatización. Y lo que queda vivo
en gioser es trabajo de la mudanza, no servicios: los ~10 G de árboles personales sin decidir.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 16:09:04 +00:00
SergioandClaude Opus 5 ef2f9391d9 puerta 5 verde: la caja publica su repo firmado y se instala de él
Estaba a medias desde el §5.4 por el lab. Con el lab instalado (§6.43), cerrada en dos movimientos,
los dos en la caja:

  publicar: 171 paquetes con expected_hash anclado, 3 sin ancla, índice verificado contra ./trust,
            firmado con la clave de release que se mudó el 16-sep. Falló uno: os-release.
  instalar: `takana install duf --require-signed --trust ./trust` ⇒ «release: trusted (by release)»,
            deps resueltas, apply OK, registrado. Bajo --prefix y --db propios, sin tocar el sistema.

⚠ El matiz honesto vale más que el verde: el artefacto YA ESTABA en el store, así que se ejercitó
resolver + verificar firma + hidratar, NO reproducir desde fuente. Lo que el lab destrabó y sí quedó
probado aparte es el HASH (§6.43, cuatro de cuatro iguales a gioser), que es donde moría antes. Queda
sin ejercitar «paquete que no está en el store» — y en una caja de producción es discutible que se
quiera: un servidor no tiene por qué compilar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 16:05:56 +00:00
Sergio 46f60b4bd2 estado: cosecha granja 2026-09-17T16:01:09Z — avance del árbol KDE 2026-09-17 16:01:09 +00:00