📊 Estado del proyecto#
Este documento responde a una sola pregunta: qué está construido de verdad, qué lo demuestra y qué falta.
La regla que lo gobierna es la del proyecto entero: no se indica que algo fue probado si no se ejecutó la prueba, y no se ocultan los errores. Por eso aquà no aparece la palabra «listo» en ningún sitio, y cada afirmación de que algo funciona viene con el comando que hay que ejecutar para comprobarlo.
Versión: 0.1.0 · Última revisión: 2026-08-07
Resumen en tres nĂşmeros#
| Construido | Del total | |
|---|---|---|
| NĂşcleo de aislamiento | 9 de 9 controles | âś… completo y verificado en CI |
| Casos técnicos | 15 | de 15, con código |
| Casos de mercado de capitales | 21 | de 21, con cĂłdigo |
Los 36 casos del catálogo tienen cĂłdigo y prueba que se ejecuta en cada commit. Ninguno llega a verified: para eso hace falta evidencia firmada por ejecuciĂłn, y todavĂa no la emiten. Esa es la distancia que queda, y está medida.
Lo que se puede ejecutar hoy y comprobar#
Cinco comandos que corren en cada commit, no en un documento:
cargo run -p sandboxctl -- escape
Ocho sondas intentan escaparse del sandbox: red, PIDs, memoria, sistema de ficheros, capacidades, dispositivos, entorno y llamadas al sistema. La suite declara bwrap [experimental] sin fugas (8 contenidas) y, si alguna se escapa, CI se pone rojo. Hay además una lĂnea base con native que debe escaparse: si no lo hace, la suite no está midiendo nada.
cargo run -p sandboxctl -- evidence verify
Verifica que cada acta de ejecuciĂłn se sostiene: la huella SHA-256 coincide con el documento, la firma Ed25519 es válida, la cadena con la evidencia anterior no está rota, y los hashes de la polĂtica y de la carga corresponden a lo que hay en el repositorio.
cargo run -p sandboxctl -- markets reconcile
Seis escenarios de custodia, cada uno con el hallazgo que debe producir. Si la conciliaciĂłn deja de detectar un descuadre que declara detectar, CI se pone rojo.
cargo run -p sandboxctl -- markets check
Los 19 casos de mercado de capitales con código, con 119 escenarios que declaran de antemano qué debe salir de cada uno. Si alguno deja de detectar lo que dice detectar, CI se pone rojo.
node scripts/verify-cases.mjs
Prueba de comportamiento de los casos técnicos. Hoy cubre el caso 01 con diez comprobaciones. Un caso en estado ready sin prueba aquà hace fallar la suite: es el guardián de que el estado declarado sea cierto.
Núcleo de aislamiento — completo#
Los nueve puntos del backlog tĂ©cnico están cerrados, cada uno verificado empĂricamente en WSL2 con bubblewrap 0.9.0 real y confirmado en CI.
| # | Qué se cerró | Cómo se aplica de verdad |
|---|---|---|
| B-01 | LĂmite de procesos | pids.max vĂa cgroups v2, pedido con systemd-run --user --scope |
| B-02 | LĂmite de memoria | memory.max, con observaciĂłn de memory.peak y oom_kill |
| B-03 | LĂmite de CPU | cpu.max, con lectura de cpu.stat durante la ejecuciĂłn |
| B-04 | Red por lista de permitidos | Namespace de red propio + proxy por socket Unix que habla CONNECT host:port y registra cada intento, permitido o no |
| B-04b | Puerto publicado con red contenida | El servicio escucha en un socket Unix dentro de la jaula; un reenviador fuera publica el puerto TCP |
| B-05 | Llamadas al sistema | Filtro seccomp BPF compilado con seccompiler y entregado a bubblewrap por descriptor de fichero |
| B-06 | UID y GID | --uid / --gid en un namespace de usuario, sin privilegios |
| B-07 | Compilador Ăşnico de argumentos | Un solo sitio traduce polĂtica → argumentos de bubblewrap. Antes habĂa varios y divergĂan |
| B-08 | Integridad de la evidencia | Huella → firma Ed25519 → cadena entre actas → rehash de polĂtica y carga |
La regla que lo gobierna todo#
Un control solicitado, un control aplicado y un control reportado tienen que describir la misma realidad.
Por eso toda acta distingue cinco listas: requestedControls,
obligatorio que este equipo no puede aplicar, la ejecuciĂłn no ocurre: falla cerrada y explica quĂ© falta. El detalle está en Referencia de polĂticas y en Formato de evidencia.
Casos técnicos — 15 de 15 con código#
| # | Caso | Estado | Qué hay | Qué falta |
|---|---|---|---|---|
| 01 | Contenido web no confiable | 🟡 building | Coordinador e intérprete separados por proceso, 15 tipos de rechazo, 10 comprobaciones automáticas | Ficha en el panel; levantar el servicio bajo bwrap dentro de CI |
| 02 | CĂłdigo generado por IA | 🟡 building | EjecuciĂłn sin red, entorno vacĂo, disco temporal, techo de tiempo | Rediseño: un sandbox efĂmero por ejecuciĂłn, con cola y cancelaciĂłn. Más lenguajes |
| 03 | Procesamiento de archivos | 🟡 building | zip slip, zip bomb, rutas absolutas, enlaces, informe por entrada | Renombrar a 03-safe-archive-processing; MIME real, más formatos, checksum |
| 04 | Plugins de terceros | 🟡 building | Manifiesto, concesión traducida a montajes y red, registro de intentos · 8 comprobaciones | Los seis plugins de ejemplo; flujo de aprobación en el panel |
| 05 | Custodia de claves y firma | 🟡 building | Firma Ed25519 en la jaula, red none, socket Unix, clave fuera del repositorio | Dividir: el determinismo se va al caso 07. LĂmites de monto, rotaciĂłn, revocaciĂłn |
| 06–15 | Los diez restantes | 🟡 building | Un núcleo por caso con 62 comprobaciones entre todos, y su servicio | Levantarlos bajo bwrap en CI; evidencia firmada. 06 y 14 necesitan además KVM |
Ninguno está en ready. Los núcleos se comprueban —80 comprobaciones entre los doce casos con prueba—, pero ninguno se levanta bajo bwrap dentro de CI ni emite evidencia firmada por ejecución, que es el requisito para verified.
Mercado de capitales — 21 de 21 con código#
La base: construida y probada#
El crate sandbox-markets tiene las dos piezas de las que dependen todos los casos financieros:
Money— enteros en unidades mĂnimas, con la moneda pegada al importe.
Pesos y dĂłlares no se suman porque no compila. Nunca coma flotante: un f64 no representa 0,10 de forma exacta, y en un libro contable eso es un descuadre que aparece tarde y en producciĂłn.
Ledger— partida doble, append-only, con reversas e idempotencia. Una
transacciĂłn que no cuadra no se registra.
Los casos#
| # | Caso | Estado | Qué hay | Qué falta |
|---|---|---|---|---|
| CM-02 | Sistema alternativo de transacciĂłn | đźź prototype | Libro de Ăłrdenes con 11 invariantes: prioridad precio-tiempo, precio fijado por la orden que descansa, libro nunca cruzado | Los 7 escenarios; Ăłrdenes de mercado; reconstrucciĂłn completa de la sesiĂłn |
| CM-03 | Custodia y segregaciĂłn de activos | 🟢 functional | El invariante de custodia, 5 tipos de hallazgo, 6 escenarios verificados en cada commit | Dividendos, bloqueos, garantĂas, insolvencia del custodio |
| CM-00, CM-01, CM-04–CM-20 | Los diecinueve restantes | 🟠prototype | Un módulo por caso con su modelo y 119 escenarios que se ejecutan en cada commit | Evidencia firmada por ejecución; datos que no sean los suyos |
Lo que está construido y no se ve#
Piezas que no son un caso pero sostienen todo lo demás:
| Pieza | Dónde | Qué hace |
|---|---|---|
| Compilador de polĂticas | crates/sandbox-core/src/compiler.rs | El Ăşnico sitio que traduce una polĂtica a argumentos de bubblewrap |
| cgroups v2 | crates/sandbox-core/src/cgroup.rs | Pide lĂmites por systemd-run y observa lo que realmente se consumiĂł |
| seccomp | crates/sandbox-core/src/seccomp.rs | Compila el filtro BPF y lo entrega por descriptor de fichero |
| Proxy de salida | crates/sandbox-core/src/egress.rs | Lista de permitidos sin comodines, con registro de cada conexiĂłn |
| Firma de evidencia | crates/sandbox-core/src/signing.rs | Ed25519, clave local con permisos 0600, fuera del control de versiones |
| Reenviador de puertos | crates/sandboxctl/src/forward.rs | Puente TCP ↔ socket Unix, para publicar sin dar red a la jaula |
| Barrido de huérfanos | crates/sandboxctl/src/service.rs | service down --all mata también lo que quedó vivo sin registro |
Esa Ăşltima lĂnea existe por un incidente real de este proyecto: tres sandboxes sobrevivieron cuatro horas sin que nada pudiera encontrarlos, porque se habĂa quitado --die-with-parent y un script de limpieza habĂa borrado sus registros. Está contado en RUNBOOK.
Lo que se decidió no hacer, y por qué#
| DecisiĂłn | Motivo |
|---|---|
No usar npm, sino pnpm | Ficheros de bloqueo deterministas y una Ăşnica forma de instalar |
No usar libseccomp (C), sino seccompiler (Rust puro) | Evitar una dependencia nativa que rompe la construcciĂłn reproducible |
| No escribir cgroups directamente | En WSL2 /init.scope no es escribible; systemd-run --user --scope funciona en ambos |
Vaciar el entorno con env -i en vez de quitar variables una a una | systemd inyecta variables propias; quitarlas de una en una siempre deja alguna |
| No incluir malware real, ni siquiera para el caso 06 | Regla del proyecto, sin excepciones |
| No conectar con ningĂşn sistema financiero real | Regla de la familia de mercado de capitales, sin excepciones |
Los estados y lo que significan#
| Estado | Qué significa exactamente |
|---|---|
planned | Especificado, sin cĂłdigo |
prototype | CĂłdigo que corre, sin prueba de comportamiento |
functional | Se ejecuta y hay una prueba concreta que lo demuestra |
verified | Además emite evidencia firmada y CI la valida |
production-research | InvestigaciĂłn, no desplegable |
deprecated | Se conserva por compatibilidad |
Qué sigue#
El orden no es arbitrario: cada elemento desbloquea al siguiente.
- Caso 01 a
functional— levantarlo bajobwrapen CI y añadir su ficha al
panel.
- Caso 04 — plugins por capacidades. Se apoya en el proxy de salida, que ya
existe.
- CM-02 a
functional— reconstrucción completa de la sesión, que es
requisito previo de CM-09.
- Caso 02, el rediseño — sandbox efĂmero por ejecuciĂłn.
- CM-00 — la puerta de la familia financiera: sin ella, los demás casos no
tienen lĂmites que respetar.
Ver también: Catálogo completo · Fichas de los casos · Cuando algo falla · Backlog de implementación · Runbook