feat(nouser): Phase A — mecanismo determinista de Mónadas

Primer trozo de Nouser/Kairos: explorador de Mónadas como agrupaciones
semánticas sobre el filesystem, sin tocar IA todavía. Cubre el 90% de
los casos con heurísticas puras.

Crates nuevos:

crates/modules/nouser/card:
- MonadManifest: la Tarjeta de Presentación de una Mónada. Espejo
  conceptual de brahman::Card pero para datos: id (Ulid), label,
  summary, centroid (vacío en Phase A), keywords, cardinality, entropy
  [0,1], dominant_lens (Grid|Code|Gallery|Database|Markdown|Tree),
  pins, members, timestamps, extensions (forward-compat).
- Diferencia explícita en docs: brahman::Card describe entidades
  runtime con payload/soma/supervision; MonadManifest describe una
  agrupación de datos sin proceso atrás.
- Validación: schema_version, label no vacío, entropy en rango,
  cardinality consistente con members.len().
- 6 tests (validación + JSON roundtrip).

crates/modules/nouser/core:
- scanner::scan_directory: walkdir → Vec<FileEntry> con metadatos.
  Skipea hidden por default; configurable max_depth y follow_links.
- cluster::by_directory: agrupa archivos por parent dir, mínimo 3
  para promover a Mónada (configurable). Computa keywords (top-N
  extensiones por freq + alfabético), elige Lens dominante por
  extensión más frecuente, entropía de Shannon normalizada.
- db::MonadDb: store en memoria con índices BTreeMap.
  resolve_members filtra IDs huérfanos.
- bin nouser con subcomandos scan, show, json. Env var
  NOUSER_MIN_FILES para el threshold.
- 13 tests (4 scanner + 6 cluster + 3 db).

Demo end-to-end:

  $ nouser scan crates
  scan: 255 archivos en crates, 19 mónadas (min_files=3)
    [01KR4C13] src       card=12  ent=0.00  lens=Code  keywords: rs
    [01KR4C13] tests     card=14  ent=0.00  lens=Code  keywords: rs
    [01KR4C13] fixtures  card=5   ent=0.00  lens=Grid  keywords: rhai

Pendientes (anotados en CHANGELOG, no urgentes):
- Phase B: bin nouser daemon que sidecarea a brahman-init.
- Phase C: pseudo-embeddings de metadatos + atracción por centroide.
- Phase D: módulo nouser-nous para el LLM real, swappable por
  priority_contexts (mock-nous en test, real-nous en prod).
- Polish: labels con 2-3 componentes del path.

cargo check --workspace: 0 errores, 0 warnings.
Tests acumulados: 58.

CHANGELOG.md actualizado.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-05-08 18:03:49 +00:00
parent bbb9a9d2f5
commit 7bdc26e61a
11 changed files with 1226 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
//! `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 scanner;
pub use nouser_card::*;