Commit Graph

95 Commits

Author SHA1 Message Date
sergio 3e335df298 feat(mirada): app del Cerebro — ventana GPUI del compositor
Envuelve mirada-brain::Desktop y lo pinta: barra con escritorios + modo
+ foco, lienzo teselado con marco por ventana. Con MIRADA_SOCKET sondea
un Cuerpo por mirada-link; sin él, simulación con ventanas sintéticas y
teclado (n/w/j/k/tab/1-9). cargo build -p mirada limpio.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 21:07:11 +00:00
sergio f57c61fe3e feat(mirada): mirada-link — transporte Cerebro↔Cuerpo del compositor
Link<Out,In> sobre socket Unix: hilo lector de fondo + canal mpsc para
sondeo no bloqueante. BrainLink/BodyLink, connected_pair (socketpair),
connect/listen por ruta; Drop cierra el socket y propaga EOF. 7 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 21:01:56 +00:00
sergio 3e2777540f feat(mirada): mirada-brain — orquestador de escritorio del compositor
Desktop agnóstico de GPUI/smithay: salidas, 9 escritorios virtuales,
registro de ventanas y foco. on_event(BodyEvent) -> Vec<BrainCommand>;
DesktopAction + mapa de teclas estilo tiling WM (Super). 17 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 21:00:24 +00:00
sergio e736587857 feat(mirada): mirada-protocol — contrato Cerebro↔Cuerpo del compositor
BrainCommand/BodyEvent + WindowPlacement, marco postcard con prefijo u32
LE (write_frame/read_frame, guard MAX_FRAME) y el puente placements()
desde un Workspace de mirada-layout. 9 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 20:58:38 +00:00
sergio 93e003be0d feat(matilda): matilda-discover — estado actual del servidor
Observa qué contenedores y vhosts existen (docker ps + sitios de
nginx) y reconstruye un Inventory "actual" que matilda-plan diferencia
contra el deseado: detecta correctamente qué crear y qué eliminar
(huérfanos). Parseo puro y testeable; sólo discover_local toca el
sistema. 6 tests.

La CLI gana el flag --discover en plan/script/apply: reconcilia
contra el estado real de la máquina en vez de partir de vacío.

matilda: 7 crates + CLI, ~48 tests. Pendiente: matilda-app (GPUI) y
la inspección detallada (docker inspect) para detectar drift de
configuración, no sólo presencia.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 20:31:26 +00:00
sergio df8f92fbb0 feat(matilda): ghost + linker + CLI — el ciclo completo de aplicación
matilda-ghost: el agente que ejecuta los ApplySteps en la máquina
destino — escribe archivos, corre comandos, reporta paso a paso;
semántica set -e (se detiene en el primer error). dry_run previsualiza
sin tocar nada. 5 tests.

matilda-linker: aplica los pasos en un host remoto por SSH sobre
brahman-ssh-multiplex; produce el mismo ApplyReport que el ghost local.

apps/matilda: deja de ser una demo hardcoded — ahora es una CLI real:
  matilda example | plan | script | apply  (local · --dry-run · --host)
Carga el inventario de un JSON, reconcilia y aplica.

matilda: 6 crates + CLI, ~42 tests. La cadena va de la declaración
a la aplicación local/remota.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 20:27:28 +00:00
sergio 5b9d8107fc feat(matilda): matilda-apply — puente del plan a la ejecución
Traduce un Plan de reconciliación a ApplySteps concretos: por cada
acción, los archivos a escribir en el servidor y los comandos a
correr. Contenedores → docker rm/run; vhosts → archivo nginx +
reload; hosts → sin pasos (son destino de conexión, no algo a
aplicar). steps_to_script() emite un script bash único con heredocs.

Sigue agnóstico de transporte — ejecutar los pasos (local, SSH o vía
matilda-ghost) es la capa de I/O. La demo CLI ahora imprime el script.

6 tests; matilda llega de la declaración al script ejecutable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 20:18:20 +00:00
sergio 37ea535cb7 feat(shuma): shuma-infer — motor de inferencia de intenciones
Detecta patrones de comandos repetidos en el historial: ventana
deslizante sobre las firmas de binarios (sólo ventanas 100%
exitosas), abstracción de argumentos variables (cd /a vs cd /b →
cd <…>), patrones maximales, puntaje por largo × frecuencia.
10 tests, agnóstico y determinista.

El shell lo corre tras cada comando terminado y promueve el patrón
más fuerte a un grupo « ...» en el panel [RUN] — la rehidratación
que convierte la repetición orgánica en una receta de un clic.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 19:12:47 +00:00
sergio 0f2f1033eb feat(shuma): shuma-session + shuma-exec — sesiones de trabajo y ejecución
shuma-session: el shell trabaja dentro de una WorkSession — directorio
actual (que es el identificador de aislamiento, hash estable del cwd),
historial de comandos ejecutados (CommandRun con salida y estado) y
grupos de comandos guardados y reutilizables (CommandGroup).

