gioser

tawasuyu/brahman

Rust 496TOML 195Markdown 55JSON 197001 Definitions

refactor(yahweh): Fase 1 — nakui-ui-schema → yahweh-meta-schema

Primer paso del refactor yahweh. El schema de UI declarativa no
tiene acoplamiento real con Nakui (sólo dep en serde/thiserror) —
movemos a yahweh para que cualquier app metadata-driven lo use sin
pasar por nakui.

Mecánico:
- git mv crates/modules/nakui/ui-schema → crates/modules/ui_engine/libs/meta-schema.
- Crate name: nakui-ui-schema → yahweh-meta-schema.
- Workspace members[] actualizado (sección yahweh, no nakui).
- Consumers actualizados: brahman-cards (Cargo.toml + lib.rs +
  readers.rs), nakui-ui (Cargo.toml + main.rs).
- Self-test (example_modules.rs): import + path rebase (5 niveles
  arriba ahora).

Documental:
- Doc del crate ahora dice "metainterfaz (yahweh meta-schema)" +
  "backend-agnostic" en filosofía.
- Module.nakui_module_dir documentado como "path opaco al backend";
  se conserva el nombre por compat con módulos ya escritos +
  serde alias "backend_module_dir" para futuro rename suave.

Tests: 13 yahweh-meta-schema + 26 brahman-cards + 48 nakui-ui
verdes. Workspace build verde.

NO hace Fase 1: mover widgets a yahweh (Fase 2), trait MetaBackend
(Fase 3), renombrar nakui_module_dir.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

f5987d9cfc47146e2a8b32a670cd38ccf9e89ed8 · by Sergio · (5 months ago) · parent f6361bbdc · browse the tree at this commit

Semantic delta · 62

crates/modules/nakui/ui-schema/src/lib.rs

crates/modules/ui_engine/libs/meta-schema/src/lib.rs

14 files · +869 −785

diff --git a/CHANGELOG.md b/CHANGELOG.md
index af9ddca..c24edfd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,79 @@ ratio/diff ver `git show <sha>`.
 
 ## 2026-05-09
 
+### refactor(yahweh): Fase 1 — `nakui-ui-schema` → `yahweh-meta-schema`
+Primer paso del refactor yahweh. El schema de UI declarativa
+(entities, menús, listas, formularios, acciones) vivía bajo
+`crates/modules/nakui/ui-schema/` y se llamaba `nakui-ui-schema` —
+un nombre que sugería acoplamiento con Nakui que en realidad no
+existe (el crate sólo depende de `serde`/`serde_json`/`thiserror`).
+Lo movemos a yahweh para que sea consumible por cualquier app de UI
+metadata-driven sin hacer pasar la dep "rara" por nakui.
+
+Cambios mecánicos:
+- **`git mv`**: `crates/modules/nakui/ui-schema/` →
+  `crates/modules/ui_engine/libs/meta-schema/`.
+- **Cargo.toml del crate movido**:
+  - `name = "nakui-ui-schema"` → `name = "yahweh-meta-schema"`.
+  - Description actualizada: "Yahweh — meta-schema: descriptores
+    declarativos de UI ... independiente del backend".
+- **Workspace `Cargo.toml`**: la entry del members[] pasa de
+  `crates/modules/nakui/ui-schema` a
+  `crates/modules/ui_engine/libs/meta-schema` (en su sección
+  yahweh, no en la sección nakui).
+- **`brahman-cards`**:
+  - Cargo.toml: dep path/name a `yahweh-meta-schema`.
+  - lib.rs: `pub use nakui_ui_schema::Module` →
+    `pub use yahweh_meta_schema::Module`.
+  - readers.rs: comment + doc-link al nuevo nombre.
+- **`nakui-ui`**:
+  - Cargo.toml: dep path/name a `yahweh-meta-schema`.
+  - main.rs: `use nakui_ui_schema::{...}` →
+    `use yahweh_meta_schema::{...}`.
+- **Self-test del crate movido**
+  (`tests/example_modules.rs`): `nakui_ui_schema` → `yahweh_meta_schema`,
+  y se rebasa el path del repo root (5 niveles arriba ahora, era 4).
+
+Cambios documentales:
+- **Doc de crate** (`lib.rs`): "Schema declarativo de la metainterfaz
+  Nakui" → "Schema declarativo de la metainterfaz (yahweh
+  meta-schema)" + "backend-agnostic" en la filosofía. La sección
+  Persistencia universal pasa de "el runtime conecta cada vista al
+  `nakui_core::store::Store`" a un wording neutro: "el runtime que
+  consume este schema conecta vistas a su backend".
+- **Doc del field `Module.nakui_module_dir`**: ahora marcado como
+  "path opaco al backend, lo interpreta el runtime concreto". Se
+  describe la convención actual de Nakui (nsmc.json + KCL + Rhai)
+  como ejemplo, no como contrato del schema. El nombre del campo
+  se mantiene por compat con módulos ya escritos; agregado
+  `#[serde(alias = "backend_module_dir")]` para que un futuro
+  rename no rompa los actuales.
+
+Tests:
+- yahweh-meta-schema (crate movido): 13 tests propios siguen
+  verdes tras el path rebase.
+- brahman-cards: 26/26 verdes (17 integration + 9 nickel).
+- nakui-ui: 48/48 verdes.
+- Workspace build verde.
+
+Lo que NO hace Fase 1:
+- No mueve los widgets de UI (form/list/modal/EntityRef selector)
+  a yahweh — eso es Fase 2.
+- No introduce un trait `MetaBackend` para desacoplar la lógica
+  de runtime de Nakui — eso es Fase 3.
+- No renombra el field `nakui_module_dir`. Se hará cuando aparezca
+  un segundo backend que también lo necesite.
+
+**Pendientes** (orden):
+1. **Fase 2**: extraer widgets render (form/list/modal/EntityRef
+   selector + helpers parse_field_value/render_value/etc.) a un
+   nuevo crate `yahweh-widget-meta-form` (o nombre similar).
+2. **Fase 3**: trait `MetaBackend` + thin shell — `nakui-ui` queda
+   reducido a una impl de backend wireada a `nakui-core`.
+3. **KCL → Nickel**: kcl_wrapper reemplazado por evaluación de
+   Nickel contracts.
+4. **card.k eliminado** (REFERENCE ONLY).
+
 ### feat(nakui-ui): migrar consumer al brazo unificado `brahman_cards::load_cards_from_dir`
 Primera consumer migration del brazo. `nakui-ui` ya no llama a
 `nakui_ui_schema::load_modules_from_dir` directamente — pasa por
