# renaser ↔ brahman — integración en el monorepo

`renaser` es un kernel bare-metal SASOS (espacio de direcciones único,
no-POSIX, `no_std`, x86_64). Vive en `renaser/` dentro de este repo. Este
documento explica **cómo** convive con brahman y **qué** comparten.

## Por qué un workspace de Cargo aparte

renaser está en el mismo repo git pero es **su propio workspace de Cargo** —
no un miembro del de brahman. Tres incompatibilidades lo imponen:

| | brahman | renaser |
| --- | --- | --- |
| toolchain | `stable` | `nightly` (artifact-deps, `rust-src`) |
| `panic` | unwind (lo necesita tokio) | `abort` (sin SO no hay unwinding) |
| `cargo build` en la raíz | compila todo para el host | el kernel jamás debe compilarse para el host |

`[profile]` y `rust-toolchain.toml` son **globales al workspace**: no se pueden
mezclar. Por eso `brahman/Cargo.toml` lleva `exclude = ["renaser"]` y
`renaser/Cargo.toml` es un `[workspace]` raíz independiente, con su propio
`rust-toolchain.toml` y `.cargo/`. Cargo los trata como ajenos; los crates
compartidos se referencian por `path` cruzando la frontera.

## El modelo: núcleos duales, superficies por-plataforma

La integración **no** es «cada crate compila para los dos lados». Es:

- **Núcleos** — lógica pura (`*-core`, geometría, contratos). Se hacen
  `no_std + alloc` y se comparten: el mismo crate compila para Linux y para
  `x86_64-unknown-none`.
- **Superficies** — IO y plataforma (daemons tokio, `sled`, gpui, smithay,
  init con `nix`/`libc`; del lado renaser, el kernel y sus drivers). **No** se
  comparten: cada plataforma tiene la suya. renaser no «importa» smithay;
  provee su propio framebuffer.

Un crate gana el tratamiento `no_std` **sólo cuando renaser de verdad lo
enlaza**. La mayoría de brahman (apps gpui, ERP, transpilador, daemons) nunca
corre en renaser y se queda `std`.

## Núcleos compartidos

| crate | rol | consumidor renaser |
| --- | --- | --- |
| `mirada-layout` | motor de teselado del compositor (geometría pura) | kernel, Fase 8 (compositor) |

Cómo se hace `no_std` un núcleo (patrón de `mirada-layout`):

1. `#![cfg_attr(not(test), no_std)]` + `extern crate alloc;` — los tests
   siguen corriendo con `std`; el crate enviado es `no_std`.
2. `std::collections` → `alloc::collections`; `Vec`/`vec!` → `use alloc::…`.
3. Punto flotante (`sqrt`/`ceil`/`round`) → crate `libm` (no están en `core`).
4. `serde` opcional tras una feature: los consumidores Linux la activan, el
   kernel no.
5. Dependencias declaradas directas (no `workspace = true`): un núcleo que
   cruza fronteras de workspace se mantiene autocontenido.

### El guardián

`scripts/check-shared-cores.sh` compila cada núcleo registrado para
`x86_64-unknown-none`. Si un núcleo recobra `std` (p. ej. al añadir una
dependencia descuidada), falla ahí. **Correrlo tras tocar un núcleo
compartido.** Al promover un crate nuevo, añadirlo al array `CORES` del script.

## Plan por etapas — estado

- **Paso 0 ✅** — renaser movido a `renaser/`, workspace propio, `exclude`.
- **Paso 1 ✅** — `mirada-layout` → `no_std`; el kernel de renaser lo
  `path`-depende cruzando workspaces. Mecanismo validado.
- **Paso 2 — descartado.** El plan era «converger el CAS». Al leer el código
  no se sostiene: son **tres capas distintas**, no una duplicación.
  - `arje-cas` — blobs SHA256 sobre el sistema de archivos. SHA256 lo fija el
    contrato `Card` (`module_sha256`); es una *superficie* Linux.
  - `renaser/almacen` — DAG de objetos (payload + hijos), hash
    `blake3(postcard)`, log sobre virtio-blk. Es una *superficie* bare-metal.
  - `minga-core` — Merkle-AST con hash **estructural** (`hash_components`,
    campo a campo, no `blake3(postcard)`): un esquema deliberadamente
    distinto que permite verificar un nodo sin los bytes de sus hijos.
  - Forzar un núcleo común impondría una abstracción equivocada (romper la
    verificación estructural de minga, o cambiar el SHA256 del protocolo
    `Card`). Lo único común —un newtype de hash de 32 bytes— no justifica
    tocar el kernel verificado.
- **Paso 4 ✅** — el guardián `no_std` (`scripts/check-shared-cores.sh`).
- **wasmi unificado ✅** — brahman y renaser corren ambos `wasmi 1.0`
  (`arje-wasm` migrado de `0.40`). El ABI WASM del host es ahora la misma
  versión en Linux y en bare-metal.
- **Paso 3 — pendiente, ya desbloqueado.** Converger el ABI `Card`/WASM:
  la matriz `sys_*` de capacidades de renaser y el contrato `Card` de
  brahman aún son universos paralelos. Es trabajo de diseño (qué forma
  toma una capacidad compartida), no un bump mecánico.

Fase 8 de renaser (su propia hoja de ruta): el kernel usa `mirada-layout` para
el compositor, con su framebuffer nativo.

## Construir

- brahman: `cargo build` en la raíz (ignora `renaser/`).
- renaser: `cd renaser && cargo build -p boot` (kernel + imagen UEFI) o
  `cargo run -p boot` (+ QEMU). Toma su toolchain nightly automáticamente.
- guardián: `./scripts/check-shared-cores.sh`.