shuma-exec: ejecutor con salida en streaming — lanza bash -c en un
directorio y entrega stdout/stderr línea a línea por un canal, sin
esperar al final. Es la capa que sandokan (poll-based, orquesta Cards)
deliberadamente no cubre.

15 tests. Agnósticos de UI, #![forbid(unsafe_code)].

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 18:32:59 +00:00
sergio 7c38a8af4e feat(shuma): shuma-sysmon — muestreo de CPU/memoria con historial
Lee /proc/stat y /proc/meminfo; calcula uso de CPU (delta entre
muestras) y de memoria; mantiene un History circular para la curva
del monitor. Parseo puro (parse_cpu_stat/parse_meminfo) separado de
la lectura de archivos → testeable sin tocar el sistema.

8 tests. #![forbid(unsafe_code)], cero deps de UI.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 18:09:46 +00:00
sergio cf337c88d7 feat(shuma): shuma-line — el cerebro agnóstico del input del shell
Análisis de la línea de comandos bash, listo para GUI o TUI:
- lexer: tokeniza + clasifica (comando vs argumento por etapa),
  reconoce comillas, variables, tuberías, redirecciones, operadores.
- pipeline: descompone la línea en etapas separadas por |.
- complete: autocompletado posicional (comando / flag / ruta) con
  CompletionSource inyectable; diccionario de flags por comando.
- LineState: input editable UTF-8-safe (cursor, motions, completado).
- Dialect conmutable (bash hoy; zsh/fish/python a futuro).

32 tests. #![forbid(unsafe_code)], cero deps de UI.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 18:08:26 +00:00
sergio b975dc7919 feat(mirada): mirada-layout — motor de teselado del compositor Wayland
Rect + split (reparto exacto de píxeles), 4 modos de layout
(MasterStack, Monocle, Grid, Columns) con tile(), y Workspace:
ventanas en orden de teselado, foco cíclico, reordenado y
resolución de geometría. Determinista, agnóstico de Wayland/smithay.

22 tests. #![forbid(unsafe_code)].

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 17:24:48 +00:00
sergio 737ae5a696 feat(charka): charka-bcd — aritmética decimal con semántica COBOL
Cimiento numérico del transpilador. Picture parsea la cláusula
PICTURE (9, V, S, 9(n)); Decimal es punto fijo exacto (mantissa i128
+ scale) con suma/resta/producto exactos, división con escala de
resultado fija, redondeo Truncate/HalfUp y coerce a un Picture con
detección de desbordamiento (ON SIZE ERROR).

22 tests. Determinista, sin deps de plataforma — base de Fase D.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 17:22:40 +00:00
sergio e3980d005f feat(yachay): notebooks reproducibles — yachay-core + demo
yachay-core: notebook como secuencia de celdas (orden de lectura) +
DAG de dependencias (orden de ejecución). Celdas markdown/código/embed
con content_hash BLAKE3; editar una propaga staleness a descendientes;
digest Merkle por celda (content_hash ‖ digests upstream) y
notebook_digest que certifica reproducibilidad. Demo CLI en apps/yachay.

14 tests. Sin kernel ni UI, #![forbid(unsafe_code)].

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 17:09:18 +00:00
sergio 3f8a3ea4b6 feat(matilda): administración de servidores — core + config + plan
matilda-core: modelo declarativo (Host, Container, VHost, Inventory).
matilda-config: renderiza Container→docker-compose/docker run y
VHost→bloque server nginx (con TLS + redirección :80→:443).
matilda-plan: reconciliación pura actual→deseado con acciones
ordenadas por dependencia (contenedores antes que vhosts, removes
en orden inverso). Demo CLI en apps/matilda.

29 tests. Funciones puras, cero Docker/SSH/disco.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 17:06:36 +00:00
sergio 639381fd94 feat(takiy): takiy-core — teoría musical + modelo de partitura
Pitch MIDI (clase/octava/frecuencia ET A4=440), Scale (raíz + patrón
de semitonos: mayor, menor natural, pentatónica), Chord (7 cualidades,
voicing, nombres) y un Score multipista con tempo: ScoreNote en
pulsos, Track con inserción ordenada y transposición atómica.

24 tests. Agnóstico de síntesis y UI, #![forbid(unsafe_code)].

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:45:55 +00:00
sergio ea079a0b23 feat(badu): app demo — cuaderno con grafo de enlaces y gravedad
CLI que siembra un cuaderno (cocina/jardín/oficina), imprime el grafo
de wiki-links (forward/backlinks, huérfanas, colgantes) y los
clústeres por gravedad semántica + vecinos + layout 2D.
cargo run -p badu.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:43:42 +00:00
sergio d0a175a90a feat(badu): toma de notas — núcleo + gravedad semántica
badu-core: modelo Note + NoteStore (etiquetas, búsqueda) + grafo de
wiki-links [[...]] derivado del cuerpo (forward/backlinks, huérfanas,
enlaces colgantes; resolución case-insensitive).