diff --git a/Cargo.lock b/Cargo.lock
index d322400..542cb0b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1238,13 +1238,13 @@ name = "brahman-cards"
 version = "0.1.0"
 dependencies = [
  "brahman-card",
- "nakui-ui-schema",
  "nickel-lang",
  "nouser-card",
  "serde",
  "serde_json",
  "thiserror 2.0.18",
  "ulid",
+ "yahweh-meta-schema",
 ]
 
 [[package]]
@@ -6396,24 +6396,14 @@ dependencies = [
  "brahman-cards",
  "gpui",
  "nakui-core",
- "nakui-ui-schema",
  "serde_json",
  "tempfile",
  "uuid",
+ "yahweh-meta-schema",
  "yahweh-theme",
  "yahweh-widget-text-input",
 ]
 
-[[package]]
-name = "nakui-ui-schema"
-version = "0.1.0"
-dependencies = [
- "serde",
- "serde_json",
- "tempfile",
- "thiserror 2.0.18",
-]
-
 [[package]]
 name = "nanorand"
 version = "0.7.0"
@@ -12840,6 +12830,16 @@ dependencies = [
  "yahweh-theme",
 ]
 
+[[package]]
+name = "yahweh-meta-schema"
+version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_json",
+ "tempfile",
+ "thiserror 2.0.18",
+]
+
 [[package]]
 name = "yahweh-provider-fs"
 version = "0.1.0"
