Commit Graph
1621 Commits
Author SHA1 Message Date
Sergio a5ad955459 merge: trabajo concurrente del otro frente 2026-09-22 04:12:32 +00:00
SergioandClaude Opus 5 d293f39e04 qillqa construye el corpus y REPRODUCE BIT A BIT — donde brush hacía 0 de 3
La prueba que de verdad decide, la misma con que se midió brush el 21/09: copia
del lab, qillqa como /usr/bin/awk, y tres recetas autotools reales. Resultado:

  pkgconf    b3:cfb6a37e…  sellada · IDÉNTICA al hash vigente
  flex       b3:6b25e351…  sellada · IDÉNTICA
  oniguruma  b3:751a5270…  sellada · IDÉNTICA

Los tres hashes son los que ya estaban en build-state.json, construidos con el
awk de busybox. O sea que qillqa no sólo deja construir: produce los MISMOS
BYTES. brush pasaba 56/57 casos POSIX y no construía ninguna de las tres.

Latencia 1,04× la de busybox (brush: 4,1×) y binario de 0,64 MB, más chico que
gawk (0,83) y que el busybox entero con sus 277 applets (0,98).

⚠ Son tres recetas, no las 943. Lo que prueban es que el camino que tumbó a brush
—el config.status que genera el libtool, donde awk hace el trabajo pesado— aquí
pasa. No prueban que no haya un cuarto caso.

Declarado en `base`, con lo medido escrito al lado de la declaración. El censo
baja a 62 con clear/reset, que ahora los da ncurses-tools.

Y una corrección de método que me costó una reparación: la primera copia del lab
la hice con `cp -al` (hardlinks) y después un `chown -R` sobre ella — que cambió
el dueño del INODO COMPARTIDO y se llevó por delante 471 entradas del
/work/dev-fs/alpine REAL, el lab que usan los demás agentes. Reparado
(chown -h 65534 sobre las 471; el control de /bin confirmó el dueño esperado) y
rehecho con copia real en el disco grande. Un hardlink no es una copia: lo que se
comparte no son sólo los datos, son los METADATOS.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 04:12:26 +00:00
Sergio 1647310894 estado: cosecha granja 2026-09-22T04:01:44Z — avance del árbol KDE 2026-09-22 04:01:45 +00:00
Sergio 2c882bdd65 merge: trabajo concurrente del otro frente 2026-09-22 03:48:36 +00:00
SergioandClaude Opus 5 ae6f0b45d9 qillqa: el awk propio — 3531 líneas, sólo libc, y CERO divergencias contra dos oráculos
«awk soberano» (usuario, 2026-09-22), que era la tercera opción del ADR pendiente
y la única que no adoptaba la semántica de otro: gawk es C con extensiones GNU,
goawk es Go y rompe la premisa de cadena de la Etapa C, frawk es otro dialecto.

Banco diferencial contra DOS oráculos a la vez —el awk de busybox 1.36.1 (el
applet que hoy viaja) y gawk 5.3.2 --posix— con 109 casos: campos y separadores,
el modelo de valores, aritmética, expresiones regulares, las funciones de cadena,
printf, control de flujo, arrays, funciones de usuario, E/S y los rincones del
parser. Resultado: 104 iguales a los dos, 0 divergencias, y 5 casos donde los
ORÁCULOS discrepan entre sí — que es justo para lo que sirve tener dos.

De esos 5, cuatro los tenemos del lado correcto por POSIX: `2^3^2` es 512 (la
potencia asocia a la derecha; busybox da 64), `index(s,"")` es 1, el `%*d` de
printf existe, y `length(array)` funciona. El quinto era nuestro y se arregló:
una coincidencia VACÍA pegada al final de la anterior no sustituye, así que
`gsub(/a*/,"-")` sobre "xax" da 3 y `-x-x-`, no 4 y `-x--x-`.

El motor de expresiones regulares es propio y esa es la razón de fondo para no
adoptar un crate: POSIX es leftmost-LONGEST y la familia Perl —el crate `regex`
en su modo por defecto— es leftmost-first. Para /a|ab/ sobre "ab", POSIX devuelve
`ab` y Perl devuelve `a`. En un awk eso decide qué borra un sub(), dónde parte un
split() y cuánto valen RSTART y RLENGTH. Construcción de Thompson con conjunto de
hilos: sin retroceso, así que `(a*)*b` contra sesenta `a` no explota.

