⎇ 3dc85ebdcdd5fda0a1be0db5f8fbce5859266f2e
shared/format/src/constantes.rs
Ñawpa willay
Pi imata llamkarqan
ch'uya
feat: mirada standalone — compositor Wayland + WM sobre Llimphi (build magro)
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