Files
sergio 550c98f275 refactor(monorepo): reorganización lógica + renames + SDDs + split CHANGELOG
Reorganización física de crates/:
- core/ (mezclaba 6 propósitos) se divide en protocol/, init/, runtime/, compat/
- shared/ (3 crates) se redistribuye en protocol/ e init/
- lapaloma (sub-módulo de ui_engine) se promueve a modules/pineal/

Renames de proyectos:
- shipote → shuma (runtime de sandboxes)
- nouser → akasha (explorador de Mónadas)
- yahweh → nahual (motor GPUI, antes ui_engine/)
- lapaloma → pineal (data-viz agnóstica)

Fraccionamiento UI → core agnóstico:
- vista-core (DeckState + snap, 175 LOC, 5 tests verdes)
- barra-core (Task + render_html + sanitize, 90 LOC, 5 tests verdes)
- vista-web y barra-web ahora son thin DOM bindings

Documentación nueva:
- 16 SDDs por subdirectorio (≤80 LOC c/u): protocol/init/runtime/compat
  + 10 módulos + apps/
- docs/STATUS.md con cifras reales por proyecto
- docs/ROADMAP.md con plan a finalización (6 hitos, ~6-8 semanas)
- CHANGELOG.md particionado en docs/changelog/<proyecto>.md (7 buckets)

Automatización:
- scripts/reorg.py — script idempotente que: git mv directorios, renombra
  package names, recomputa path = refs, reescribe imports rust, actualiza
  workspace Cargo.toml. Soporta --dry-run.
- scripts/split-changelog.py — particiona CHANGELOG por componente.

Validación:
- cargo check --workspace pasa (124 crates + 2 nuevos cores).
- 10 tests adicionales (5 en vista-core + 5 en barra-core) verdes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 14:48:34 +00:00

4.0 KiB

Changelog — misc

Entradas que no encajan en otro proyecto (chore, ci, gitignore, etc.).

chore(.gitignore): excluir .claude/ (state local de Claude Code)

Iter 18. Side cleanup tras debugging: .claude/ aparecía en git status cada sesión (contenía scheduled_tasks.lock y settings.local.json, ambos local-only). Excluido para que no se commitee accidentalmente y para que git status quede limpio.

Investigación previa que motivó el cleanup: persiguiendo un supuesto deadlock en drift_check_surfaces_expected_per_record_diffs con eprintlns/macro de log a archivo en drift.rs y run.rs. Conclusión: no hay deadlock — pasa cleanly aislado, en suite nakui-core, y en cargo test --workspace. El "hang" original venía de procesos cargo y test-binaries huérfanos de sesiones anteriores compitiendo por el build lock. Source restaurado, ningún cambio funcional. Memoria project_drift_hang.md reescrita con el playbook correcto.

feat(explorer+daemon): discovery dinámico vía broker + query socket

La UI deja de hardcodear el socket admin: ahora descubre al daemon nouser vía MatchEvent::Available del broker brahman y le consulta sus Mónadas directo, sin pasar por brahman-admin. Cierra el "explorer encuentra al daemon de forma totalmente dinámica" del meta-plan.

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 un Unix socket en ese path y monta un listener blocking que sirve nouser_card::query::QueryRequest::ListMonads, responde ListMonadsResponse { engine, monads: Vec<MonadView> }.
  • Explorer construye un consumer Card con flow.input = monad-list:json vía brahman_sidecar::build_consumer_card, llama await_provider_blocking(card, 3s) y recibe el socket descubierto.
  • Cachea ese socket; cada poll (2s) llama nouser_core::engine_socket::client::list_monads(socket, 2s). Fallo de query → invalida cache → próximo tick re-descubre.

Wire types nuevos en nouser_card::query:

  • QueryRequest::ListMonads (single variant por ahora).
  • ListMonadsResponse { engine: EngineInfo, monads: Vec<MonadView> }.
  • MonadView: proyección slim de MonadManifest SIN centroid ni members — la UI no los necesita y eran KB por Mónada que no tenían por qué viajar cada poll.
  • transport::default_socket_path() con env override NOUSER_ENGINE_SOCKET.
  • Const FLOW_MONAD_LIST = "monad-list", FLOW_TYPE_NAME = "json".

Listener en nouser_core::engine_socket:

  • spawn_listener(config, db) arma std::os::unix::net::UnixListener en thread blocking dedicado. Frecuencia esperada (UI cada 2s) no amerita tokio.
  • client::list_monads(socket, timeout) — cliente blocking con QueryError tipado (Connect / Io / Serde / Daemon / Timeout / Empty).
  • 3 tests integración: roundtrip vacío, Mónadas reales, request inválido devuelve ErrorResponse.

Refactor explorer:

  • Drop dep brahman-admin, add deps brahman-sidecar, nouser-card, nouser-core.
  • State: socket: Option<PathBuf> cache + snapshot: Option<ListMonadsResponse>
    • socket_source: "discovery"|"cache" (sólo informativo).
  • Tick: tick(prior_socket) separado del UI, devuelve un enum TickOutcome::{Ok, DiscoveryFailed, QueryFailed}. Cualquier fallo invalida la cache → re-discovery automática.
  • Header reformulado: Engine 'nouser_engine' · N mónada(s) · socket: /... (cache|discovery) · watching: /tmp/x.
  • Render pintado de un engine card + Mónadas, sin ya iterar BrokeredCard del admin.

Trade-offs aceptados:

  • Polling 2s (no streaming). El broker no empuja cambios de Data cards hoy; agregar streaming requiere extender el protocolo handshake. Para snapshot UI, polling 2s es suficiente.
  • Re-descubrimiento full en cada error de query (en lugar de retry con backoff). Discovery es barato (~ms vs broker), no vale la pena la complejidad.

Tests: 10 (nouser-card, +3 query) + 27 (nouser-core, +3 engine_socket)

  • 4 (sidecar) verdes. Explorer compila clean.