tawasuyu

tawasuyu/mirada

Sovereign tiling Wayland compositor + window manager in Rust, on Llimphi.

Rust 50Markdown 30TOML 211282 Definiciones

⎇ 3dc85ebdcdd5fda0a1be0db5f8fbce5859266f2e shared/format/src/constantes.rs Rust · 163 líneas · 8.9 KB Historia Quién tocó qué crudo

feat: mirada standalone — compositor Wayland + WM sobre Llimphi (build magro) 3dc85ebdc · Sergio ·

1// =============================================================================
2//  Constantes del format en disco
3// =============================================================================
4
5/// Firma magica del superbloque — «RENASer GRaFo». Distingue un disco de
6/// renaser de uno virgen o ajeno.
7pub const MAGIA: [u8; 8] = *b"RENASGRF";
8
9/// Version del format del superbloque en disco. Un disco con otra version se
10/// reformatea al arrancar. v3 (Fase 24) — el superbloque porta `log_inicio`:
11/// el sector donde arranca el log activo. El compactador semantico copia el
12/// set alcanzable a una zona limpia del disco y reanca el superbloque a un
13/// nuevo `log_inicio` en una sola escritura atomica. v2 (Fase 7) ya portaba
14/// el ancla `manifiesto`, gemela de `raiz`.
15pub const VERSION_SUPERBLOQUE: u32 = 3;
16
17/// Version del format del manifiesto serializado. Independiente de la del
18/// superbloque: el manifiesto es un objeto del grafo, no una estructura fija
19/// del disco. v4 — cada `EntradaApp` declara su `permisos: u32`: un bitfield
20/// que dicta QUE capacidades el kernel enlaza en su `Linker` de wasmi. Las
21/// capacidades sensibles (red, raiz, altavoz, configuracion, escritura del
22/// grafo) no se REGISTRAN si el bit no esta puesto: la frontera es fisica,
23/// no chequeada en runtime. No hay escalada porque no hay tabla que escalar.
24///
25/// v5 (Fase 67 / WAWA §14.1.3) — cada `EntradaApp` gana `concesion:
26/// Option<Hash>`: el hash de una [`ConcesionCapacidad`] firmada por el
27/// `AGORA_AUTH_RING` sobre `(bytecode, permisos)`. Cuando una app la declara,
28/// el kernel toma la INTERSECCION [`permisos_efectivos`]`(declarados,
29/// concedidos)` — un manifiesto re-firmado ya no puede escalar un binario mas
30/// alla de lo que su concesion, atada a su hash, autoriza. Si `concesion` es
31/// `None` no hay techo per-bytecode: gobierna la firma del manifiesto (camino
32/// legacy, rollout escalonado — ver `SDD-capacidades.md` §3.6).
33///
34/// CORTE DE FORMATO: `postcard` NO es autodescriptivo, asi que cada campo nuevo
35/// rompe el wire de la version previa. Un disco viejo NO deserializa — el guardia
36/// de version (`Manifiesto::deserializar` exige `version == VERSION_MANIFIESTO`)
37/// lo rechaza y exige re-sembrar el genesis. En la practica el operador re-forja
38/// la imagen en cada `cargo run -p boot`, asi que la genesis nace limpia.
39/// v5→v6 (2026-05-30): agrega `overlay_revocacion: Option<Hash>` para el plano de
40/// control del SDD-rotacion-revocacion §4.
41/// v6→v7 (2026-06-03): agrega `marco: Option<Hash>` para persistir el marco del
42/// escritorio (`pata`) activo entre reinicios — Fase 9 del SDD de pata.
43pub const VERSION_MANIFIESTO: u32 = 7;
44
45/// Version del format de la `Configuracion` serializada. La configuracion es
46/// otro objeto del grafo (idioma + paleta); el manifiesto la enlaza por hash.
47/// v1 inaugura el modelo: cambiarla es engendrar un nodo nuevo y reanclar.
48pub const VERSION_CONFIGURACION: u32 = 1;
49
50/// Version del format del canal de release serializado. Independiente del
51/// manifiesto: un canal es otro objeto del grafo, con su propia historia de
52/// raices recomendadas. v1 inaugura el modelo de distribucion.
53pub const VERSION_CANAL: u32 = 1;
54
55/// Techo del nombre de un canal, en bytes. Acota la cabecera serializada y
56/// fuerza a que los canales se nombren cortos —`estable`, `beta`, `dev`,
57/// `cofradia-tal`—. Quien intente registrar un canal con un nombre mas largo
58/// se topa con un error de deserializacion.
59pub const NOMBRE_CANAL_LIMITE: usize = 64;
60
61/// Techo del tamaño de un objeto serializado: 1 MiB. Acota los buferes de E/S
62/// y permite descartar un registro corrupto sin leer un disparate.
63pub const MAX_OBJETO: usize = 1024 * 1024;
64
65/// Tamaño de un sector del disco, en bytes. El log se traza en multiplos de
66/// esta unidad — la misma que expone el transporte virtio-blk.
67pub const TAM_SECTOR: usize = 512;
68
69/// El identificador de un objeto: el hash BLAKE3 de su forma serializada. En
70/// un almacen direccionado por contenido, la identidad ES el contenido.
71pub type Hash = [u8; 32];
72
73// =============================================================================
74//  CodigoError — el lenguaje de los retornos de syscall, sin alucinaciones
75// -----------------------------------------------------------------------------
76//  Los retornos negativos de las capacidades `sys_*` no son enteros opacos:
77//  son variantes nombradas, fuertemente tipadas, con un valor i32 estable.
78//  El kernel emite `CodigoError::X as i32`; el userspace compara contra el
79//  mismo numero. Anadir una variante NUEVA es engendrar un valor nuevo (las
80//  existentes jamas se renumeran), de modo que un binario viejo y un kernel
81//  nuevo siguen hablando el mismo idioma para los codigos que ambos conocen.
82//
83//  Los retornos POSITIVOS de algunas capacidades son cuentas de bytes copiados
84//  —no errores—; por eso `Ok = 0` y todos los errores caen en negativos. La
85//  comparacion habitual del userspace queda intacta: `< 0` ya es "fallo", y
86//  el codigo concreto lo describe.
87// =============================================================================
88
89/// El catalogo de retornos negativos de las capacidades del kernel. Un solo
90/// nombre por causa: nadie ha de inventarse una semantica nueva para el -1.
91///
92/// Mantenido en `format` porque viaja por TRES fronteras: el kernel lo emite,
93/// el explorador (host-side) lo lee de las trazas, y los modulos WASM lo
94/// reciben. La crate ya es no_std y la traen ambos lados sin friccion.
95#[repr(i32)]
96#[derive(Clone, Copy, PartialEq, Eq, Debug)]
97pub enum CodigoError {
98    /// Operacion completada sin novedad. Las capacidades que devuelven un
99    /// conteo de bytes usan tambien `0` para "no habia nada que entregar"
100    /// (lectura sin frame, sin evento, sin estado previo); el contexto del
101    /// retorno positivo distingue ambos casos.
102    Ok = 0,
103    /// El recurso solicitado no esta presente: un objeto que no esta en el
104    /// grafo, la tarjeta de red sin montar, una app sin estado previo, una
105    /// cola del puntero o el teclado vacia. Tambien lo emite un guardar
106    /// que no encontro su ranura.
107    Ausente = -1,
108    /// La capacidad recibida en `salida` no cubre los datos a copiar. La app
109    /// debe llamar con un bufer mas amplio; el kernel no escribio nada en el
110    /// destino.
111    CapacidadInsuficiente = -2,
112    /// El subsistema de almacenamiento (virtio-blk, log de objetos, censo del
113    /// manifiesto) fallo al servir o anclar el objeto. NO es culpa del modulo,
114    /// pero la operacion no pudo completarse.
115    AlmacenamientoFallo = -3,
116    /// La app no tiene el FOCO del compositor en este fotograma y la capacidad
117    /// solo se honra para la ventana enfocada — por ejemplo, cambiar la
118    /// `Configuracion` del escritorio. Reintentar cuando la app sea la
119    /// destinataria del teclado.
120    SinFoco = -4,
121    /// El envio al dispositivo (driver de red, altavoz) fracaso. Lo emite el
122    /// driver y la capacidad lo propaga: no hay rastro de bytes residuales en
123    /// el hardware.
124    EnvioFallo = -5,
125    /// Cuota de recurso saturada para esta app en este fotograma: hay un
126    /// limite blando que protege un recurso fisico (DMA, descriptores de un
127    /// anillo virtio) y la app lo alcanzo. El kernel NO entrega la
128    /// operacion ni avanza el contador; la app ha de retirarse y volver a
129    /// intentar en su proximo `tick` —cuando la IRQ del hardware haya
130    /// liberado los descriptores que tenia retenidos—. Es BACK-PRESSURE
131    /// cooperativa: el equivalente de un `Poll::Pending` que cabe en un
132    /// codigo de retorno entero. Distingue a una autodefensa del kernel
133    /// frente al codigo de la app de un fallo del propio almacenamiento.
134    Saturado = -6,
135    /// El payload que la app entrego al kernel decodifica pero esta FUERA
136    /// del dominio que la capacidad acepta — un codigo de idioma que no es
137    /// letras ASCII, una paleta cuyos canales suman cero, un campo
138    /// inconsistente con su contexto. Distinto de `Ausente` (recurso
139    /// inexistente) y `CapacidadInsuficiente` (bufer corto): aqui los
140    /// bytes llegaron pero su SIGNIFICADO los descalifica. La app ha
141    /// de reconstruir su entrada con valores legitimos antes de reintentar.
142    PayloadInvalido = -7,
143}
144
145impl CodigoError {
146    /// Convierte el codigo a su forma de cable i32 — la unica que el userspace
147    /// recibe. `as i32` directo, sin trampa: el `#[repr(i32)]` fija el valor.
148    pub const fn como_i32(self) -> i32 {
149        self as i32
150    }
151}
152
153/// La identidad de un autor agora: una clave publica Ed25519, 32 bytes. Quien
154/// firma una raiz de canal se identifica con esto. `format` no valida la
155/// firma —no enlaza ninguna primitiva criptografica—; solo declara su forma.
156/// La verificacion vive en `agora` (o en `firma`), donde corresponde.
157pub type AgoraId = [u8; 32];
158
159/// Una firma Ed25519, 64 bytes. La produce `agora` sobre el mensaje canonico
160/// que devuelve [`mensaje_a_firmar`]. `format` la transporta y la deja a quien
161/// pueda verificarla.
162pub type Firma = [u8; 64];
163