`command -v cc gcc clang zig` en la caja no devolvía nada. Eso no es sólo incómodo: es lo que hacía
que rustc, con el compilador propio ya sellado, no pudiera enlazar una sola dylib —y ahí entran 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. El camino de librerías no puede ser global; quien sabe cuál es cuál es un driver de C.
NO introduce nada nuevo en el corpus: envuelve el `seed-zig` que ya está en el store —producto del
bootstrap, como stage1-rootfs—. Volver a zig el compilador de C OFICIAL de la distro sería otra cosa,
y es decisión de ADR. La caché de zig va a /work y no a la raíz de 5,9 G, que ya nos costó una caída.
Controles que corre el propio guion, sobre el HECHO y no sobre la intención: compila y ejecuta un
hola mundo en C; enlaza una proc-macro, compila el programa que la usa y lo ejecuta; y —el que evita
el remedio peor que la enfermedad— comprueba que el estático SIN banderas siga enlazando.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`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>
`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>
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>
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>
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>
`radio gcc-libs` contestaba «9 dependientes, 9 sellados caen a deuda», y con ese número avisé de una
cascada de horas —firefox con PGO dos veces, waterfox, atuq—. La respuesta correcta es CERO: los
cinco declaran gcc-libs en `deps.runtime`, y **`runtime` no entra en `hash_inputs`**, así que
re-sellarla no re-hashea a nadie. Se vio al mirar el store después del cambio: los cinco seguían al
día.
El grafo de `_deps` une build+runtime a propósito —eso es el CIERRE de una imagen, y esa unión
arregló en su día que firefox arrancara sin libstdc++—, pero `radio` responde otra pregunta: «¿a
quién obligo a reconstruir?». Ahora usa dos grafos: la cascada sale del de BUILD, y las imágenes del
de la unión, que es lo correcto para cada uno. Los que dependen sólo por runtime se siguen
informando, nombrados, diciendo que NO se reconstruyen.
Controles: gcc-libs ⇒ 0 de cascada y 9 sólo-runtime; zlib ⇒ 126 directos y 391 transitivos (sigue
viendo las de verdad); zsh ⇒ 0. Y `test-yupana-radio.py` pasa: libdrm sigue cruzando las 5 colas.
Un número que sobreestima frena arreglos correctos, que es justo lo que casi pasa acá.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`/usr/lib/libgcc_s.so` no es una librería: es un ld script —`GROUP ( libgcc_s.so.1 -lgcc )`— y ese
`-lgcc` es libgcc.a, que ninguna receta del corpus proveía. Esta misma la borraba: el
`find -name '*.a' -delete` de la poda, y de paso el `rm -rf /usr/lib/gcc` se llevaba el original.
Medido en la caja con el rust recién sellado: los binarios estáticos compilan y corren, pero
cualquier dylib —y eso incluye TODAS las proc-macros— muere con `unable to find library -lgcc`. O
sea `cargo build` con `derive` imposible sobre takana, con el compilador perfecto. Y no alcanza con
dar `-L /usr/lib`: con eso se resuelven `-lc` y `-lgcc_s`, y entonces aparece justo este `-lgcc`.
Es la misma familia que el hueco que originó esta receta —todo presente, todo reproducible, y el
camino que hace falta no existe—, sólo que del lado del ENLACE en vez del arranque.
libgcc.a se copia a /usr/lib (donde el -L del enlazador ya mira; el gcc completo no está en esta
distro) y se salva de la poda. Y entra un GUARDIÁN 3 que compara lo que el ld script PIDE contra lo
que el artefacto TRAE: si vuelve a quedarse sin libgcc.a, corta.
Radio medido con yupana antes de tocar: 7 dependientes directos, 9 transitivos, 7 imágenes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
Tres intentos persiguieron el mismo problema por partes: `-lgcc` no se encuentra, después `-lgcc_s` y
`-lc` en los build scripts del stage2. La causa es una sola: un enlazador invocado SIN driver de C no
conoce los caminos del sistema. Ese `-L /usr/lib`, el directorio privado de gcc y las libs implícitas
las agrega `gcc`, no `ld`. Dárselos a mano es una lista sin fondo, porque cada etapa del bootstrap
enlaza cosas distintas.
Y el intento de dárselos por RUSTFLAGS (_BOOTSTRAP y _NOT_BOOTSTRAP) NO llegó a los build scripts:
comprobado mirando el renglón de enlace, donde `/usr/lib` seguía sin aparecer. Así que la cura va
donde corresponde: `linker = "gcc"` en el `[target.x86_64-alpine-linux-musl]` de bootstrap.toml. De
paso, con gcc de driver los `-Wl,-rpath,…` del bootstrap vuelven a ser válidos —eran lo que había
obligado a `rpath = false`, que se deja igual porque sigue siendo lo correcto con prefijo /usr—.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Con `-lgcc` resuelto, el build avanza y muere más adentro: los build scripts de libc, proc-macro2 y
quote no encuentran `-lgcc_s` ni `-lc`. Mirando el renglón de enlace entero, sus únicos `-L` son sus
propios directorios de build: NO lleva /usr/lib. El enlace de `std` sí lo llevaba —de ahí
`musl-root = "/usr"`—, pero eso aplica al TARGET, no a los binarios de HOST que el bootstrap compila
por el camino.
Es la misma causa de las tres veces: sin driver de C, nadie agrega los caminos del sistema. Se los
damos por RUSTFLAGS en las dos variantes que mira el bootstrap (_BOOTSTRAP para lo que compila el
stage0, _NOT_BOOTSTRAP para stage1+). libc.so, libc.a y libgcc_s.so están los tres en /usr/lib del
lab: comprobado, no supuesto.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
El primer intento dejó el enlace en `configure` y lo comprobó ahí mismo: la comprobación dio ✓ y el
build murió igual, con el log mostrándolo con claridad cruel —«rust: libgcc.a enlazada desde
/usr/lib/gcc/…» y, tres pantallas después, «ld.lld: error: unable to find library -lgcc»—.
La causa es que LAS FASES NO COMPARTEN SISTEMA DE FICHEROS: cada una es un bwrap nuevo con
`--tmp-overlay /`, que es una capa tmpfs DESCARTABLE (lo dice el propio comentario de sandbox.rs).
El enlace se evaporó entre configure y compile. Un guardián que comprueba en la misma fase en la que
escribe confirma algo que ya no será cierto cuando importe: lo que cambia el entorno de una fase se
hace EN esa fase. Ahora va al principio de `compile` y de `install`, que son las que enlazan.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
El build muere a los 6 minutos enlazando libstd.so: `ld.lld: error: unable to find library -lgcc`.
Es la otra cara de lo que la receta ya documentaba para `rpath = false`: al poner ld.lld como
enlazador del triple, se invoca DIRECTO, y el `-L` del directorio privado de gcc lo agrega gcc, no
ld. libgcc_s.so sí está en /usr/lib —por eso `-lgcc_s` pasa y sólo falla el estático—, pero libgcc.a
vive en /usr/lib/gcc/<triple>/<version>/.
Se enlaza a /usr/lib, que el propio renglón de enlace que falla ya busca. La ruta sale de
`gcc -print-libgcc-file-name` y no escrita a mano a propósito: la versión es del LAB, que no entra en
hash_inputs, así que una ruta literal se rompería en silencio el día que el lab mueva de gcc.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Si el push del estado se rechaza porque otro agente empujó primero, el ciclo siguiente se rechaza
IGUAL —nadie rebasa nunca— y el commit del cron se queda local para siempre. Se encontró en la caja:
rama divergente con un `estado: cosecha granja` atascado y la cosecha diciendo «reintenta» cada media
hora sin que nada cambiase. El mensaje tranquilizaba y no era cierto.
Ahora, cuando lo rechazan, llama a `git-sincronizar.sh`, que es la regla 2 ter automatizada: rebasa,
COMPRUEBA por parche que el commit sobrevivió, lo recupera del reflog si no, y empuja. Y si tampoco
puede, lo dice y deja el comando para verlo, en vez de prometer un reintento que no existe.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
`firmware-tigerlake` cortaba con «falta regulatory.db», y no era un fallo suyo: upstream sacó ese
fichero del tarball de linux-firmware y hoy sólo se publica en su propio proyecto de kernel.org.
Comprobado sobre el artefacto sellado de linux-firmware 20260910: `find -name "regulatory*"` no
devuelve nada.
Lo que pasa sin ella no es «no hay WiFi», que sería fácil de notar: cfg80211 arranca, la tarjeta
asocia, y se queda en el dominio `world` —pierde canales de 5 y 6 GHz y emite a la potencia mínima—.
Un WiFi que funciona y va mal.
La receta NO compila nada: el `make` del proyecto regenera la db y la firma con otra clave, y el
kernel valida contra la que lleva compilada, así que regenerarla la rompería. Copia `regulatory.db` y
su `.p7s` tal cual, y corta si la firma falta —sin firma, cfg80211 ignora la base y volvemos al
dominio world, que es justo lo que veníamos a arreglar—.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Los que faltaban son casi todos de la forma `ath11k/WCN6855/hw2.1/regdb.bin -> ../hw2.0/regdb.bin`:
un `..` no resuelve si el directorio desde el que cuelga todavía no existe, y yo probaba el destino
ANTES del mkdir. Con el directorio creado primero resuelven los 2415 de 2415 — medido sobre el árbol
desempaquetado, no deducido.
Queda dicho en la receta porque la lectura fácil era la contraria: «WHENCE declara enlaces a blobs
que el tarball no trae», que habría llevado a bajar el umbral y sellar un artefacto con 337 firmwares
inalcanzables. Y si el destino de verdad no existe, ahora se borra el directorio vacío que el mkdir
haya dejado: un directorio vacío en el artefacto es exactamente lo que el §3 de CLAUDE.md prohíbe.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Primer intento con el arreglo: 2078 de 2415 (86 %), y el guardián cortó. La causa es que WHENCE
encadena —declara `a -> b` donde `b` es a su vez un enlace que aparece más abajo—, así que en una
sola pasada el destino todavía no existe cuando toca crear el primero. Se repite hasta que una
pasada no agregue nada, con tope de tres. Y ahora salta los que ya existen, para no recontar.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
Dos defectos medidos el 2026-09-17 al construirla por primera vez en la caja.
1) La receta decía «cp -a preserva los symlinks internos, que es lo que el kernel espera». La premisa
es FALSA: `find -type l` sobre el árbol desempaquetado da 0. Los ~2400 enlaces los crea
copy-firmware.sh al instalar, leyéndolos de WHENCE, y esta receta evita ese script porque pide
rdfind. El resultado habría sido un artefacto de 1,9 G, sellado y reproducible, con iwlwifi MUDO: el
driver pide `iwlwifi-QuZ-a0-hr-b0-77.ucode` en la raíz y el blob vive en intel/iwlwifi/. Justo el
metal al que apunta firmware-tigerlake (TigerLake/AX201) se quedaba sin WiFi. Ahora se crean desde
WHENCE, cuyo destino es relativo al directorio del enlace, y sólo si el destino existe.
2) La aserción de completitud era `> 5000 ficheros`, medida sobre una versión vieja. La 20260910 trae
4889 y el guardián la rechazaba POR COMPLETA. Un umbral escrito a mano envejece y miente en la
dirección cara: frena lo bueno y hace dudar del tarball, que estaba pineado por sha256 y era el
correcto. Ahora se le pregunta a WHENCE, que viaja dentro del tarball y declara cuántos blobs hay.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
El primer build confirmó la predicción que la propia receta traía escrita: `link = "static"` salió
DINÁMICO, contra la libncursesw del lab, y moría con `Error relocating ... symbol not found` —o sea,
habría arrancado en el sandbox de Alpine y no dentro de una imagen—. La causa de fondo es que zsh
carga sus módulos con dlopen; por eso va `--disable-dynamic`, que los mete en el binario.
Pero `--disable-dynamic` solo dejaba un zsh sin `=~`:
zsh:1: failed to load module: zsh/regex
zsh:1: -regex-match not available for regex
Dos explicaciones mías fueron falsas antes de la buena, y quedan escritas en la receta porque las dos
son plausibles y costaron un build cada una: (1) «quedan en link=dynamic, hay que sedearlos a static»
—el sed no cambió nada, los disponibles ya salían static—; (2) «el .mdd evalúa $ac_cv_func_regcomp y
config.status no tiene esas variables, hay que exportarlas» —el configure contesta yes a las cuatro y
el módulo seguía fuera—.
Lo zanjó `configure.ac`, que no opina: con dynamic apagado, un módulo que su .mdd declara `dynamic`
se DESCARTA (link=no) y sólo los que declaran `either` pasan a estático. regex.mdd dice `dynamic` y
complete.mdd dice `either`: por eso había completado y no había `=~`. El arreglo va sobre los .mdd,
antes del configure, y sobrevive a que make regenere config.modules.
Además `--enable-pcre` era una etiqueta, no un hecho: zsh 5.9 sólo habla PCRE1 y el corpus tiene
pcre2; el configure lo decía tres veces. Se quitan la bandera y la dep, que mentían sobre el cierre.
Y el control va EN LA RECETA: la instalación corta si el ELF tiene INTERP o si falta alguno de
{regex, complete, zle, parameter} dentro del binario. Ese guardián es quien atajó los dos intentos
fallidos en vez de sellarlos. Medido sobre el artefacto: statically linked, 16 módulos cargan,
`=~` contesta, 1663 completadores, 14 M.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`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>
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>
El git sellado no traía `git-remote-http` —ni `-https`, ni `git-http-fetch`— pese a tener `curl` en
[deps], y el artefacto mostraba la forma exacta que deja el Makefile cuando NO_CURL está puesto:
`git-http-backend` (el lado servidor, que no usa curl) presente y los tres helpers ausentes.
La causa estaba un paso antes. El tarball de git trae `configure` y takana lo corre; su
`AC_CHECK_LIB` enlaza `conftest.c -lcurl` y nada más, y con libcurl ESTÁTICA eso no resuelve: le
faltan `-lssl -lcrypto -lz`, que son sus privadas. El test falla en silencio, `config.mak.autogen` se
lleva `NO_CURL=YesPlease` y el build TERMINA EN VERDE sellando un git mutilado:
checking for SHA1_Init in -lcrypto... yes
checking for curl_global_init in -lcurl... no ← acá
checking for XML_ParserCreate in -lexpat... no
La cura son tres líneas: `LIBS="$(curl-config --libs)"` al configure (sale de curl-config, no escrito
a mano: si curl gana privadas mañana, las trae solo), `NO_EXPAT=1` porque con curl encendido el
Makefile agrega http-push.o y expat no está en deps, y un GUARDIÁN que corta si `config.mak.autogen`
quedó con NO_CURL=YesPlease — el modo de fallo es silencioso, así que se comprueba el HECHO.
Medido sobre el artefacto, no sobre el git del host: b3:215742cb… trae git-remote-http,
git-remote-https, git-http-fetch y los ftp; y CLONA por HTTPS de verdad —clone, no ls-remote, que es
donde murió la vez del ubsan—: árbol en disco y rev-list contesta.
Radio, medido con yupana: git tiene CERO dependientes transitivos ⇒ el re-sello no arrastra ninguna
reconstrucción. Toca las 7 imágenes que lo incluyen, que es otra cosa.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>