prueba
This commit is contained in:
@@ -1,10 +1,18 @@
|
||||
# ============================================================================
|
||||
# rule.k — Triplet [Sujeto + Evento + Acción(Objeto)]. La gramática del
|
||||
# Cerebro del fractal. Cada regla es una sinapsis: cuando ocurre `when`,
|
||||
# el motor ejecuta `then` para todos los Entes que cumplen `scope`.
|
||||
# rule.k — REFERENCE ONLY. NOT LOADED.
|
||||
#
|
||||
# El motor en Rust las indexa por discriminante de EventKind para lookup
|
||||
# La gramática autoritativa de Rule vive en Rust:
|
||||
# crates/ente-brain/src/rules.rs
|
||||
# El loader (crates/ente-brain/src/loader.rs) sólo acepta JSON / JSONL.
|
||||
#
|
||||
# Conservado como notas de diseño humano-legibles del shape Rule:
|
||||
# Triplet [Sujeto + Evento + Acción(Objeto)]. Cada regla es una sinapsis:
|
||||
# cuando ocurre `when`, el motor ejecuta `then` para los Entes que cumplen
|
||||
# `scope`. El motor las indexa por discriminante de EventKind para lookup
|
||||
# en O(1). Las reglas son inmutables tras carga (Arc<Rule>).
|
||||
#
|
||||
# Si cambias el shape en Rust, sincroniza este archivo a mano (o
|
||||
# reemplázalo por JSON Schema generado vía `schemars`).
|
||||
# ============================================================================
|
||||
|
||||
schema Rule:
|
||||
|
||||
@@ -97,3 +97,76 @@ pub fn extract_rules_from_json(raw: &str) -> anyhow::Result<Vec<Rule>> {
|
||||
}
|
||||
Ok(rules)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::introspect::append_rule_jsonl;
|
||||
use crate::rules::{Action, EventKind, EventPattern, LogLevel, Rule, Scope};
|
||||
use ulid::Ulid;
|
||||
|
||||
fn sample_rule() -> Rule {
|
||||
Rule {
|
||||
id: Ulid::new(),
|
||||
priority: 5,
|
||||
when: EventPattern::Single { kind: EventKind::EnteSpawned },
|
||||
then: vec![Action::Log {
|
||||
level: LogLevel::Info,
|
||||
message: "test".into(),
|
||||
}],
|
||||
scope: Scope::default(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rules_from_array() {
|
||||
let r = sample_rule();
|
||||
let raw = format!("[{}]", serde_json::to_string(&r).unwrap());
|
||||
let parsed = extract_rules_from_json(&raw).expect("array parse");
|
||||
assert_eq!(parsed.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rules_from_object_with_array() {
|
||||
let r = sample_rule();
|
||||
let raw = format!(r#"{{"rules":[{}]}}"#, serde_json::to_string(&r).unwrap());
|
||||
let parsed = extract_rules_from_json(&raw).expect("object parse");
|
||||
assert_eq!(parsed.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rules_from_jsonl_with_comments_and_blanks() {
|
||||
let r1 = sample_rule();
|
||||
let r2 = sample_rule();
|
||||
let raw = format!(
|
||||
"# header comment\n\n{}\n# inline comment\n{}\n\n",
|
||||
serde_json::to_string(&r1).unwrap(),
|
||||
serde_json::to_string(&r2).unwrap()
|
||||
);
|
||||
let parsed = extract_rules_from_json(&raw).expect("jsonl parse");
|
||||
assert_eq!(parsed.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_rule_jsonl_roundtrip() {
|
||||
let dir = tempdir_unique();
|
||||
let path = dir.join("rules.jsonl");
|
||||
let r1 = sample_rule();
|
||||
let r2 = sample_rule();
|
||||
append_rule_jsonl(&path, &r1).expect("append 1");
|
||||
append_rule_jsonl(&path, &r2).expect("append 2");
|
||||
let raw = std::fs::read_to_string(&path).expect("read back");
|
||||
let parsed = extract_rules_from_json(&raw).expect("roundtrip parse");
|
||||
assert_eq!(parsed.len(), 2);
|
||||
assert_eq!(parsed[0].id, r1.id);
|
||||
assert_eq!(parsed[1].id, r2.id);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
fn tempdir_unique() -> std::path::PathBuf {
|
||||
let base = std::env::temp_dir();
|
||||
let p = base.join(format!("ente-brain-loader-{}", Ulid::new()));
|
||||
std::fs::create_dir_all(&p).unwrap();
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# ============================================================================
|
||||
# card.k — Genética del Ente. Esquema KCL para EntityCard.
|
||||
# card.k — REFERENCE ONLY. NOT LOADED.
|
||||
#
|
||||
# Esta es la gramática autoritativa: cualquier Card que se cargue al fractal
|
||||
# debe pasar la validación de este esquema. El boot de PID 1 acepta JSON que
|
||||
# cumple este shape (KCL exporta JSON tras validar `check:`).
|
||||
# La validación canónica de EntityCard vive en Rust:
|
||||
# crates/ente-card/src/lib.rs :: EntityCard::validate()
|
||||
# El loader (crates/ente-brain/src/loader.rs) sólo acepta JSON.
|
||||
#
|
||||
# Para validar manualmente:
|
||||
# kcl run examples/my-card.k --schema schema/card.k
|
||||
#
|
||||
# Cada `check:` es invariante de fractal. Romperlo = Card inválida = no boot.
|
||||
# Este archivo se conserva como notas de diseño legibles para humanos sobre
|
||||
# las invariantes que `validate()` debe garantizar. Si modificas el shape
|
||||
# en Rust, sincroniza este archivo a mano (o reemplázalo por JSON Schema
|
||||
# generado vía `schemars`).
|
||||
# ============================================================================
|
||||
|
||||
# ---------- Identidad ----------
|
||||
|
||||
Reference in New Issue
Block a user