# Changelog Registro cronológico de cambios sustantivos en el monorepo Brahman. Cada entrada lista las acciones concretas tras un commit; para detalles de ratio/diff ver `git show `. ## 2026-05-08 ### feat(broker): priority contexts — biases per-contexto operativo - `brahman-card::ContextBias { pin_to: Option, priority_offset: i8 }` declara un override per-contexto. - `Card.priority_contexts: BTreeMap` y mismo en `WireCard` (cruza el wire). Las conversiones `From` lo propagan. - `BrokerConfig.current_context: Option`. Cuando el broker corre bajo un contexto y una Card declara biases para ese nombre, se aplican: - Como **consumidor**: `pin_to` sobreescribe el `Flow.pin_to` estático. - Como **productor**: `priority_offset` se suma a la priority base (clamp en `[Low=0, Critical=3]`) para el ranking. - `BrokeredCard` propaga `priority_contexts`. `find_producer_for` usa `effective_priority(card)` y `effective_pin(card, input)` antes de los tiebreaks. - `brahman-admin::AdminConfig.current_context` + `StatusSnapshot.current_context` espejan el contexto activo. `brahman-status` lo imprime como `Context: ` justo debajo de `Init: ...`. - `ente-zero` lee `BRAHMAN_BROKER_CONTEXT` env var y la propaga al broker y al admin. Sin var, biases per-contexto inactivos. - 4 tests nuevos en brahman-broker: `context_priority_offset_lifts_producer_above_alphabetic_winner`, `context_pin_to_overrides_static_pin`, `unknown_context_no_op`, `priority_offset_clamps_to_critical`. - Validación end-to-end: `BRAHMAN_BROKER_CONTEXT=test ente-zero` → `brahman-status` muestra `Context: test`. ### feat(card): WireCard + extensions — forward-compat sin romper postcard - `Card.extensions: BTreeMap` restaurado con `#[serde(flatten, default, skip_serializing_if = is_empty)]`. Los campos JSON/TOML desconocidos sobreviven el roundtrip de archivos. - Nuevo `WireCard`: proyección postcard-friendly (sin `extensions`, `genesis: Vec` recursivo). Conversiones `From` y `From` con descarte/recreación de extensions. - `brahman-handshake::Hello.card` pasa de `Card` a `WireCard`. Client hace `card.into()` antes de enviar; Server hace `hello.card.into()` para volver a Card antes de validar/registrar. - 3 tests nuevos en brahman-card: `extensions_preserved_in_json_roundtrip`, `wire_card_roundtrip_strips_extensions`, `wire_card_postcard_friendly` (postcard encode/decode efectivo). - brahman-card gana `postcard` como dev-dep para el último test. - Contrato documentado: extensions = anotaciones locales que NO cruzan al Init; sólo viven en archivos. ### `9420eae` chore: limpia warnings dead-code en arje (commit del usuario) - `ente-zero/src/events.rs`: `#![allow(dead_code)]` a nivel módulo — es vocabulario de eventos con variantes/campos reservados para flujos no cableados aún (CapabilityRequested, ShutdownReason::Signal, CapabilityGrant::{Granted, Denied, QuotaExceeded}, ExitStatus fields). - `ente-zero/src/graph/mod.rs`: comentado el re-export ahora innecesario de `SHUTDOWN_GRACE`. `DEFAULT_GRANT_TTL` con `#[allow(dead_code)]` + nota "reservado para capability granting". - `ente-zero/src/graph/capabilities.rs`: `renew_grant` con `#[allow(dead_code)]` (capability renewal pendiente). - `ente-kernel/src/surface.rs`: drop de `use anyhow::Context` (no se usaba). - `ente-hostnamed-compat/src/main.rs`: drop de `Connection` (no se usaba). - `ente-polkit-compat/src/main.rs`: `PolicyDecision.source` con `#[allow(dead_code)]` (sólo aparece en `Debug` para logging). - `cargo check --workspace`: 17 warnings → 0. ### feat(sidecar): WIT al sidecar — módulos conscientes vivos - `brahman-card::WitInterface` deriva `Serialize`, `Deserialize`, `PartialEq`, `Eq` para cruzar el wire postcard. - `brahman-handshake::Hello` lleva `wit: Option`. Server usa `ResolvedCard::from_conscious` cuando viene presente, `from_agnostic` cuando no. - `brahman-handshake::Client::connect` queda como wrapper agnóstico de `connect_with(path, card, wit: Option)`. - `brahman-broker::Broker::register` ahora toma `Option` como tercer arg. `BrokeredCard` guarda el wit. 25 sitios de tests actualizados con `, None`. - `brahman-sidecar::SidecarConfig` con campo `wit`. Helpers nuevos: `SidecarConfig::new(card).with_wit(wit)` y `spawn_conscious(card, wit)`. El log `attached` reporta `conscious=true|false`. - `brahman-status` muestra marker 🧠 + sección `wit:` (package/world, imports, exports) por sesión consciente. - Example nuevo `crates/shared/brahman-sidecar/examples/presence-conscious.rs`: toma label + path .wit (default `shared_wit/protocol.wit`), parsea con brahman-card-wit, spawna sidecar consciente. - Validado end-to-end: ``` $ presence-conscious demo.conscious shared_wit/protocol.wit & $ brahman-status Sessions (1): 01K... demo.conscious 🧠 lifecycle=Daemon wit: brahman:protocol@0.1.0 / module imports: types, handshake, lifecycle exports: run ``` ### feat(core): brahman-card-wit — extractor opcional de contratos WIT - Crate nuevo `crates/core/brahman-card-wit` con `wit-parser = "0.230"`. - API: `parse_wit(source)` y `parse_wit_file(path)` devuelven `Vec` (uno por `world` declarado). - Interfaces importadas/exportadas (no sólo funciones) se resuelven por nombre via `resolve.interfaces[id].name`. - Example `crates/core/brahman-card-wit/examples/brahman-wit-info.rs` CLI: `brahman-wit-info shared_wit/protocol.wit` → lista paquete, worlds, imports y exports. - 4 tests: inline, archivo real (`shared_wit/protocol.wit`), parse error, world vacío. - Validado contra `protocol.wit`: detecta worlds `module` y `admin-host` con sus imports/exports correctos. ### `7b589b8` chore: agrega CHANGELOG.md retroactivo - `CHANGELOG.md` en la raíz con los 11 commits previos documentados acción por acción. A partir de este punto, cada cambio sustantivo actualiza también este archivo en el mismo commit. ### `8a83a26` feat(handshake): notificación push de matches - Frame `MatchEvent { kind: Available | Lost, ... }` añadido al protocolo. - `Session::run_post_handshake` usa `tokio::select!` para multiplexar reads del cliente y un canal `mpsc` push del server. - Server: `SessionTxTable` (Arc>>>) y `LastMatches` para diff por sesión. `broadcast_match_diffs` corre tras cada `register` y `unregister`, emite sólo los cambios. - Capacity del canal push: 32 (ephemeral, `try_send` non-blocking). - Client: `VecDeque` interno, `take_event()` (non-blocking) y `await_event(timeout)`. `ping()` ahora drena MatchEvents intermedios hasta encontrar el Pong. - Example `crates/core/brahman-handshake/examples/subscriber.rs`. - Test `match_event_pushed_on_producer_arrival` (handshake integ 6→7). ### `70a7a0d` feat: segundo módulo (nakui) + admin API + brahman-status - Crate nuevo `crates/shared/brahman-sidecar` (DRY del thread + tokio + ping loop). API: `spawn(card)` / `spawn_with_handle(config)`. - `nakui` cmd_run llama `brahman_sidecar::spawn` antes de `run_server`. Card: lifecycle Daemon, supervision Restart, flow `command` (json) / `report` (json). - Crate nuevo `crates/core/brahman-admin` con `StatusSnapshot` JSON line-delim, `AdminServer` y `client::query`. - ente-zero levanta también el AdminServer en `primordial_loop`. - Example `crates/shared/brahman-sidecar/examples/presence.rs` (módulo dummy long-lived parametrizable por label). - Example `crates/core/brahman-admin/examples/brahman-status.rs` (CLI que pretty-printa el snapshot). - `brahman-broker`: `BrokeredCard` ahora incluye `lifecycle`. `Endpoint` y `Match` derivan `Serialize`/`Deserialize`. Nuevo `Broker::cards()` iterador. - `brahman-card`: `pub use ::ulid` para que módulos no dependan de ulid. - yahweh-shell migrado al sidecar compartido (96→53 LOC). ### `595f68e` feat(yahweh-shell): primer módulo brahman vivo - yahweh-shell spawnea sidecar antes de `Application::new()`. - Card declarada: label `brahman.ui_engine`, lifecycle Widget, supervision Delegate, payload Virtual, flow input `render-data` (json) / output `user-intent` (json). - Sidecar en thread aparte con tokio current_thread runtime, desacoplado del runtime GPUI. ### `df9d10c` feat(ente-zero): enchufa el handshake server al Init real - ente-zero levanta `brahman_handshake::server::Server::bind` en `primordial_loop` después del ente-bus, con degradación grácil si bind falla (mismo patrón que uevents). - Nuevo módulo `brahman-handshake/src/transport.rs`: helper `default_socket_path()` con resolución `BRAHMAN_INIT_SOCKET` → `XDG_RUNTIME_DIR` → `TMPDIR`. - Example `crates/core/brahman-handshake/examples/probe.rs`. - Validación end-to-end manual: probe contra ente-zero vivo imprime `HelloAck: session=... init_attached=true`. ### `07d77a3` feat(handshake): integra el broker con el ciclo de sesiones - `ServerConfig` acepta `Option>>`. - `register_session` indexa la Card en el broker y la `SessionRegistry` antes de emitir HelloAck. - `Session::handle` refactor a `do_handshake → run_post_handshake → cleanup` con cleanup unificado (broker + sessions). - Tests integ nuevos: `broker_registers_and_unregisters_with_session` y `broker_matches_two_live_modules`. - Fix colateral: `brahman-card::TypeRef` pasa de internally-tagged (`#[serde(tag = "kind")]`) a externally-tagged. Postcard no soporta internally-tagged en formatos no self-describing. JSON cambia de `{"kind":"primitive","name":"x"}` a `{"primitive":{"name":"x"}}`. ### `5091106` feat(core): brahman-broker — matching híbrido - Crate nuevo `crates/core/brahman-broker`. - 3 estrategias de matching: `Exact`, `Structural`, `ExactThenStructural` (default). Devuelven `Match::via` con la estrategia que ganó. - Override `pin_to`: el consumer pide un productor por label; si la pista no resuelve, cae en type-search. - Tiebreak por `Card.priority` desc, luego `label` asc (estable y determinista). - API: `register`, `unregister`, `find_producer_for`, `all_matches`, `cards`, `sessions`, `len`, `is_empty`. - 11 tests (matching, pin_to, priority, no-self-loops, all-matches). ### `814390f` feat(core): brahman-handshake — protocolo runtime - Crate nuevo `crates/core/brahman-handshake` con server y client Rust↔Rust sobre Unix socket. - Frames length-prefixed (4 bytes LE) + cuerpo postcard. - Mensajes: `Hello`, `HelloAck`, `Ping`, `Pong`, `Farewell`, `Error`. - `MAX_FRAME_BYTES = 4 MiB` para evitar reservas absurdas. - Tradeoff: drop `extensions`/`extra` de Card por incompat postcard ↔ `serde_json::Value`. Forward-compat queda en `schema_version` + `protocol_version` negotiation. - 4 tests integ + 1 unit en codec. ### `ed0e973` refactor(arje): migra ente-card a re-export de brahman-card - `ente-card/src/lib.rs` reescrito como crate-shim de re-export (327 LOC → 25 LOC). - `EntityCard` ≡ `brahman_card::Card` por type alias. - `ente-card/Cargo.toml`: deps reducidas a `brahman-card`. - `Card` impl `Default` (Ulid::nil(), label vacío) para que `..Default::default()` funcione en struct-literals. - 4 sitios en `ente-zero/src/seed.rs` actualizados con `..Default::default()` para los campos aditivos. - Los 21 consumidores arje compilan sin tocar fuente. ### `0feba74` feat(core): brahman-card — Tarjeta canónica híbrida - Crate nuevo `crates/core/brahman-card`. - Hereda de arje: `id: Ulid`, `lineage`, `Capability` tipado, `Payload::{Wasm, Native, Virtual, Legacy}`, `SomaSpec` (namespaces, cgroups, rlimits, cpu_affinity), `Supervision` (Restart con backoff, OneShot, Delegate), `genesis` recursivo. - Aditivo brahman: `Permissions` enumerados (`NetworkingPolicy`, `FsPolicy`, `IpcPolicy`), `Lifecycle` ortogonal a Supervision, `Priority` de scheduling, `Flows` con `TypeRef` discriminado (Primitive | Wit), `pin_to` opcional. - `TrustLevel` derivado de `Permissions` (no declarado). - `ResolvedCard { card, wit: Option, trust }`. - Soporta JSON (canónico) + TOML (auto-detectado por extensión). - 8 tests incluido `arje_seed_format_compatible` que valida que el JSON de arje sigue parseando con defaults para los aditivos. ### `4d50bfc` chore: absorbe nakui (ERP matemático) en modules/nakui - `~/nakui` → `crates/modules/nakui/{core,modules}`. - `core/`: el crate `nakui-core` con 4 bins (nakui, demo, inventory_demo, sales_demo) y tests. - `modules/{inventory,sales,treasury}/`: data declarativa (`nsmc.json`, `schema.k`, `morphisms/`) que el crate consume. No son crates Cargo. - Deps directas (no `workspace = true`): thiserror v1, surrealdb, rhai, petgraph. No conflicto con el resto del workspace. ### `53dbdf0` chore: monorepo inicial con arje + minga + yahweh absorbidos - 45 crates absorbidos en 4 ejes: - `crates/core/`: 24 crates de arje (Init systemd-compatible: `ente-card`, `ente-zero`, `ente-kernel`, `ente-bus`, `ente-cas`, `ente-soma`, `ente-wasm`, `ente-snapshot`, `ente-brain`, `ente-echo`, `ente-policy-provider`, + 12 `*-compat`). - `crates/modules/semantic_dht/`: 5 crates de minga (`minga-core` con AST/CAS/MST, `minga-p2p` con libp2p Kad, `minga-store`, `minga-vfs`, `minga-cli`). - `crates/modules/ui_engine/`: 11 crates de yahweh (libs/{core, theme, bus, providers}, widgets/{tree, splitter, tabs, tiled, container_core, text_input}). - `crates/apps/`: 5 crates de yahweh (file_explorer, database_explorer, text_viewer, image_viewer, yahweh-shell). - `shared_wit/protocol.wit` con handshake/lifecycle inicial. - `Cargo.toml` unificado: thiserror bumped a 2 (transparente para arje), tokio "full", paths intra-workspace de yahweh redirigidos. - `cargo check --workspace`: 0 errores (sólo dead-code warnings preexistentes en ente-zero).