badu-gravity: SemanticField sobre vectores semánticos — afinidad
coseno, vecinos más cercanos, clústeres por umbral (union-find) y
layout 2D dirigido por fuerzas (notas afines se atraen, todas se
repelen; determinista, sin RNG).

29 tests. Cero red, #![forbid(unsafe_code)].

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:42:28 +00:00
sergio 4e27065a15 feat(agorapura): app demo — escenario narrado del ágora
CLI que recorre el caso canónico de extremo a extremo: Venezuela
atestigua la nacionalidad de Yumaira, otras identidades corroboran,
una firma manipulada se rechaza, y tres políticas negociadas dan
veredictos distintos sobre la misma evidencia. cargo run -p agorapura.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:39:07 +00:00
sergio c1c136954e feat(agorapura): identidad humana federada — core + grafo de confianza
agorapura-core: identidades fractales (persona/comunidad/alianza/
institución) sobre claves ed25519, Claims sujeto-predicado-valor y
Attestations firmadas y autoverificables (la prueba viaja con el
dato). agorapura-graph: TrustGraph guarda sólo atestaciones con firma
válida; corroboration() devuelve evidencia cruda y TrustPolicy —un
umbral negociado, no una verdad del sistema— la traduce a sí/no.

22 tests. Cero red, cero estado global, #![forbid(unsafe_code)].

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:38:20 +00:00
sergio ced5853154 feat(fana): backend GPUI + app — editor de escritura DAG
fana-editor-gpui: EdgesElement pinta los conectores de dependencia
como paths; editor_view compone bloques de átomo (divs absolutos
coloreados por coherencia) + osciloscopio del sidepane. RenderPlan
ahora lleva su LayoutConfig para que el backend sea autosuficiente.

app fana: ventana con un relato de ejemplo (rama principal + alterna),
botón «Mutar raíz» que dispara la onda de choque lógica
(propagate_mutation), «Re-validar todo», leyenda y estadísticas.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:31:12 +00:00
sergio 494fb7c0bc feat(fana): fana-render-plan — plan de dibujo agnóstico del editor DAG
build_plan(NarrativeGraph) → RenderPlan: AtomBlocks apilados por
profundidad topológica (una columna por rama), Edges de dependencia
(borde inferior → superior) y osciloscopio de coherencia en el
sidepane (tono + intensidad semántica normalizada). Determinista:
orden desempata por (profundidad, columna, id). 10 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:28:27 +00:00
sergio 649ca02d4d feat(verbo): verbo-daemon — embeddings compartidos entre procesos
Daemon que carga un Provider una vez y lo sirve sobre socket Unix;
DaemonClient lo consume desde otro proceso implementando el trait
Provider (indistinguible de un backend local). Multi-instancia: un
daemon por modelo, cada uno en su socket. Frames postcard con
prefijo de largo. 8 tests (wire + integración real sobre socket).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:25:56 +00:00
sergio f46c7b435f feat(dominium): backend GPUI + app — ventana viva del simulador
dominium-canvas-gpui: Element que pinta un RenderPlan como quads,
centrado en sus bounds (rgba→hsla, único crate que toca gpui).

app dominium: compone core→physics→iso→render-plan→canvas en una
ventana GPUI con bucle de simulación de fondo (~11 tps), panel de
estadísticas, controles play/pausa + re-sembrar, y re-siembra
automática al colapso poblacional.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:22:35 +00:00
sergio cba61e3549 feat(dominium): maqueta isométrica agnóstica — dominium-render-plan
build_plan(World, IsoProjector, ZWeights, PlanConfig) → RenderPlan:
un quad por celda (color = mezcla pesada de las 5 capas, relieve =
Z compuesto) + un quad-marca por Lemming posado sobre el terreno.
Quads ordenados por profundidad de pintor (depth = x+y) + caja
envolvente para centrado. Cero deps gráficas. 10 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:19:40 +00:00
sergio e2833a20c4 feat(dominium): dominium-iso — proyección pseudo-3D isométrica
Proyección calculada en CPU antes de emitir quads 2D (GPUI no maneja
matrices 3D ni mallas).

- ZWeights — pesos del Z compuesto, uno por capa; z_of() calcula el
  relieve como Σ wᵢ·capaᵢ (los 5 sliders del panel).
- IsoProjector — matriz iso fija: x=(x-y)·cos30, y=(x+y)·sin30 − Z·zf.
  cos/sin de 30° vía libm → proyección bit-exacta cross-platform.
- project() + shadow() (Lambert plano: la sombra cae en z=0 desplazada
  por la dirección de luz, larga en proporción a la altura).

6 tests verdes (origen, eje del rombo, Z eleva, Z compuesto lineal,
determinismo, sombra de punto en el suelo). cargo check verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:16:33 +00:00
sergio ed651d6ac5 feat(shuma): shuma-shell-render — draw-plan del Lienzo de Contexto
Layout agnóstico del grafo de intenciones del shell:

- layout(SessionGraph) → CanvasPlan: cada comando %cN es un NodeBox
  ubicado en una columna por su profundidad de dependencia
  (longest-path); cada ref %pN/%cN que consume genera una Edge hacia
  el comando que la produjo. Nodos colapsados se dibujan retraídos.
- paint(plan, canvas) → render directo contra pineal-render: aristas
  al fondo, cajas con borde coloreado por estado (ámbar/verde/rojo).

4 tests verdes (columnas por dependencia, aristas de buffer, comandos
independientes en col 0, paint emite draw calls). cargo check verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:12:54 +00:00
sergio cd3b41a401 feat(dominium): dominium-physics — ciclo del motor (difusión + tick)
- diffuse — ecuación de fluidos discreta sobre los 3 campos dinámicos
  (materia/psique/poder): cada celda intercambia con sus 4 vecinas +
  entropía. Buffer de lectura separado (lee estado viejo). oro y
  degradacion no difunden.
- tick — un paso completo: difusión → transiciones (agente exhausto se
  fuerza a Pelear) → acciones de los agentes → envejecimiento + cosecha
  (la energía del muerto vuelve como materia/fertilidad). run() corre N.

Determinista bit-exacto: aritmética f32 en orden fijo, sin HashMap ni
reducciones paralelas. Test `run_is_deterministic` verifica que mismo
input → mismo estado bit a bit.

7 tests verdes. cargo check --workspace verde. dominium ya CORRE
(core + physics = simulación funcional).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:08:01 +00:00
sergio d1727b1374 feat(dominium): dominium-core — núcleo del simulador de campo medio
- grid — el Sustrato Plano: grilla SoA de 5 capas f32 (materia, psique,
  poder, oro, degradación), indexada y*width+x.
- lemmings — Agentes Vectoriales en SoA: pos_x/y, edad, energia,
  vector_psi [Orden,Miedo,Curiosidad,Corruptibilidad], accion u8.
  spawn / swap_remove / nearest (determinista, empate por menor índice).
- world — World + las 6 acciones atómicas fijas: Mover (gravedad mental
  hacia el vecino más afín al psi), Extraer, Sincronizar, Intercambiar,
  Replicar, Degradar. step_lemming despacha por el byte accion.
- params — SimParams (las constantes que los sliders del panel ajustan).

Cero deps gráficas — sólo serde (regla inviolable de la spec).
11 tests verdes (acciones verificadas: Mover sigue la materia, Extraer
degrada, Replicar engendra, Intercambiar conserva energía, etc.).
cargo check --workspace verde.

Pendiente dominium: physics (difusión/entropía/cinemática), iso,
render-plan, canvas/panel GPUI.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:01:42 +00:00
sergio 191e6b06e1 feat(fana): fana-semantic — scoring de intensidad semántica
Desbloqueado por verbo. fana-semantic embebe los átomos y mide su
afinidad a un conjunto de conceptos.

- ConceptSet — embebe el texto de referencia de cada concepto como su
  vector ancla (vía cualquier verbo Provider).
- SemanticScorer — embebe el contenido de un NarrativeAtom y llena
  atom.semantic_vectors con la similitud coseno concepto→intensidad.
  Limpia el scoring previo en cada pasada.

Agnóstico del backend (verbo_core::Provider). 3 tests verdes con
verbo-mock — incluye: texto idéntico al ancla puntúa coseno ≈ 1.
cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:54:42 +00:00
sergio e0ad7315be feat(verbo): verbo-mock — backend de embeddings determinista
Backend sin modelo real: FNV-1a del texto siembra un LCG que genera el
vector. Mismo texto → mismo vector siempre; textos distintos → vectores
distintos. Dimensión configurable (default 384d, típica de modelos
ligeros).

Desbloquea desarrollar y testear los consumidores de verbo
(fana-semantic, badu, chasqui) sin descargar modelos ONNX ni pegarle a
Cohere. Los backends reales (cohere/bge/fastembed) son swaps de config.

4 tests verdes (determinismo, distinción, dimensión, batch).
cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:53:43 +00:00
sergio c2d6c15138 feat(verbo): verbo-core — contrato model-agnostic de embeddings
Primer crate de verbo (provider de embeddings compartido; desbloquea
fana-semantic, badu y la búsqueda de chasqui).

- ModelId — identidad de modelo (nombre + dimensión). Vectores de
  distinto ModelId no son comparables.
- EmbeddingVector — vector + su ModelId; new() valida la dimensión,
  cosine() rechaza comparar modelos distintos (error tipado, no
  sinsentido silencioso), norm() euclidiana.
- EmbedError — ModelMismatch / BadDimension / Backend.
- trait Provider — model_id + embed + embed_batch (default secuencial).
  Lo cumplen los backends concretos (cohere / bge / fastembed).

5 tests verdes (cosine idéntico/ortogonal/cross-model/zero, validación
de dimensión). cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:52:43 +00:00
sergio 1da4ee11d7 feat(shuma): núcleo del shell — parser de intenciones + grafo de contexto
shuma-intent: el corazón agnóstico del shell shuma.