Las cinco cosas que el banco destapó, todas dando resultados plausibles y ninguna
reventando —quedan como pruebas de regresión en tests/divergencias_medidas.rs:

  · leer NF no forzaba el partido en campos ⇒ `{print NF}` daba 0 hasta que
    alguien tocara un campo. El partido es perezoso a propósito (es lo que hace
    barato asignar a $0) y el precio es acordarse de forzarlo.
  · `length` sin paréntesis se leía como una VARIABLE llamada length, que vale
    vacío. Es el único builtin al que POSIX permite omitirlos.
  · los arrays se pasan por referencia, y eso se decide mirando si la función usa
    el parámetro como array — `a["k"]=1` tiene el nombre en el LUGAR de la
    asignación, y sólo se miraba el valor.
  · substr con inicio ≤ 0 recorta a 1 SIN ajustar el largo, y los no enteros se
    truncan. La lectura estricta de POSIX daría otra cosa; ni busybox ni gawk la
    hacen, y lo que hay que ejecutar son los guiones escritos contra ellos.
  · la regla del vacío en gsub, arriba.

Verificado además contra este repo: de los 61 programas awk únicos que usan sus
guiones y recetas, qillqa acepta los 59 reales (los 2 restantes son f-strings de
Python que mi extractor tomó por awk). 29 pruebas propias en verde.

El nombre es quechua («escritura») y sigue el precedente de simi: lo registra el
comentario de cabecera y lo DECIDE un ADR. El comando instalado será `awk` — eso
es contrato y lo llaman los configure de medio corpus.

⚠ Lo medido es el build NATIVO del hub. Falta la receta, el estático musl con zig
cc, y la prueba que de verdad decide: un `configure` de autotools con qillqa como
/usr/bin/awk. Es la lección de brush — pasó 56/57 casos POSIX y no construía una
sola receta.

Va también recipes/ncurses-tools.toml (clear, reset, tput, tset, infocmp, tic),
declarada en `base`: la canónica instala sólo lib y cabeceras, así que clear y
reset en una imagen eran el applet de busybox. Instala los binarios y NO la base
terminfo: resuelven con los --with-fallbacks compilados en la librería, que
cubren la consola del metal, QEMU y cualquier ssh moderno.

⚠ Y ncurses-tools selló DINÁMICO dos veces antes de salir bien: ncurses usa
`-static`/`-dynamic` como MARCADORES de tramo alrededor de las librerías —su
forma portable de -Wl,-Bstatic … -Wl,-Bdynamic—, no como decisión global. El
`-dynamic` llega al final de la línea de enlace y gana por orden. Se quita
sobreescribiendo LIBS_TIC y LIBS_TINFO en la línea de make. Tercer sabor del
agujero que documenta scripts/static-audit.sh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 03:48:25 +00:00
Sergio 0ff269a7d6 estado: cosecha granja 2026-09-22T03:31:36Z — avance del árbol KDE 2026-09-22 03:31:36 +00:00
Sergio 03ea9ef615 estado: cosecha granja 2026-09-22T03:01:45Z — avance del árbol KDE 2026-09-22 03:01:45 +00:00
Sergio 2c723c7493 estado: cosecha granja 2026-09-22T02:31:54Z — avance del árbol KDE 2026-09-22 02:31:54 +00:00
Sergio 55160d3f06 estado: cosecha granja 2026-09-22T02:02:12Z — avance del árbol KDE 2026-09-22 02:02:12 +00:00
Sergio 6af8547e94 estado: cosecha granja 2026-09-22T01:31:38Z — avance del árbol KDE 2026-09-22 01:31:38 +00:00
Sergio 0f051c51f2 estado: cosecha granja 2026-09-22T01:01:23Z — avance del árbol KDE 2026-09-22 01:01:23 +00:00
Sergio a2159048f9 estado: cosecha granja 2026-09-22T00:31:28Z — avance del árbol KDE 2026-09-22 00:31:28 +00:00
Sergio 720b72099c estado: cosecha granja 2026-09-22T00:01:47Z — avance del árbol KDE 2026-09-22 00:01:47 +00:00
Sergio 66db5484e9 estado: cosecha granja 2026-09-21T23:31:35Z — avance del árbol KDE 2026-09-21 23:31:35 +00:00
Sergio e08ee8ba0e estado: cosecha granja 2026-09-21T23:01:45Z — avance del árbol KDE 2026-09-21 23:01:45 +00:00
Sergio 9941ab3cea estado: cosecha granja 2026-09-21T22:31:22Z — avance del árbol KDE 2026-09-21 22:31:22 +00:00
Sergio a88d9e5b77 estado: cosecha granja 2026-09-21T22:01:37Z — avance del árbol KDE 2026-09-21 22:01:37 +00:00
SergioandClaude Opus 5 4357b29cb7 busybox 69 → 64: psmisc y bc, las dos piezas que el plan marcaba TRAER
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>
2026-09-21 21:49:57 +00:00
Sergio 5fd8746445 atuq §7.terdecies: «no hay identidad» era también «no pude preguntar» — y en pacha-cli eso guardaba los dotfiles EN CLARO
Contesta el segundo pendiente del §7.duodecies: `pacha`/`pacha-secretos` en
`perfil.servidor`. La respuesta a la pregunta de origen es **NO**, y es la
CONTRARIA a la del escritorio.

