feat: Crossreferencia — Card.references como grafo del fractal
Las Cards ahora declaran sus relaciones con otras Cards. El Engine
posee Mónadas; las Mónadas declaran que son poseídas por el Engine.
- brahman-card:
- RelationshipKind { Owns, OwnedBy, Processes, ProcessedBy, Sibling }
- CardReference { kind, target_id: Ulid, target_label: String }.
target_label es cache para que la UI renderee sin resolver.
- Card.references: Vec<CardReference> + espejo en WireCard.
Conversiones From propagan.
- brahman-broker::BrokeredCard propaga references.
- brahman-status imprime "ref OwnedBy → label (id)" por sesión.
- nouser daemon: cada Mónada publicada añade OwnedBy apuntando al
engine. Declaración unilateral — el engine no necesita conocer
Mónada IDs de antemano.
Validación end-to-end:
$ ente-zero & nouser daemon crates/core
$ brahman-status
Sessions (6):
[ente] brahman.nouser_engine
[data] brahman-handshake/src
ref OwnedBy → brahman.nouser_engine (01K...)
[data] ente-brain/src
ref OwnedBy → brahman.nouser_engine (01K...)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -166,9 +166,11 @@ fn cmd_daemon(args: &[String]) -> Cmd {
|
||||
|
||||
// 1. El propio engine se presenta como Ente.
|
||||
let engine_card = build_engine_card();
|
||||
let engine_id = engine_card.id;
|
||||
let engine_label = engine_card.label.clone();
|
||||
eprintln!(
|
||||
"nouser daemon: publicando engine '{}' (kind=Ente)",
|
||||
engine_card.label
|
||||
"nouser daemon: publicando engine '{}' (kind=Ente, id={})",
|
||||
engine_label, engine_id
|
||||
);
|
||||
brahman_sidecar::spawn(engine_card);
|
||||
|
||||
@@ -181,10 +183,18 @@ fn cmd_daemon(args: &[String]) -> Cmd {
|
||||
db.monad_count()
|
||||
);
|
||||
|
||||
// 3. Cada Mónada se presenta como Card de tipo Data.
|
||||
// 3. Cada Mónada se presenta como Card de tipo Data, declarando
|
||||
// su relación OwnedBy con el engine. La UI puede entonces
|
||||
// cruzar referencias para reconstruir el grafo
|
||||
// "nouser_engine posee Mónada X" sin lookup adicional.
|
||||
let mut handles = Vec::with_capacity(db.monad_count());
|
||||
for monad in db.monads() {
|
||||
let card = monad.to_brahman_card();
|
||||
let mut card = monad.to_brahman_card();
|
||||
card.references.push(brahman_card::CardReference {
|
||||
kind: brahman_card::RelationshipKind::OwnedBy,
|
||||
target_id: engine_id,
|
||||
target_label: engine_label.clone(),
|
||||
});
|
||||
match brahman_sidecar::spawn_with_handle(brahman_sidecar::SidecarConfig::new(card)) {
|
||||
Ok(h) => handles.push(h),
|
||||
Err(e) => eprintln!(
|
||||
|
||||
Reference in New Issue
Block a user