Files
brahman/crates/modules/nouser/core/src/lib.rs
T
Sergio 2ae888bc8f feat(explorer+daemon): discovery dinamico via broker + query socket
Cierra el "explorer encuentra al daemon de forma totalmente dinamica"
del meta-plan. La UI deja de hardcodear el socket admin: descubre al
daemon nouser via MatchEvent::Available del broker y le consulta sus
Monadas directo.

Pipeline end-to-end:
- Daemon publica engine Card con service_socket = $XDG_RUNTIME_DIR/
  nouser-engine.sock y flow.output = monad-list:json.
- Daemon binda Unix socket en ese path con listener blocking que
  sirve nouser_card::query::QueryRequest::ListMonads, responde
  ListMonadsResponse { engine, monads: Vec<MonadView> }.
- Explorer construye consumer Card con flow.input matched,
  brahman_sidecar::await_provider_blocking le devuelve el socket,
  y nouser_core::engine_socket::client::list_monads lo consulta.
- Cachea el socket; cualquier fallo de query lo invalida y la
  proxima iteracion re-descubre.

Wire types nuevos en nouser_card::query:
- QueryRequest::ListMonads
- ListMonadsResponse { engine: EngineInfo, monads: Vec<MonadView> }
- MonadView: proyeccion slim de MonadManifest SIN centroid ni
  members (KB que no tienen por que viajar cada poll).
- transport::default_socket_path() con env override.

Listener en nouser_core::engine_socket: spawn_listener + client
blocking con QueryError tipado. 3 tests integracion verdes.

Refactor explorer:
- Drop dep brahman-admin, add brahman-sidecar/nouser-card/nouser-core.
- State: socket cache + snapshot + socket_source informativo.
- TickOutcome enum desacopla la I/O del UI.

Trade-offs: polling 2s (no streaming — broker no empuja Data cards
hoy), re-discovery full en error (discovery es barato).

Tests: 10 (nouser-card +3 query) + 27 (nouser-core +3 engine_socket)
+ 4 (sidecar) verdes. Explorer compila clean.
2026-05-09 03:08:20 +00:00

35 lines
1.1 KiB
Rust

//! `nouser-core` — el explorador de Mónadas.
//!
//! Implementa la pipeline determinista descrita en el diseño de Kairos:
//!
//! 1. [`scanner`]: recorre directorios y emite [`FileEntry`] (sin tocar
//! contenido en Phase 0 — sólo metadatos).
//! 2. [`cluster`]: agrupa archivos en [`MonadManifest`] usando
//! heurísticas (parent dir + extensión dominante). 0 LLM.
//! 3. [`db`]: store en memoria con índices files↔monads.
//!
//! Pipeline:
//! ```text
//! scan_directory(path)
//! → Vec<FileEntry>
//! → cluster::by_directory(min_files=N)
//! → Vec<MonadManifest>
//! → MonadDb::ingest(...)
//! ```
//!
//! Lo importante: en este crate no hay IA, no hay embeddings. Es la
//! capa determinista que cubre el 90% de los casos. Los embeddings
//! (`Phase C`) y Nous (`Phase D`) se enchufan después como módulos
//! separados que producen flows brahman.
#![forbid(unsafe_code)]
#![warn(rust_2018_idioms)]
pub mod cluster;
pub mod db;
pub mod embed;
pub mod engine_socket;
pub mod scanner;
pub use nouser_card::*;