psmisc 23.7 (killall pstree fuser prtstat pslog) y gavinhoward/bc 7.0.3 (bc Y dc
del mismo árbol). Ninguna estaba en el corpus, y lo de psmisc es lo que el plan
daba por cubierto sin estarlo: procps-ng NO trae killall ni pstree ni fuser —
procps-ng es ps/top/free/kill/pgrep/pkill/pidof/uptime/vmstat/w/watch.
bc es el de gavinhoward y no el de GNU por la cadena: C99 sin dependencias, bc y
dc en un árbol, y es el bc de sistema de Alpine y FreeBSD. El de GNU arrastra ed
y flex, y su dc va en otro paquete.
⚠ killall5 NO lo trae psmisc: es de sysvinit. Acá lo cubre arje-zero por FUNCIÓN
(es PID 1 y apaga él) ⇒ se retira con los indultos, no se reemplaza. Son 3 de los
4 que la tabla prometía, dicho así para que no vuelva a prometer lo que no hay.
Dos pisones de psmisc, los dos escritos en la receta para no repetirlos:
1. `-lncurses` no existe acá (la nuestra es widec ⇒ libncursesw.a). No sirve
LIBS=-lncursesw —el AC_CHECK_LIB compila un programa de prueba CON -lncurses,
no pregunta si el símbolo resuelve— ni la variable de caché con
`make TERMCAP_LIB=…`, porque src_pstree_LDADD = @TERMCAP_LIB@ se sustituye en
tiempo de configure y el Makefile queda con -lncurses LITERAL. Lo que funciona
es un enlace libncurses.a → libncursesw.a en el scratch y un -L.
2. Y ese -L se comió el -static. El harness inyecta LDFLAGS=-static para las
recetas link="static" (takana-build/src/lib.rs:285); reemplazar LDFLAGS lo
pierde. Los seis binarios sellaron DINÁMICOS sin que nada fallara: killall
respondía bien y sólo pstree moría en ejecución con `Error relocating
/lib/libncursesw.so.6`, tomando la librería del anfitrión. Un `file` lo dice en
un segundo; ninguna prueba del build lo iba a decir.
Los dos van a `base` en targets.toml, y el censo baja de 69 a 64.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cuatro artefactos sellados y el paso 2 del plan cerrado. Los diez applets que
dejan de depender de busybox salieron de arreglar recetas, no de escribir código:
xz unxz xzcat lzma unlzma lzcat → recipes/xz-tools.toml (nueva, b3:194c7d69…)
vi → un symlink en recipes/vim.toml
cpio → un symlink en recipes/libarchive.toml
arch hostname → los trajo el feature de uutils (b3:614ff653…)
xz-tools es el TERCER caso de la familia de zstd-cli, y eso ya estaba escrito en
targets.toml: «la receta canónica construye sólo lib/ y su artefacto no tiene
usr/bin; declararla no habría arreglado nada». Igual que musl-shared, zlib-shared
y libffi-shared. Cuatro veces la misma forma — la receta publica la lib, la
imagen declara el paquete, y el binario no está. Va como variante porque ampliar
la canónica re-hashearía a sus 14 consumidores.
⚠ xz-tools selló DINÁMICO en la primera corrida pese al link = "static", y
funcionaba: comprimía y descomprimía sin una queja. Es el relink de libtool, que
libarchive.toml y bluez.toml ya documentan — hace falta LDFLAGS=-all-static en
compile Y en install. Lo delató el `file` del binario, no una prueba que fallara.
Paso 2 del plan: uutils, findutils, findutils-xargs, diffutils, gzip, grep y
xz-tools declarados en el perfil `base` — seis recetas que llevaban meses
`sealed` con `perfiles: []`. Hasta hoy, `find`, `xargs`, `diff`, `cmp`, `gzip`,
`zcat` y `grep` en una imagen de takana eran el applet de busybox, no porque
faltara escribirlos sino porque nadie los declaró. `grep` entra como PUENTE
declarado: ripgrep ya viaja pero publica `rg` y no es grep POSIX.
El censo gana modo --guardian, y vigila PÉRDIDAS, no un umbral: un umbral hay
que subirlo cada vez que se retira un applet y a la tercera nadie lo sube con
criterio; que un applet con proveedor medido deje de tenerlo es siempre una
regresión. Probado en los dos sentidos — rc=0 contra /store, rc=1 contra un store
mutilado, nombrando applet y proveedor perdido.
Los cuatro sellaron con el mismo hash en el store tirable y en /store: dos
work_root distintos, bytes idénticos.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
El plan de botar busybox decía de sí mismo que el reparto applet→dueño era
«juicio, no medida». Medido contra los 1407 artefactos del store: de los 277
applets vivos, 167 los provee el dueño que el TSV nombra, 31 los provee OTRO
paquete, y 79 no los provee NADIE salvo busybox — 56 más de los 23 previstos.
El hallazgo transversal es que una receta de LIBRERÍA no es un paquete de
HERRAMIENTAS, y build-state no distingue: `xz` figura en SEIS perfiles con el
`usr/bin` VACÍO (su receta pasa --disable-xz --disable-xzdec --disable-scripts,
o sea liblzma y nada más), y `ncurses` instala sólo install.libs/install.includes
⇒ ni clear, ni reset, ni tput. Las dos viajan, las dos dicen `sealed`, y el único
binario que hay adentro de la imagen es el applet de busybox.
Y al revés: `switch_root` y `sulogin` los trae util-linux, `partprobe` lo trae
parted, y `getty` tiene sustituto — `agetty` de util-linux, en los 7 perfiles ⇒
deja de ser ESCRIBIR y pasa a ser migrar el exec de la card. Seis de los 18
huecos de iproute2 (ipaddr iplink ipneigh iproute iprule iptunnel) no son
comandos de nadie: son nombres internos de busybox y se borran del defconfig.
uutils traía 78 applets, no los 90 que el plan le atribuía: el multicall
contestaba `coreutils: unknown program 'chmod'`. Construía con las default
features (feat_common_core) y el resto vive detrás de feat_os_unix_musl, que
cubre exactamente los 25 que faltaban. Construido y verificado contra un store
tirable: 79 → 106 applets, 27 nuevos y CERO perdidos, chmod/uname/id ejecutan, y
`stdbuf` correctamente ausente (por eso la variante _musl y no feat_os_unix:
upstream lo excluye en musl porque necesita un cdylib).
Importaba más de lo que parece: USERLAND_COMPONENTS hidrata uutils DESPUÉS de
busybox para ensombrecerlo, y lo que no existe no ensombrece nada — chmod, chown,
id, uname y stat los seguía dando busybox con el userland Rust instalado encima.
⚠ Dicho en la receta y en el documento: who/users/uptime/pinky compilan contra
los stubs de utmpx de musl y contestan vacío. No es regresión, tampoco es
sustitución.
El censo queda como script (scripts/busybox-censo-proveedores.py) y como dos
columnas del TSV, no como una tabla escrita a mano que vuelva a envejecer.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paso 1 de docs/plan-botar-busybox.md. 124 applets fuera del defconfig: los 105 que
no se reemplazan (dpkg, rpm, httpd, telnetd, ubi*, nand*, i2c*) y 19 cuya función ya
hace otro componente (init/runit -> arje-zero, syslogd/klogd/logread -> hammerd).
Binario de 1.230.976 a 977.096 bytes.
CORRIGE UN ERROR DEL PLAN: arje-zero y hammerd reemplazan la FUNCIÓN, no el COMANDO
-- son un binario cada uno. Por eso 5 indultos: setuidgid (la card de gitea lo
ejecuta), switch_root (el /init del instalador, antes de que arje exista) y
poweroff/halt/reboot (nada más en el corpus apaga la máquina).
scripts/busybox-vigia.py falla si alguien invoca un applet retirado; lee la lista de
la propia receta para que no haya dos que se desincronicen. Su primera versión daba
91 hits y ninguno real: las cuatro reglas que lo bajaron a 0 están documentadas.
El mapa applet->símbolo sale de las líneas //applet: del fuente, no de poner el
nombre en mayúsculas: eso falla en 6 casos medidos, dos de ellos en la lista.
Verificado: 277 applets exactos, los 5 indultados presentes, y zlib-ng, jq y
logrotate reconstruidas y selladas con el busybox recortado -- el sandbox sigue en
pie. Son 3 de las 24 dependientes, no las 24, y el boot de la imagen no se probó.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Medido contra el artefacto sellado (401 symlinks) cruzado con build-state.json:
148 applets ya tienen dueño sellado Y en perfil, 125 tienen dueño sellado que no
viaja en ninguna imagen (uutils, brush, findutils, diffutils, arje-zero, hammerd),
y de los 128 sin dueño 105 son basura que se borra.
Dos hallazgos que cambian el plan: busybox entra a los 7 perfiles como dep de BUILD
de 24 recetas, no como raíz de producto en targets.toml; y brush (shell Rust) ya
está sealed, sin validar y sin perfil.
docs/state/busybox-applets.tsv es la tabla applet-por-applet (generada), con 24
parejas marcadas NO-drop-in.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>