- parse — Intention: una línea del prompt parseada en etapas separadas
  por pipe. Ref (%cN comando / %pN buffer) + Stage (Exec | Inject).
  Parsea el ejemplo de la spec: `ssh nodo 'cat data.json' | %p1 | sort`.
- graph — SessionGraph: el grafo de contexto de la sesión. record()
  registra una intención (%cN), complete() le asigna buffer de salida
  (%pN) + estado, resolve() resuelve referencias, dangling_refs()
  valida una intención antes de ejecutar (la validación previa del
  prompt), collapse_succeeded() retrae nodos OK (quietud visual).

Todo puro y serializable (sesiones exportables). El front-end GPUI
(zonas RUN/SENS + lienzo central) lo rehidrata; la ejecución la hace
sandokan. 8 tests verdes. cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:47:11 +00:00
sergio 6884b3f8cb feat(fana): fana-store — persistencia del grafo narrativo (sled)
- fana-core: NarrativeAtom + CoherenceState ahora Serialize/Deserialize
  (serde con feature rc para el Arc<String>; uuid con feature serde).
- fana-graph: + atoms() iterator + from_atoms() constructor.
- fana-store: GraphStore sobre sled. put/get/remove_atom por Uuid,
  serialización bincode. save_graph persiste átomo por átomo;
  load_graph reconstruye el grafo (la adjacency se re-cablea desde las
  dependencies de cada átomo).

7 tests verdes (roundtrip put/get/remove + save/load_graph preserva
estructura). cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:43:01 +00:00
sergio 353e0bbb43 feat(fana): C1 — núcleo del writer DAG editor (core + graph)
Primer paso de fana (prioridad alta entre las apps Fase C).

- fana-core — NarrativeAtom: id + content_hash SHA-256 + content
  Arc<String> (structural sharing: ramificar es O(1)) + semantic_vectors
  + dependencies + branch_id + CoherenceState (Valid/InConflict/
  PendingEvaluation). Invariante hash↔content verificable; set_content
  re-hashea y marca PendingEvaluation.
