chore: absorbe nakui (ERP matemático) en modules/nakui

- crates/modules/nakui/core/: el crate nakui-core (4 bins, tests).
  Deps directas (serde, rhai, surrealdb, petgraph, sha2, uuid, tokio,
  thiserror v1) — no convertidas a workspace = true en esta pasada.
- crates/modules/nakui/modules/{inventory,sales,treasury}/: datos
  declarativos del dominio (nsmc.json, schema.k, morphisms/) que el
  crate consume — no son crates.

cargo check -p nakui-core: 0 errores.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-05-08 05:49:58 +00:00
parent 53dbdf0f1d
commit 4d50bfc587
49 changed files with 11953 additions and 40 deletions
@@ -0,0 +1,19 @@
// EVIL: creates a Movimiento with monto = -1, violating schema.k:
// check: monto > 0
// Schema check on the Created record (KclPostCreate) must reject this.
let mov_id = input.params.mov_id;
[
#{
op: "create",
entity: "Movimiento",
id: mov_id,
data: #{
id: mov_id,
caja_id: input.ids.caja,
monto: -1,
tipo: "in",
timestamp: "2026-05-04T00:00:00Z",
memo: "evil",
},
},
]
@@ -0,0 +1,9 @@
// EVIL: writes to a Caja id that wasn't declared in inputs.
// The phantom id is passed via params to keep the script syntactically valid.
[
#{
op: "set",
path: #{ entity: "Caja", id: input.params.phantom_id, field: "saldo" },
value: 0,
},
]
@@ -0,0 +1,14 @@
// EVIL: subtracts from BOTH cajas. Same currency, so the conservation rule
// (Σ Δ Caja.saldo group_by currency = 0) catches it.
[
#{
op: "set",
path: #{ entity: "Caja", id: input.ids.source, field: "saldo" },
value: input.states.source.saldo - 100,
},
#{
op: "set",
path: #{ entity: "Caja", id: input.ids.dest, field: "saldo" },
value: input.states.dest.saldo - 1,
},
]
@@ -0,0 +1,7 @@
// Deletes its primary input. The kernel must:
// - accept the Delete op (token = "Caja", in writes)
// - skip the per-input KCL post-check (entity no longer exists)
// - allow apply to remove the record cleanly
[
#{ op: "delete", entity: "Caja", id: input.ids.caja },
]
@@ -0,0 +1,10 @@
// EVIL: tries to write `Stock.cantidad` using a Caja's UUID. The id matches
// a tracked role but the entity does not — the capability check must reject
// with a `<entity-mismatch>` token rather than letting it through.
[
#{
op: "set",
path: #{ entity: "Stock", id: input.ids.caja, field: "cantidad" },
value: 0,
},
]