diff --git a/Cargo.toml b/Cargo.toml
index b0892c7..a4e8e12 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -52,6 +52,7 @@ members = [
     "crates/modules/ui_engine/libs/core",
     "crates/modules/ui_engine/libs/theme",
     "crates/modules/ui_engine/libs/bus",
+    "crates/modules/ui_engine/libs/meta-schema",
     "crates/modules/ui_engine/libs/providers/fs",
     "crates/modules/ui_engine/libs/providers/sqlite",
     "crates/modules/ui_engine/widgets/tree",
@@ -65,7 +66,6 @@ members = [
     # modules/nakui/ — ERP matemático (nakui absorbido)
     # ============================================================
     "crates/modules/nakui/core",
-    "crates/modules/nakui/ui-schema",
 
     # ============================================================
     # modules/nouser/ — explorador de Mónadas (nuevo)
diff --git a/crates/apps/nakui-ui/Cargo.toml b/crates/apps/nakui-ui/Cargo.toml
index a0922d4..3a0c684 100644
--- a/crates/apps/nakui-ui/Cargo.toml
+++ b/crates/apps/nakui-ui/Cargo.toml
@@ -7,7 +7,7 @@ description = "Nakui — runtime GPUI de la metainterfaz: carga module.json desd
 
 [dependencies]
 nakui-core = { path = "../../modules/nakui/core" }
-nakui-ui-schema = { path = "../../modules/nakui/ui-schema" }
+yahweh-meta-schema = { path = "../../modules/ui_engine/libs/meta-schema" }
 brahman-cards = { path = "../../core/brahman-cards" }
 yahweh-widget-text-input = { path = "../../modules/ui_engine/widgets/text_input" }
 yahweh-theme = { path = "../../modules/ui_engine/libs/theme" }
diff --git a/crates/apps/nakui-ui/src/main.rs b/crates/apps/nakui-ui/src/main.rs
index 5ab9d27..3f6b979 100644
--- a/crates/apps/nakui-ui/src/main.rs
+++ b/crates/apps/nakui-ui/src/main.rs
@@ -37,7 +37,7 @@ use nakui_core::event_log::{
 use brahman_cards::CardBody;
 use nakui_core::executor::Executor;
 use nakui_core::store::{MemoryStore, Store};
-use nakui_ui_schema::{
+use yahweh_meta_schema::{
     Action, FieldKind, FieldSpec, FormView, ListView, Module, View,
 };
 use serde_json::{json, Value};
diff --git a/crates/core/brahman-cards/Cargo.toml b/crates/core/brahman-cards/Cargo.toml
index bc47950..ac16228 100644
--- a/crates/core/brahman-cards/Cargo.toml
+++ b/crates/core/brahman-cards/Cargo.toml
@@ -15,7 +15,7 @@ thiserror = { workspace = true }
 ulid = { workspace = true }
 brahman-card = { path = "../brahman-card" }
 nouser-card = { path = "../../modules/nouser/card" }
-nakui-ui-schema = { path = "../../modules/nakui/ui-schema" }
+yahweh-meta-schema = { path = "../../modules/ui_engine/libs/meta-schema" }
 nickel-lang = "2.0.0"
 
 [dev-dependencies]
diff --git a/crates/core/brahman-cards/src/lib.rs b/crates/core/brahman-cards/src/lib.rs
index bf65906..1a6a529 100644
--- a/crates/core/brahman-cards/src/lib.rs
+++ b/crates/core/brahman-cards/src/lib.rs
@@ -48,8 +48,8 @@ use serde_json::Value;
 use thiserror::Error;
 
 pub use brahman_card::Card as EnteCard;
-pub use nakui_ui_schema::Module as UiModuleSpec;
 pub use nouser_card::MonadManifest;
+pub use yahweh_meta_schema::Module as UiModuleSpec;
 
 /// Estructura canónica única que consumen los downstream del sistema
 /// (UI runtime, storage, DHT, wire). Cada formato input se proyecta
@@ -59,7 +59,7 @@ pub use nouser_card::MonadManifest;
 /// (identidad legible + extensiones forward-compat); el body preserva
 /// el typing rico de cada dominio sin colapsarlos.
 // PartialEq se omite porque algunos body variants vienen de crates
-// que no lo implementan (MonadManifest, nakui_ui_schema::Module).
+// que no lo implementan (MonadManifest, yahweh_meta_schema::Module).
 // Si downstream necesita igualdad, comparar via JSON round-trip o
 // agregar PartialEq en los crates origen.
 #[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/crates/core/brahman-cards/src/readers.rs b/crates/core/brahman-cards/src/readers.rs
index 44b99cc..fbac969 100644
--- a/crates/core/brahman-cards/src/readers.rs
+++ b/crates/core/brahman-cards/src/readers.rs
@@ -114,11 +114,11 @@ impl CardReader for MonadJsonReader {
 }
 
 // ============================================================================
-// UiModule (nakui-ui-schema)
+// UiModule (yahweh-meta-schema)
 // ============================================================================
 
-/// Reader para el shape JSON de los `module.json` de la UI Nakui
-/// ([`nakui_ui_schema::Module`]).
+/// Reader para el shape JSON de los `module.json` de la metainterfaz
+/// ([`yahweh_meta_schema::Module`]).
 ///
 /// Heurística: tiene `entities` Y `views` Y `menu`. Es el shape más
 /// específico del repo, así que va primero en el orden default — si
diff --git a/crates/modules/nakui/ui-schema/Cargo.toml b/crates/modules/nakui/ui-schema/Cargo.toml
deleted file mode 100644
index e6627d2..0000000
--- a/crates/modules/nakui/ui-schema/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-name = "nakui-ui-schema"
-version.workspace = true
-edition.workspace = true
-license.workspace = true
-description = "Nakui UI metainterface schema: módulos declaran menús, listas y formularios como datos (JSON); el runtime los carga y renderiza sin código compilado por módulo."
-
-[dependencies]
-serde = { workspace = true }
-serde_json = { workspace = true }
-thiserror = { workspace = true }
-
-[dev-dependencies]
-tempfile = { workspace = true }
diff --git a/crates/modules/ui_engine/libs/meta-schema/Cargo.toml b/crates/modules/ui_engine/libs/meta-schema/Cargo.toml
new file mode 100644
index 0000000..6fffb20
--- /dev/null
+++ b/crates/modules/ui_engine/libs/meta-schema/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "yahweh-meta-schema"
+version.workspace = true
+edition.workspace = true
+license.workspace = true
+description = "Yahweh — meta-schema: descriptores declarativos de UI (entities, menús, listas, formularios, acciones) consumidos por widgets metainterfaz reusables. Independiente del backend: cualquier app que monte una UI dirigida por datos puede usarlo."
+
+[dependencies]
+serde = { workspace = true }
+serde_json = { workspace = true }
+thiserror = { workspace = true }
+
+[dev-dependencies]
+tempfile = { workspace = true }
diff --git a/crates/modules/nakui/ui-schema/src/lib.rs b/crates/modules/ui_engine/libs/meta-schema/src/lib.rs
similarity index 91%
rename from crates/modules/nakui/ui-schema/src/lib.rs
rename to crates/modules/ui_engine/libs/meta-schema/src/lib.rs
index 82dfd29..2af599c 100644
--- a/crates/modules/nakui/ui-schema/src/lib.rs
+++ b/crates/modules/ui_engine/libs/meta-schema/src/lib.rs
@@ -1,22 +1,22 @@
-//! Schema declarativo de la metainterfaz Nakui.
+//! Schema declarativo de la metainterfaz (yahweh meta-schema).
 //!
-//! Cada **módulo** Nakui (customers, products, sales, ...) declara
-//! aquí qué menús, vistas, listas y formularios expone, sin escribir
-//! código GPUI ni Rust. El runtime ([`nakui-ui` crate]) lee estos
-//! `module.json` desde un directorio y monta automáticamente la UI
-//! correspondiente.
+//! Cada **módulo** declara aquí qué menús, vistas, listas y
+//! formularios expone, sin escribir código GPUI ni Rust. Cualquier
+//! runtime de UI dirigida por datos (Nakui hoy, otros mañana) lo
+//! carga y monta la UI correspondiente.
 //!
 //! ## Filosofía
 //!
-//! - **UI como datos**: agregar un módulo = escribir un JSON. Ningún
-//!   recompile, ningún acoplamiento con el binario del runtime.
-//! - **Persistencia universal**: el runtime conecta cada vista al
-//!   `nakui_core::store::Store` actual; los formularios escriben
-//!   ops por la pipeline normal de Nakui (executor + event log).
-//! - **Schema primero, semántica después**: este crate sólo define
-//!   la *forma* de los manifests. Validación semántica
-//!   (referencias rotas a entities, campos faltantes, etc.) vive en
-//!   el runtime que lo carga, no acá.
+//! - **UI como datos**: agregar un módulo = escribir un JSON o un
+//!   `.ncl`. Ningún recompile, ningún acoplamiento con el binario
+//!   del runtime.
+//! - **Backend-agnostic**: este crate sólo describe la *forma* de
+//!   la UI. La conexión a un store/log/executor concretos vive en
+//!   el runtime que lo consume (ej: el meta-runtime de Nakui que
+//!   wirea esto a `nakui_core` + KCL post-checks).
+//! - **Schema primero, semántica después**: validación semántica
+//!   (referencias rotas a entities, campos faltantes, etc.) vive
+//!   en el runtime que lo carga, no acá.
 //!
 //! ## Anatomía de un módulo
 //!
@@ -47,7 +47,7 @@ use std::path::{Path, PathBuf};
 use serde::{Deserialize, Serialize};
 use thiserror::Error;
 
-/// Manifiesto de un módulo de la metainterfaz Nakui.
+/// Manifiesto de un módulo declarativo de UI.
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct Module {
     /// Identificador estable. Único dentro del directorio cargado.
@@ -66,20 +66,28 @@ pub struct Module {
     #[serde(default)]
     pub entities: Vec<EntitySpec>,
 
-    /// Path a un módulo nakui-core (directorio con `nsmc.json` +
-    /// schemas KCL + scripts Rhai). Cuando está set, el runtime
-    /// carga un `Executor` para ese path y permite que las acciones
-    /// `Morphism { name }` despachen al pipeline real
-    /// (compute → log → apply).
+    /// Path opaco al backend que va a manejar este módulo. Lo
+    /// interpreta el runtime concreto (no este schema).
+    ///
+    /// Convención actual de Nakui: directorio con `nsmc.json` +
+    /// schemas KCL + scripts Rhai. Cuando está set, el runtime
+    /// Nakui carga un `Executor` para ese path y permite que las
+    /// acciones `Morphism { name }` despachen al pipeline real
+    /// (compute → log → apply). Otro backend puede ignorar este
+    /// campo o darle un significado distinto.
     ///
     /// Path resuelto relativo al directorio del `module.json`
     /// o absoluto.
     ///
-    /// Si es `None`, las acciones `Morphism` quedan deshabilitadas
-    /// (toast informativo al usuario). Las acciones `SeedEntity`
-    /// siguen funcionando sin esto — son altas administrativas que
-    /// no necesitan validación de manifest.
-    #[serde(default)]
+    /// Si es `None`, los backends que requieren manifest deberían
+    /// degradar (toast informativo, deshabilitar morphisms, etc.);
+    /// los `SeedEntity` siguen funcionando — son altas
+    /// administrativas que no necesitan validación de manifest.
+    ///
+    /// Nombre conservado por compat con módulos ya escritos.
+    /// Renombrar a `backend_module_dir` o similar si emerge un
+    /// segundo backend que también lo use.
+    #[serde(default, alias = "backend_module_dir")]
     pub nakui_module_dir: Option<String>,
 
     /// Items del menú. Cada uno apunta a una key de `views`. Orden
diff --git a/crates/modules/nakui/ui-schema/tests/example_modules.rs b/crates/modules/ui_engine/libs/meta-schema/tests/example_modules.rs
similarity index 89%
rename from crates/modules/nakui/ui-schema/tests/example_modules.rs
rename to crates/modules/ui_engine/libs/meta-schema/tests/example_modules.rs
index 1e552c1..230b10c 100644
--- a/crates/modules/nakui/ui-schema/tests/example_modules.rs
+++ b/crates/modules/ui_engine/libs/meta-schema/tests/example_modules.rs
@@ -4,13 +4,16 @@
 //! corra `NAKUI_MODULES_DIR=examples/nakui-modules cargo run -p nakui-ui`
 //! va a obtener los 6 módulos cargados sin tocar nada.
 
-use nakui_ui_schema::{load_modules_from_dir, FieldKind, View};
+use yahweh_meta_schema::{load_modules_from_dir, FieldKind, View};
 
 fn examples_dir() -> std::path::PathBuf {
     // Tests corren desde el dir del crate; el repo root está dos
     // niveles arriba: crates/modules/nakui/ui-schema → repo.
+    // Tras el lift a yahweh, el crate vive en
+    // `crates/modules/ui_engine/libs/meta-schema`, así que el repo
+    // root queda 5 niveles arriba.
     let here = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
-    here.join("../../../..").join("examples/nakui-modules")
+    here.join("../../../../..").join("examples/nakui-modules")
 }
 
 #[test]
@@ -50,8 +53,8 @@ fn sales_engine_declares_nakui_module_dir_and_morphism() {
         "sales_engine debería declarar nakui_module_dir"
     );
     let has_morphism_view = sales.views.values().any(|v| match v {
-        nakui_ui_schema::View::Form(form) => {
-            matches!(form.on_submit, nakui_ui_schema::Action::Morphism { .. })
+        yahweh_meta_schema::View::Form(form) => {
+            matches!(form.on_submit, yahweh_meta_schema::Action::Morphism { .. })
         }
         _ => false,
     });