Premisa medida, no supuesta: la Card de `pacha-secretos` es `scope=system` y
entra al `genesis`, o sea que arje arranca el daemon EN EL ARRANQUE. De ahí se
sigue que un sembrador en la imagen no llega a tiempo por construcción — en el
arranque no hay nadie logueado; `abrir_almacen()` decide una vez en `main()` y
no vuelve a mirar; y `agora-cli unlock` de una sesión ssh siembra en el llavero
de ESA sesión. Declararlo dejaría la función PARECIENDO cerrada, que es peor
que el hueco. Queda escrito al lado de las dos raíces, en `targets.toml`, para
que nadie copie la decisión del escritorio.

Y al ir a medirlo, el control POSITIVO salió rojo — con la seed en `/proc/keys`
el daemon decía que no había identidad — y eso destapó el defecto de verdad:
los CINCO lectores de la seed hacían `.ok().flatten()` (o un `_ =>`), que
convierte «el llavero no se pudo consultar» en «no hay identidad desbloqueada».
La causa del rojo la mide la sonda de syscalls: en el LXC `add_key` funciona y
`keyctl(KEYCTL_SEARCH)` da `ENOSYS` ⇒ se puede sembrar y no cosechar.

El peor de los cinco no era un mensaje feo: `pacha-cli` guardaba los dotfiles
SIN CIFRAR, en silencio, con la identidad del usuario desbloqueada.

Arreglado en tawasuyu (`4f2b5eac7`) con `pacha_llavero::SeedDeSesion` —tres
estados, tres textos— y `Reason` en `net.tawasuyu.Secretos1`. Pin de las dos
recetas `23a292863` → `cd9acd0d9` ⇒ `b3:e8038352` (4,6 M) y `b3:a9fb8c17`
(8,5 M), mirados por dentro y probados como artefacto: el daemon sellado ahora
dice «motivo=el llavero de sesión NO se pudo consultar (… os error 38) — esto
no es «no hay identidad»».

Tres cosas más que quedaron medidas por el camino:
- la guarda pegada al build **se disparó sola por primera vez**: el latido
  revirtió `pacha.toml` entre las dos construcciones de la misma tanda;
- el muro del `Cargo.lock`, quinta vez, y la arista que faltaba era la mía de
  esa mañana: se la llevó un «merge de git en «main» (import)». Bisecado con
  `git log -S`;
- el índice Y el árbol compartidos de tawasuyu tenían una versión de
  `pacha-boveda-llimphi` ANTERIOR al arreglo de `7917fbb96`. Lo delató el test
  de regresión, no el diff.
2026-09-21 21:41:43 +00:00
Sergio c020c2af19 merge: trabajo concurrente del otro frente 2026-09-21 21:34:58 +00:00
SergioandClaude Opus 5 466972e301 busybox: 79 → 69 applets sin otro dueño, y ninguno de los diez costó escribir userland
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>
2026-09-21 21:34:46 +00:00
Sergio 077e5acc21 estado: cosecha granja 2026-09-21T21:32:11Z — avance del árbol KDE 2026-09-21 21:32:11 +00:00
Sergio 3573fb0057 merge: cosecha de la granja 21:02Z 2026-09-21 21:02:47 +00:00
SergioandClaude Opus 5 64005efcbd busybox: los 23 applets sin dueño eran 79 — el reparto era juicio, y medido no da
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>
2026-09-21 21:02:07 +00:00
Sergio 8f0391dbc0 estado: cosecha granja 2026-09-21T21:02:05Z — avance del árbol KDE 2026-09-21 21:02:05 +00:00
Sergio d154ce02a2 simi: REPRODUCE bit a bit — y dos trampas operativas que costaron dos corridas
scripts/verificar-repro.sh simi en el worker: «✓ simi REPRODUCE», 0
no-determinismos. Queda anotado en docs/state/repro-verificado.tsv con su hash,
que es la clave del libro: si la receta o alguna dep cambia, la entrada deja de
casar y hay que volver a verificar.

