feat(card): Card::new(label) — alternativa segura a Default::default()

Cierra la trap documentada de Card::default() que devuelve id =
Ulid::nil(). Usar Card::default() viva colisionaba con cualquier otra
Card default-construida bajo el mismo id 00000...

La fix no es romper Default (sigue siendo determinista, requerido por
callers que lo usan como template para deserializacion y patterns de
busqueda) sino agregar un constructor explicito Card::new(label) que
asigna id = Ulid::new() + label provisto, manteniendo defaults seguros
en todo lo demas.

Pensado para struct-literals con override parcial:

    let card = Card {
        kind: CardKind::Data,
        payload: Payload::Embedded(json),
        ..Card::new("mi-modulo.algo")
    };

Refactor de call sites en codigo de produccion:
- brahman_sidecar::discovery::build_consumer_card
- nouser daemon::build_engine_card

Default queda con docstring expandida que apunta a Card::new para uso
"vivo". to_brahman_card en nouser-card NO se modifica porque asigna
el id estable de la Monada, no uno fresco.

Tests: 3 unitarios nuevos en brahman-card. 15 tests verdes (era 12).
This commit is contained in:
Sergio
2026-05-09 02:43:21 +00:00
parent 006640057a
commit 4c9e4c3962
4 changed files with 97 additions and 13 deletions
+2 -5
View File
@@ -727,16 +727,13 @@ fn embed_via(
/// Card del propio engine (kind=Ente). Es el "ser" que produce y
/// administra Mónadas; aparece en brahman-status junto a sus Mónadas.
fn build_engine_card() -> brahman_card::Card {
use brahman_card::{ulid::Ulid, Card, CardKind, Lifecycle, Payload, Priority, Supervision};
use brahman_card::{Card, CardKind, Lifecycle, Payload, Priority, Supervision};
Card {
schema_version: brahman_card::CARD_SCHEMA_VERSION,
id: Ulid::new(),
label: "brahman.nouser_engine".into(),
payload: Payload::Virtual,
supervision: Supervision::Delegate,
lifecycle: Lifecycle::Daemon,
priority: Priority::Normal,
kind: CardKind::Ente,
..Default::default()
..Card::new("brahman.nouser_engine")
}
}