- fana-graph — NarrativeGraph: DAG de átomos + adjacency
  dependencia→dependientes. propagate_mutation: BFS que marca
  PendingEvaluation en cascada a todo descendiente (la "onda de choque
  lógica" de la spec), agnóstico de UI — devuelve los ids afectados.
  topological_order con detección de ciclo.

10 tests verdes. cargo check --workspace verde.
Pendiente fana: semantic (cliente verbo), store (sled), llm, render-plan,
editor-gpui.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:41:17 +00:00
sergio 05886022e0 feat(sandokan-remote): B1.4 — RemoteEngine vía SSH socket-forward
Opción B: RemoteEngine orquesta en un host remoto tunelando el wire
del daemon sobre un canal SSH direct-streamlocal hacia el sandokan.sock
remoto. El protocolo es idéntico al de DaemonEngine (postcard
length-prefixed) — sólo cambia el transporte, así que read_frame/
write_frame se reusan tal cual.

- brahman-ssh-multiplex: + SshSession::forward_unix — abre un canal
  direct-streamlocal y devuelve su ChannelStream (AsyncRead+AsyncWrite).
- sandokan-daemon: protocol ahora pub, exporta read_frame/write_frame.
- sandokan-remote: RemoteEngine { SshSession + remote_socket }.
  connect() o with_session(); cada operación abre un canal nuevo
  (multiplexado sobre la conexión maestra).
- sandokan umbrella re-exporta RemoteEngine.

Completa Fase B: sandokan tiene Local + Daemon + Remote + auto().
cargo check --workspace verde. RemoteEngine necesita un host remoto
con `sandokan daemon` para validación runtime (sin unit test).

Opción A (text-parse del CLI por compat) queda pendiente por decisión
del usuario.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:37:11 +00:00
sergio 0e13c35f3e feat(brahman-ssh-multiplex): A6 — sesión SSH multiplexada (russh)
Envuelve russh 0.54 con una API mínima: una SshSession mantiene el
Handle maestro; cada exec() concurrente abre su propio canal en
paralelo sobre la misma conexión TCP (SSH multiplexa canales por
diseño del protocolo).

- SshConfig (host/port/user/auth/keepalive) + SshAuth (Password | Key).
- SshSession::connect — config russh + keepalive + auth password o
  clave privada en disco; verificación de host key TOFU por default.
- SshSession::exec — corre un comando en un canal nuevo, junta
  stdout/stderr/exit_code.
- SshSession es Clone barato (comparte el Handle).

Base de sandokan RemoteEngine y del Linker SSH de matilda.
Compila contra russh 0.54. El test de conexión real requiere un
servidor SSH (fuera del unit test).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:26:16 +00:00
sergio 1e01dc27a5 feat(brahman-card-discovery): B4 — búsqueda de Cards local + DHT
- index — CardIndex: índice en memoria con filtros (by_label
  case-insensitive substring, by_kind, providing por Capability, by_id).
- registry — scan_dir: carga toda Card *.json de un directorio,
  saltando ruido y archivos rotos.
- discovery — CardDiscovery: une el índice local con la malla P2P;
  announce_all publica las Cards locales al DHT, find_remote busca
  proveedores. Modo local-only sin DHT también soportado.

Lo consumen el card-browser de nahual-shell y agorapura.
7 tests verdes. cargo check --workspace verde.

settings.local.json: defaultMode bypassPermissions (sesión desatendida).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:23:16 +00:00
sergio 27603c906d feat(brahman-dht): B3 — discovery typed sobre el Kademlia compartido
brahman-net corre un único Kademlia para todo el ecosistema.
brahman-dht le pone arriba un esquema de claves namespaced para que
distintos dominios coexistan sin colisión en la misma malla.

- key — RecordKind (Code/Card/Persona/Service/Custom) + DhtKey.
  Wire: [kind_tag] ++ blake3(id) = 33 bytes longitud fija. Custom(n)
  usa 0x80|n: nunca choca con los kinds estándar.
- Dht — wrapper sobre BrahmanNet: announce/withdraw/find (modelo de
  provider records).

Consumidores: minga (Code), brahman-card-discovery (Card), agorapura
(Persona). 5 tests verdes (incl. smoke async sobre un nodo libp2p real).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:11:40 +00:00
sergio 94ea0eaa53 feat(sandokan): CLI de prueba + fix wire serialization
apps/sandokan (binario `sandokan`): CLI para probar el orquestador.
Subcomandos: daemon, run <exec> [args], list, status, telemetry, stop.

Fix: Intent serializaba Card directo, pero Card tiene un campo
`#[serde(flatten)] extensions` incompatible con postcard ("sequence
length must be known"). Intent::card ahora usa #[serde(with)] que
proyecta Card↔WireCard en el límite de serialización (las extensions
locales se descartan al cruzar el wire — comportamiento correcto).

Smoke test verificado end-to-end: daemon + run /bin/sleep + list +
status Running + telemetry + stop + status Killed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:05:03 +00:00
sergio 8cd8003dd5 feat(sandokan): B1.5 — umbrella + Engine::auto()
Crate sandokan (umbrella): re-exporta core/local/daemon y provee la
selección de transporte.

- auto(socket) — patrón "el primero que arranca gana": prueba si hay
  un daemon escuchando; si lo hay devuelve DaemonEngine, si no
  LocalEngine. Box<dyn Engine> (el trait es object-safe vía async_trait).
- auto_default() — auto() con default_socket_path().
- default_socket_path() — $XDG_RUNTIME_DIR/sandokan.sock o
  /run/brahman/sandokan.sock.

3 tests: fallback a Local sin daemon, pick Daemon con serve() activo,
default path absoluto. cargo check --workspace verde.

sandokan ya es usable end-to-end en modo local y daemon. Falta
RemoteEngine (B1.4, depende de brahman-ssh-multiplex).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 14:05:32 +00:00
sergio b7d9d7abd9 feat(sandokan-daemon): B1.3 — DaemonEngine + protocolo wire
DaemonEngine: implementación del trait Engine que delega a otro proceso
vía Unix socket. Materializa el patrón horizontal de sandokan (el
binario que arranca primero expone el engine; los demás se le suman).

- protocol.rs — DaemonRequest/DaemonResponse (espejan los métodos de
  Engine) + framing postcard length-prefixed (u32 LE + bytes), con
  MAX_FRAME 16 MiB defensivo.
- client.rs — DaemonEngine: stateless, un round-trip por llamada;
  is_reachable() para el probe de auto().
- server.rs — serve(engine, socket): envuelve cualquier Engine, una
  task por conexión, multi-request por conexión.

EngineError ahora es Serialize/Deserialize (viaja por el wire);
NotFound se propaga tipado a través del socket.

1 test de integración: roundtrip real DaemonEngine ↔ serve ↔ LocalEngine
(list vacío + NotFound propagado). cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 14:04:22 +00:00
sergio cba3a9dd6e feat(sandokan-local): B1.2 — LocalEngine
Primera implementación del trait Engine: orquestación in-process.

- LocalEngine encarna Cards vía arje-incarnate, mantiene un registro
  HashMap<Ulid, Entity> de entidades activas.
- run()       — incarnate + registro; mergea env del contexto.
- stop()      — SIGTERM + período de gracia + SIGKILL + reap.
- list()      — reaping perezoso (waitpid WNOHANG) + handles activos.
- status()    — reaping perezoso + LifecycleState.
- telemetry() — lee /proc/<pid>/status (VmRSS + Threads), sin invocar
                binarios externos.
- Reaping sin task de fondo: cada consulta hace waitpid WNOHANG.

proc.rs: lectura directa de procfs (mem_bytes, thread_count, proc_exists).

4 tests verdes (2 proc + 2 engine: empty list, NotFound paths).
cargo check --workspace verde.

v1: IsolationLevel es advisory (Sealed reservado para cuando el Intent
transporte rootfs spec). CPU% pendiente (requiere 2 samples).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 13:57:26 +00:00
sergio af5d4a1f22 feat(sandokan-core): B1.1 — contrato del orquestador
Primer crate de la Fase B. Define SOLO el contrato del orquestador
sandokan (library horizontal embebible, no daemon supremo):

- Intent / ExecContext / IsolationLevel — qué orquestar
- ExecHandle — referencia a una entidad encarnada
- LifecycleEvent / TelemetryFrame — observabilidad (wire types)
- EngineError — taxonomía de fallas
- trait Engine — run/stop/list/status/telemetry (poll-based, sin
  streams sobre trait objects, para que las 3 impls lo cumplan
  uniformemente)

Las impls concretas (LocalEngine, DaemonEngine, RemoteEngine) vendrán
en crates separados (sandokan-local, sandokan-daemon, sandokan-remote).

3 tests verdes. cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 00:38:22 +00:00
sergio 545dd59c72 feat(sandokan-lifecycle): A4 — primitivas de lifecycle agnósticas
Nuevo crate runtime/sandokan-lifecycle: lógica pura reutilizable por
cualquier supervisor de procesos (shuma, matilda Ghost, charka-shadow,
mirada). Sin syscalls, sin proceso, sin UI.

Módulos:
- backoff   — Backoff exponencial con tope
- ttl       — Ttl anclado a Instant
- quota     — ResourceQuota + check_quota + Breach + QuotaAction
- restart   — RestartPolicy + RestartTracker (conteo + backoff)
- state     — LifecycleState (Pending/Running/Exited/Failed/Killed)

15 tests verdes. cargo check --workspace verde.

Variante segura de A4: se crea la library limpia sin tocar shuma-core
(módulo maduro). La migración de WorkspaceManager a consumir estas
primitivas queda registrada como A4.2 (refactor diferido, no urgente).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 00:32:52 +00:00
sergio 848fc7a072 refactor(brain): A2 — split arje-brain en 3 sub-crates
DAG de dependencias limpio (modularidad horizontal):
- arje-brain-rules     — rules + engine + dispatch (motor determinista)
- arje-brain-cognitive — observer + crystallize (estadística)
- arje-brain-audit     — audit chain → CAS (accountability)
- arje-brain           — umbrella de integración (introspect +
                         autopromote + metrics + loader)

Habilitador clave: TimedEvent movido de observer.rs a rules.rs
(engine lo necesitaba, era el único acoplo que rompía el DAG).

arje-brain re-exporta la API de los 3 sub-crates: arje-zero y chasqui
(consumidores) no requieren cambios. cargo check --workspace verde.
24 tests del brain pasan (4 rules + 6 cognitive + 5 audit + 9 umbrella).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 00:24:48 +00:00
sergio b83d40a833 refactor(naming): A1 — ente→arje, vista→revista, pluma→fana
Rename batch de la Fase A del PLAN_MACRO:
- 25 crates ente-* → arje-* (protocol/init/runtime/compat). El linaje
  arje (init Linux) queda con prefijo coherente.
- vista → revista (revista-core + revista-web).
- pluma → fana (fana-md + fana-md-reader-web). fana absorbe el linaje
  markdown de pluma; será el writer DAG editor (prioridad alta).

Cambios:
- git mv de 29 crate dirs + 2 SDDs
- package/lib/bin names + path refs + imports .rs reescritos
- workspace Cargo.toml + comentarios de sección
- SDDs de init/runtime/compat/protocol actualizados a arje-
- SDD de revista + SDD de fana (reescrito: writer DAG editor)
- docs/STATUS.md, ROADMAP.md, PLAN_MACRO.md, arje-boot.md,
  arje-replace-systemd.md actualizados
- docs/changelog/akasha.md → chasqui.md

scripts/rename-fase-a.py idempotente (--dry-run soportado).
cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 00:10:14 +00:00
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
sergio 4619ba3a2b feat(cosmobiologia): crate WASM + fallback inteligente + DEPLOY.md (fase 3b)
Cierra el requerimiento del módulo web. El cliente puede correr en
modo WASM (render local, scrubbing instantáneo, sin round-trip) o
caer al SSR (server compone el SVG) si el bundle WASM no está
desplegado. Switch automático sin configuración.

cosmobiologia-web (crate nuevo, cdylib + rlib):
- `lib.rs` con un único export wasm-bindgen
  `render_model_to_svg(json, size, rot_offset_deg) -> String` que
  deserializa un `RenderModel`, llama `compose_wheel` +
  `draw_commands_to_svg` de cosmobiologia-render, y devuelve el
  SVG inline listo para `wheel.innerHTML = svg`.
- Cargo.toml con `wasm-bindgen` + `getrandom` con feature
  `wasm_js` solo bajo `target_arch = "wasm32"` (en nativo no se
  arrastran).
- `.cargo/config.toml` con `--cfg getrandom_backend="wasm_js"`
  para que la transitividad
  `uuid → cosmobiologia-model → cosmobiologia-render` compile a
  wasm32-unknown-unknown.
- `cargo check -p cosmobiologia-web` pasa en nativo (valida la
  signature). Build WASM real lo dispara el usuario con
  `wasm-pack build --target web --out-dir ../../../apps/
  cosmobiologia-server/static/wasm` — comando documentado en
  DEPLOY.md y en doc del crate.

cosmobiologia-server — soporte cliente WASM:
- Nuevo flag `--static-wasm <dir>` (default = static/wasm relativo
  al cwd). Si el directorio existe, los archivos WASM se sirven
  en `/static/wasm/*`. Si no existe, devuelve 404 y el cliente
  cae al SSR.
- ServeDir de `tower-http` para fileserver simple.

index.html:
- Nueva función `tryLoadWasm()` que hace `import dinámico` del
  módulo WASM al boot. Si carga OK, `wasm` global queda set; si
  falla (archivo no existe o error de WASM), se loguea info y
  sigue.
- `refreshSelected()` ahora hace fetch del RenderModel JSON
  (`/api/sky` o `/api/charts/:id/render`); si hay WASM, llama
  `wasm.render_model_to_svg(json)` localmente; si no hay WASM o
  el render WASM falla, hace fetch del SVG SSR como fallback.
- Info row muestra "WASM" o "SSR" según el modo activo —
  visualmente claro qué pipeline está corriendo.

cosmobiologia-server/DEPLOY.md (nuevo):
- Build del binario + build del WASM (con wasm-pack).
- systemd service template (sandboxing básico: ProtectSystem
  strict, ProtectHome, PrivateTmp, NoNewPrivileges).
- Caddyfile y nginx para reverse proxy con TLS.
- DNS: A records para cosmobiologia.gioser.net + api.*.
- CORS: warnings sobre permissive vs producción multi-usuario.
- Separación demo público (DB vacía en VPS) vs desktop personal
  (DB compartida en `~/.local/share/cosmobiologia/`).
- Backup con SQLite `.backup`.
- Smoke test post-deploy con curl.
- Tabla de referencia de TODOS los endpoints.

Tests: 10 verdes (cosmobiologia-render::math). El cliente WASM
no agrega tests propios — la lógica testeable vive en render.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 01:25:48 +00:00
sergio d341004f59 feat(cosmobiologia-server): server HTTP single-user con CRUD completo (fase 2)
Crate nuevo `cosmobiologia-server` (binario axum, nativo) que
monta `cosmobiologia-engine` + `cosmobiologia-store` y expone
la rueda + el CRUD del tree por HTTP.

Endpoints v1:
- `GET  /api/health`
- `GET  /api/tree`                         tree completo anidado
- `POST /api/groups`                       crear grupo
- `PATCH /api/groups/:id`                  renombrar
- `DELETE /api/groups/:id`                 borrar
- `POST /api/contacts`                     crear contacto
- `PATCH /api/contacts/:id`                renombrar
- `DELETE /api/contacts/:id`               borrar
- `POST /api/charts`                       crear carta
- `GET  /api/charts/:id`                   chart JSON
- `PATCH /api/charts/:id`                  editar (label/birth/config)
- `DELETE /api/charts/:id`                 borrar
- `GET  /api/charts/:id/render`            RenderModel JSON
- `GET  /api/charts/:id/svg`               SVG inline (reusa
                                            svg_export del engine)
- `GET  /api/sky`                          "Cielo ahora" — RenderModel
                                            UTC actual sin chart_id real

Query params del render para activar overlays sin POST:
- `offset_min=<i64>`                       time scrubbing
- `transit=1`                              overlay de tránsito al now
- `prog_age=<f64>`                         progresión secundaria
- `sa_age=<f64>`                           solar arc
- `pd_age=<f64>`                           primary directions (Naibod)

Decisiones:
- Single-user, sin auth. Bind por default a `127.0.0.1:8787` —
  el server NO debe exponerse a la red pública en esta fase.
- DB por default = misma del desktop (`$XDG_DATA_HOME/cosmobiologia/
  charts.db`). `--db` permite override.
- CORS permissive (es localhost, single-user, sin auth).
- `ApiError` con mapeo a HTTP status: 404 NotFound,
  400 BadRequest, 500 todo lo demás. Body JSON `{ "error": "..." }`.

Smoke test:
  cargo run -p cosmobiologia-server -- --port 18787
  curl /api/health         → {"status":"ok",...}
  curl POST /api/groups    → {"id":"01KRYVP...","name":"Familia",...}
  curl POST /api/contacts  → {"id":"01KRYVP...","group_id":...}
  curl /api/tree           → árbol anidado
  curl /api/sky            → RenderModel con VSOP real

Pendiente (fase 3): cliente `cosmobiologia-web` (cdylib WASM)
que consuma estos endpoints y pinte SVG/Canvas2D.

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