Las dos trampas, anotadas en el SDD porque las dos fallan en silencio:

1. --store <tirable> NO sirve para verificar reproducibilidad. Un store vacío da
   «Error: io: No such file or directory» a secas —sin decir qué falta— porque las
   deps del build no están ahí. El método correcto ya estaba escrito: apartar el
   artefacto dentro del MISMO store y reconstruir. Dos corridas perdidas por
   inventar un instrumento en vez de leer el que existía.

2. La cosecha BORRA una receta sembrada a mano: siembra hub→worker con
   rsync --delete, y el hub del que siembra es gioser, no el clon donde se
   trabaja. El worker perdió recipes/simi.toml entre el build y la verificación
   (el artefacto sellado sobrevivió, la receta no) y el verificador informó
   «REPRODUCEN: 0 · sin artefacto: 0» — o sea nada, porque su primer [ -f ] falla
   y salta en silencio.

Comprobado de paso: editar los comentarios de la receta NO cambia el hash
(hash_inputs es una lista explícita de campos). Y el artefacto vive sólo en el
store del worker: sella con PROMOTE=0 y la cosecha baja el manifiesto, no el
store. Promoverlo es otro paso.
2026-09-21 20:35:53 +00:00
Sergio c2586b131c estado: cosecha granja 2026-09-21T20:31:34Z — avance del árbol KDE 2026-09-21 20:31:34 +00:00
Sergio 07867ba23e estado: cosecha granja 2026-09-21T20:01:39Z — avance del árbol KDE 2026-09-21 20:01:39 +00:00
Sergio 76885a93fe estado: cosecha granja 2026-09-21T19:31:38Z — avance del árbol KDE 2026-09-21 19:31:38 +00:00
Sergio 7de281a79f estado: cosecha granja 2026-09-21T19:01:40Z — avance del árbol KDE 2026-09-21 19:01:40 +00:00
Sergio 8f8c105e7d estado: cosecha granja 2026-09-21T18:31:39Z — avance del árbol KDE 2026-09-21 18:31:39 +00:00
SergioandClaude Opus 5 c5a27d9b4c busybox recortado: 401 -> 277 applets, con vigía y cinco indultos medidos
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>
2026-09-21 18:26:01 +00:00
Sergio 58e7972977 estado: cosecha granja 2026-09-21T18:02:09Z — avance del árbol KDE 2026-09-21 18:02:09 +00:00
Sergio 0a82d3f701 estado: cosecha granja 2026-09-21T17:32:20Z — avance del árbol KDE 2026-09-21 17:32:20 +00:00
Sergio 9defa8686f estado: cosecha granja 2026-09-21T17:02:02Z — avance del árbol KDE 2026-09-21 17:02:02 +00:00
Sergio c7097e4a91 atuq §7.duodecies: el sembrador entra a las cuatro imágenes — y cifraba la seed de todos con una palabra pública
El §7.undecies dejó la bóveda declarada y a NADIE capaz de abrirla: ninguna
imagen traía un binario que sembrara `pacha_llavero::SEED_IDENTIDAD`. Esta es
esa unidad.

De las dos formas posibles entra `agora-cli`, y el motivo no es que sea mejor:
el wizard `churay-welcome-llimphi` SÍ tiene binario (medido: `src/main.rs` sin
`[[bin]]`, o sea que cargo lo descubre), pero decide además backend de IA,
dotfiles, fondo de pantalla y chasqui — la experiencia de primer arranque
entera, que no se decide dentro de una unidad del navegador.

