plan + simi: el bloqueante del sh está RESUELTO, y la receta tenía su medición caducada
El plan decía que el candidato a /bin/sh era `brush` y que la unidad de trabajo
#1 era medirlo. Quedó superado: existe `simi`, un /bin/sh PROPIO (crates/simi,
4448 líneas de Rust), sellado y medido contra el corpus REAL.
simi ash bash brush
divergencias (1339) 0 — 8 35
ms/caso 1,5 1,5
tamaño 499 KB 0,92 MB 6,9 MB
Y lo importante de esos 1339: sólo 10 están escritos a mano, los otros 1329 son
FASES REALES de recetas del corpus. No es «pasa un banco POSIX que yo inventé»
—eso es sh-banco-posix.sh, que brush pasa 56/57 y aun así no construye una
receta autotools— es «hace LO MISMO que el ash sobre el material que hay».
Para llegar a 0 hubo que arreglar una RECETA, no simi (commit anterior).
⚠ Y la receta de simi llevaba un mes con su medición caducada: citaba el hash
b3:46ff6fcf… (superado; el vigente es b3:327b31b7…) y «159 casos» (el banco
creció a 1339). Re-medido contra el artefacto vigente, que además traje del
worker al store del hub: estático de verdad (0 NEEDED), 498 736 bytes,
DIVERGE=0. La lección: una medición con su hash al lado CADUCA cuando el hash
avanza, y nada avisa.
⇒ Lo que falta para botar el sh de busybox no es escribir ni medir: es DECLARAR
simi en un perfil, y eso la mete en la raíz de confianza del arranque (frente
C). Es una decisión, con su propia unidad de trabajo.
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
2 archivos · +53 −12
- docs/plan-botar-busybox.md +36 −7
- recipes/simi.toml +17 −5
diff --git a/docs/plan-botar-busybox.md b/docs/plan-botar-busybox.md
index 6ad5b26b..9b3999de 100644
--- a/docs/plan-botar-busybox.md
+++ b/docs/plan-botar-busybox.md
@@ -125,13 +125,42 @@ GNU que los `configure` del corpus sí usan. Las tres opciones son legítimas y
**Sin `sh` POSIX no se bota busybox en ningún frente**: es el `exec` de las cards, el `/bin/sh` del
producto y el shell del sandbox. Lo esperado era que fuera un proyecto de meses.
-**`recipes/brush.toml` (0.4.0, reubeno/brush, MIT, Rust, compat bash) está `sealed`.** Compila
-estático musl con zig cc y produce `/usr/bin/brush`.
+## ✅ RESUELTO — `simi`, y la noticia es mejor de lo que esta sección decía
-⚠ **Y está sin validar como `sh`.** La receta es un import crudo de nixpkgs y lo dice en su primera
-línea: «PUNTO DE PARTIDA, no final». No está en ningún perfil, nadie lo ejecutó como `/bin/sh`, y el
-sandbox de build es el consumidor más duro que existe (`configure` de autotools). **La unidad de
-trabajo #1 es medirlo, no adoptarlo.**
+**El bloqueante ya no existe.** Lo que había escrito acá —que el candidato era `brush` y que había
+que medirlo— quedó superado: se escribió un `/bin/sh` PROPIO, **`simi`** (`recipes/simi.toml`,
+`crates/simi`, 4448 líneas de Rust), y está medido contra el corpus REAL.
+
+| | simi | ash (control) | bash | brush |
+|---|---|---|---|---|
+| divergencias duras, **1339 casos** | **0** | — | 8 | 35 |
+| avisos (stderr) | 0 | — | | |
+| ms/caso | 1,5 | 1,5 | | |
+| tamaño | **499 KB** estático, 0 NEEDED | 0,92 MB | | 6,9 MB |
+| latencia (hub) | 547 µs | 464 µs · 1,18× | | 3,5× |
+
+⚠ **Y lo importante de esos 1339: sólo 10 están escritos a mano — los otros 1329 son fases REALES
+de recetas del corpus.** No es «pasa un banco POSIX que yo inventé» (eso es
+`sh-banco-posix.sh`, y brush lo pasa 56/57 y aun así no construye una receta autotools): es «hace
+LO MISMO que el ash sobre el material que de verdad hay».
+
+Para llegar a 0 hubo que arreglar **una receta, no simi**: `wasi-libcxx` usaba `${t/unknown-/}`, un
+bash-ism que el ash tolera por cortesía y que POSIX no tiene. Era la ÚNICA divergencia de las 1339.
+simi implementa las diez expansiones POSIX (`${v}` `:-` `:=` `:?` `:+` `${#v}` `#` `##` `%` `%%`) y
+**ninguna de bash** (`${v/a/b}` `${v:1:2}` `${!v}` `${v^^}`) — verificadas una por una. Eso no es
+una carencia: es la línea que define qué es `/bin/sh` acá, y hace que un bash-ism en una receta
+FALLE en vez de colarse.
+
+### Lo que queda de `simi`, y es sólo declararla
+
+Está **sellada y vigente** (`b3:327b31b7…`, traída al store del hub el 2026-10-22) y **en ningún
+perfil, a propósito**: declararla la mete en la raíz de confianza del arranque (frente C) y eso es
+su propia unidad de trabajo. Dicho de otro modo: el paso que falta no es escribir ni medir, es
+DECIDIR.
+
+⚠ Dos cosas que su receta tenía caducadas y se corrigieron el 22-oct: citaba el hash
+`b3:46ff6fcf…` (superado) y «159 casos» (el banco creció a 1339). *Una medición con su hash al lado
+caduca cuando el hash avanza* — y ésta llevaba un mes diciendo un número viejo.
## Orden de ataque
@@ -194,7 +223,7 @@ parecer trabajo pendiente.
| applet(s) | qué falta | tamaño |
|---|---|---|
-| `sh` `ash` `hush` | **EL BLOQUEANTE.** `brush` está sellado y medido como insuficiente para el sandbox (ver el veredicto del paso 3). Queda medirlo como `/bin/sh` del PRODUCTO, que es consumidor mucho más blando | grande |
+| ~~`sh` `ash` `hush`~~ | ✅ **RESUELTO por `simi`** (ver arriba): 0 divergencias en 1339 casos, 499 KB, estático. No es `brush` — es código propio. Lo único pendiente es DECLARARLA en un perfil, que es decisión de frente C, no trabajo de implementación | — |
| ~~`halt` `poweroff` `reboot`~~ | ❌ **NO son hueco: están INDULTADOS a propósito y el TSV lo dice.** Me equivoqué al meterlos acá: sí es cierto que los tres resuelven a busybox en la caja viva, pero eso **es la decisión**, no un descuido — *«nada más en el corpus apaga la máquina: arje-zero es PID1, no una CLI»*, y `kernel_ab.rs` documenta `reboot -f kexec`. Mismo caso: `setuidgid` (lo invoca la card de gitea) y `switch_root` (lo ejecuta el /init del instalador). ⇒ **5 indultados, no 3 huecos.** Lección: el TSV ya tenía el veredicto medido y yo lo re-derivé peor | — |
| `nslookup` | **no hay NINGÚN cliente DNS de consulta**: `drill`, `dig`, `host`, `kdig` — ninguno existe en el store. Es hueco de capacidad, no de nombre | mediano |
| `setpriv` | nuestro `util-linux` NO lo construye (medido: ausente del artefacto, y upstream lo trae) ⇒ probablemente una bandera del configure. ⚠ Pero `util-linux` tiene radio 79: tocarlo cascadea | chico, cascada caro |
diff --git a/recipes/simi.toml b/recipes/simi.toml
index c4f240d2..ee64afdd 100644
--- a/recipes/simi.toml
+++ b/recipes/simi.toml
@@ -9,11 +9,23 @@
# divergencias POSIX medidas (reubeno/brush#1394 y #1396, las dos reportadas por nosotros). simi son
# 4448 líneas con CERO divergencias contra el ash de busybox en los 159 casos del banco diferencial.
#
-# SELLADA en el worker el 2026-09-21: `b3:46ff6fcf67bd23dece4d130c92855908520200f88ca85981317f81fcc56bb834`
-# ELF x86-64 **estático** (verificado por `scripts/static-audit.sh simi`: «estáticos de verdad: 1,
-# MIENTEN: 0»), stripped, **498 736 bytes**. Contra el artefacto sellado, no contra el build del hub:
-# · banco diferencial, 159 casos vs el ash de busybox 1.36.1 → **0 divergencias** (bash: 8, brush: 35)
-# · latencia de arranque **468 µs contra 449 µs del ash — 1,04×** (brush: 1569 µs, 3,5×)
+# ══ MEDICIÓN VIGENTE — 2026-10-22, contra `b3:327b31b7…` ══════════════════════════════════════
+# ⚠ Esta nota citaba `b3:46ff6fcf…` y «159 casos», y las dos cifras habían CADUCADO: la receta
+# avanzó (hash vigente `b3:327b31b72d8051e0d86693d16090fb393b774622d120c5c140ad8673986fcc2d`) y el
+# banco creció. Re-medido contra el artefacto vigente, traído del worker al hub:
+#
+# · ELF x86-64 **estático** de verdad: `readelf -d` ⇒ **0 NEEDED**, `file` ⇒ «statically linked»
+# · **498 736 bytes** stripped (sigue igual)
+# · banco diferencial vs el ash de busybox: **1339 casos** —1329 de ellos **fases REALES de
+# recetas del corpus**, no escritas a mano— ⇒ **DIVERGE=0, avisos(stderr)=0**, 1,5 ms/caso
+# contra los 1,5 del ash. (bash: 8 divergencias; brush: 35)
+# · latencia de arranque medida EN EL HUB: 547 µs contra 464 µs del ash, **1,18×**. En el worker
+# dio 1,04×; el propio banco avisa de que la cifra incluye el fork+exec de Python y sirve para
+# COMPARAR, no como absoluto. brush: 3,5×.
+#
+# ⚠ Para llegar a DIVERGE=0 hubo que arreglar **una receta, no simi**: `wasi-libcxx` usaba
+# `${t/unknown-/}`, un bash-ism que el ash tolera y que POSIX no tiene. Era la única divergencia de
+# las 1339. simi implementa las diez expansiones POSIX y ninguna de bash, a propósito.
#
# ⚠ Todavía NO está en ningún perfil de `docs/state/targets.toml`, y es a propósito: declararla es
# meterla en la raíz de confianza del arranque (frente C) y eso es su propia unidad de trabajo.