Cada app tiene ahora su propia ranura de estado en el Manifiesto de Génesis (EntradaApp.estado): guarda y recobra lo suyo, sobrevive al reinicio, y no pisa a ninguna otra app. - apps/memoriosa: app WASM interactiva nueva. Cuenta las teclas pulsadas y persiste el recuento; al reiniciar despierta con su cuenta intacta. Reemplaza la 2a instancia de hola en la genesis. - kernel: capacidades sys_estado_cargar / sys_estado_guardar. El kernel custodia un manifiesto VIVO (Mutex<Manifiesto>); fijar_estado lo muta, lo re-graba en el grafo y lo re-ancla. ContextoCapacidades.indice_app da a cada app su identidad — su ranura, jamas la de otra. - cargar_userspace instala el manifiesto vivo antes de instanciar las apps: el init de una app ya consulta su estado al despertar. Verificado en QEMU (screendump + sendkey): disco virgen -> memoriosa con 0 celdas, testigo verde; 5 pulsaciones -> 5 celdas; reinicio -> 5 celdas intactas, testigo ambar (init releyo el estado del grafo). Cierra la Fase 7 — el userspace nace del grafo, completa. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5.1 KiB
renaser — Fase 7 :: Apps que nacen del Grafo
Plan de ataque. Para el estado general ver ROADMAP.md; para la arquitectura,
ARCHITECTURE.md.
El objetivo
Hoy el kernel lleva el userspace empotrado en su propio binario:
main.rs tiene cuatro include_bytes! (app.wasm, discola.wasm,
glotona.wasm, cronista.wasm) y cinco llamadas encender_app con regiones
escritas a mano. Eso contradice la tesis de renaser: el almacenamiento es un
grafo de objetos direccionado por contenido, no un binario monolítico.
La Fase 7 destruye el include_bytes! del userspace. Las aplicaciones
pasan a ser objetos del grafo; el kernel las descubre, las verifica por su
hash y las inyecta en caliente en wasmi. Qué apps arrancan, con qué cuota y
en qué región lo dicta un Manifiesto de Génesis que también vive en el
grafo. (La fuente font.ttf sigue empotrada: es del kernel, no del userspace.)
El problema de la génesis
Hay un huevo-y-gallina: el kernel lee el manifiesto para saber qué cargar, pero el manifiesto y el bytecode tienen que haber sido escritos antes. En un disco virgen no hay nada. Dos vías para sembrarlo:
- A — el kernel siembra. En un disco sin manifiesto, el kernel graba en el
grafo el bytecode de unas apps de génesis y un manifiesto por defecto. El
bytecode de génesis llega vía
include_bytes!— todavía. - B —
bootsiembra la imagen. El constructor de imagen (anfitrión) pre-puebla el disco con los objetos de bytecode y el manifiesto. El kernel jamás empotra una app.
B es el estado final puro, pero exige enseñarle a boot el formato del grafo
(objetos, BLAKE3, log, superbloque) — trabajo de anfitrión considerable. Se
ataca incremental, como las Fases 6.1a/b/c.
Sub-fases
7a — El Manifiesto y la carga desde el grafo (semilla por el kernel) — ✅ HECHA
manifiesto.rs(andamiaje ya creado) — tiposManifiesto/EntradaApp, (de)serialización postcard. Hoy es un módulono_stddel kernel; no se comparte con las apps (la frontera app↔kernel es el ABI WASM numérico, no tipos Rust).almacen.rs— elSuperBloquegana un segundo ancla,manifiesto: Option<Hash>, gemelo deraiz.VERSIONsube de1a2(un disco v1 se reformatea, como ya haceinitcon discos ajenos). Gettersmanifiesto()/fijar_manifiesto().manifiesto::sembrar_genesis()— en un disco sin manifiesto: graba el bytecode de las apps de génesis (include_bytes!, sólo aquí), compone unManifiestopor defecto con sus regiones y cuotas, lo graba y lo ancla.manifiesto::cargar()— lee el ancla del superbloque, recupera el objeto, lo deserializa.kernel_main— reemplaza las cincoencender_appescritas a mano por: cargar el manifiesto (o sembrarlo si falta) e iterar susEntradaApp.wasm/mod.rs— el techo de memoria deja de ser la constanteTECHO_MEMORIAy pasa a venir por-app del manifiesto (EntradaApp).- Verificar en QEMU — la pantalla debe verse idéntica a la Fase 6.2 (cinco apps en sus regiones), pero ahora nacidas del grafo.
7b — La imagen sembrada por boot; muere include_bytes! — ✅ HECHA
boot(anfitrión) aprende el formato del grafo y pre-puebla la imagen de disco con los objetos de bytecode + el manifiesto.- El kernel pierde los
include_bytes!del userspace;sembrar_genesisse retira o queda como camino vacío de respaldo.
7c — Persistencia inter-sesión — ✅ HECHA
- Una app (cronista evolucionada, o una nueva interactiva) guarda su estado mutado como un objeto nuevo del grafo al recibir teclado.
- Cada
EntradaAppusa su campoestado: Option<Hash>(ya previsto en el tipo). Al guardar, el kernel reescribe el manifiesto; al arrancar, le pasa ese estado a la app para que despierte donde quedó. - Probablemente una capacidad host nueva para que el kernel se entere del hash de estado nuevo que la app produjo.
Guardarraíles (directiva de la arquitecta)
- No romper
check-shared-cores.sh. Si algún tipo del manifiesto llegara a compartirse entre apps y kernel, debe habitar un núcleo estrictamenteno_std. Hoy no se comparte:manifiesto.rses kernel-only. - Errores recuperables con
Result. Si el kernel lee del grafo un objeto de bytecode corrupto (su hash recomputado ≠ su id),almacen::recuperarya lo detecta — devuelveErr. El kernel niega esa instanciación, pinta la baliza de desalojo en la región de esa app, y sigue levantando el resto. Un módulo podrido nunca tumba el arranque.
Estructura de archivos
| archivo | estado | rol en la Fase 7 |
|---|---|---|
kernel/src/manifiesto.rs |
nuevo (7a) | tipos Manifiesto/EntradaApp + (de)serialización + carga/siembra |
kernel/src/almacen.rs |
a modificar (7a) | SuperBloque.manifiesto, VERSION 2, getters |
kernel/src/main.rs |
a modificar (7a) | kernel_main itera el manifiesto en vez de include_bytes! |
kernel/src/wasm/mod.rs |
a modificar (7a) | techo de memoria por-app desde el manifiesto |
boot/ |
a modificar (7b) | siembra la imagen de disco con el grafo |