⚠ Y antes de poder declararlo apareció lo que lo volvía imposible: sin
`AGORA_PASSPHRASE`, `Sesion::abrir()` caía en la frase de desarrollo
"agora-dev" con un aviso por stderr y un ✓ en pantalla. La cadena que eso toca:
frase → Argon2id → ChaCha20-Poly1305 que cifra la seed → la clave con la que
`boveda` descifra su base. O sea, en una imagen de escritorio, la bóveda de
todo el mundo cerrada con una palabra escrita en el fuente, y nada que falle.

Arreglado en tawasuyu (`fd08dc03a`): variable > terminal (se pregunta, sin eco,
y DOS veces en la génesis, donde un error de tipeo no se nota hasta que la seed
ya no se recupera) > desarrollo sólo si no hay a quién preguntarle. La decisión
vive en una función pura con cuatro tests, probada AL REVÉS: con el brazo
`Preguntar` borrado falla con `left: Desarrollo / right: Preguntar`.

Pin `9967b02c` → `da5fb8968` ⇒ `b3:46529e14`, 1,9 M, sellado en el worker con
la guarda PEGADA al build. Mirado por dentro (regla 3) y probado como
artefacto, con control negativo: `identity new` + `unlock` deja
`user pacha:id:default: 32` en `/proc/keys`, y con la frase equivocada contesta
«autenticación fallida» y NO re-siembra.

El muro del `Cargo.lock` por cuarta vez, con la causa cambiada: esta vez no la
puso quien tocó el lock sino otro agente que metió `shuma-taller` en un
`Cargo.toml`. Cerrado en el worker, donde el registro está completo: +1 línea.
Y el lock del árbol compartido traía otra vez el malo (índice y árbol con dos
versiones distintas, las dos rotas), así que el commit se armó con
`commit-tree` sin pasar por el índice.

Corrección al §7.undecies: el verbo es `agora-cli unlock`, no
`agora-cli identity unlock`.

El guardián de coherencia pasa de SEIS lugares a SIETE, con su cuarto control
negativo; los cuatro, en verde.

Queda: la herencia del llavero de SESIÓN entre procesos hermanos (sin medir —
y `/proc/keys` como root no la mide), y `pacha`/`pacha-secretos` en
`perfil.servidor` con el mismo hueco.
2026-09-21 16:40:46 +00:00
Sergio 384eccf060 estado: cosecha granja 2026-09-21T16:32:10Z — avance del árbol KDE 2026-09-21 16:32:10 +00:00
Sergio 146dd15b39 estado: cosecha granja 2026-09-21T16:04:56Z — avance del árbol KDE 2026-09-21 16:04:56 +00:00
SergioandClaude Opus 5 63397e278a plan: botar busybox — 401 applets repartidos, y el trabajo real son 23
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>
2026-09-21 15:54:12 +00:00
Sergio 0bffb40923 estado: cosecha granja 2026-09-21T15:31:59Z — avance del árbol KDE 2026-09-21 15:31:59 +00:00
Sergio 9733e1a421 estado: cosecha granja 2026-09-21T15:03:05Z — avance del árbol KDE 2026-09-21 15:03:05 +00:00
Sergio cc425c5615 estado: cosecha granja 2026-09-21T14:32:33Z — avance del árbol KDE 2026-09-21 14:32:33 +00:00
Sergio 4699dd12aa estado: cosecha granja 2026-09-21T14:02:12Z — avance del árbol KDE 2026-09-21 14:02:12 +00:00
Sergio b72f695d18 estado: cosecha granja 2026-09-21T13:32:29Z — avance del árbol KDE 2026-09-21 13:32:29 +00:00
Sergio 53b933e3d9 estado: cosecha granja 2026-09-21T13:02:01Z — avance del árbol KDE 2026-09-21 13:02:01 +00:00
Sergio 97245dc7cf estado: cosecha granja 2026-09-21T12:31:55Z — avance del árbol KDE 2026-09-21 12:31:55 +00:00
Sergio 7d0065631e estado: cosecha granja 2026-09-21T12:02:15Z — avance del árbol KDE 2026-09-21 12:02:15 +00:00
Sergio 8d5d0bbb5d estado: cosecha granja 2026-09-21T11:31:54Z — avance del árbol KDE 2026-09-21 11:31:54 +00:00
Sergio f06fbcab7b estado: cosecha granja 2026-09-21T11:01:53Z — avance del árbol KDE 2026-09-21 11:01:53 +00:00
Sergio 2ccb6ae7ce estado: cosecha granja 2026-09-21T10:31:47Z — avance del árbol KDE 2026-09-21 10:31:47 +00:00