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>
This commit is contained in:
sergio
2026-05-20 00:10:14 +00:00
parent 3fc6dcfa72
commit b83d40a833
159 changed files with 2384 additions and 1111 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ Histórico particionado el 2026-05-19 por proyecto/intención. Cada
archivo bajo `docs/changelog/` consolida las entradas de un
subdirectorio del workspace.
- [`akasha`](docs/changelog/akasha.md) — 15 entradas
- [`chasqui`](docs/changelog/chasqui.md) — 15 entradas
- [`init`](docs/changelog/init.md) — 1 entradas
- [`minga`](docs/changelog/minga.md) — 5 entradas
- [`misc`](docs/changelog/misc.md) — 2 entradas
Generated
+461 -461
View File
File diff suppressed because it is too large Load Diff
+38 -38
View File
@@ -12,43 +12,43 @@ members = [
"crates/protocol/brahman-admin",
"crates/protocol/brahman-sidecar",
"crates/protocol/brahman-net",
"crates/protocol/ente-card",
"crates/protocol/arje-card",
# ============================================================
# init/ — PID 1 + encarnación Linux (arje)
# ============================================================
"crates/init/ente-zero",
"crates/init/ente-kernel",
"crates/init/ente-soma",
"crates/init/ente-snapshot",
"crates/init/ente-incarnate",
"crates/init/arje-zero",
"crates/init/arje-kernel",
"crates/init/arje-soma",
"crates/init/arje-snapshot",
"crates/init/arje-incarnate",
# ============================================================
# runtime/ — Infraestructura de ejecución (bus + cas + wasm + brain)
# ============================================================
"crates/runtime/ente-bus",
"crates/runtime/ente-cas",
"crates/runtime/ente-wasm",
"crates/runtime/ente-brain",
"crates/runtime/ente-echo",
"crates/runtime/arje-bus",
"crates/runtime/arje-cas",
"crates/runtime/arje-wasm",
"crates/runtime/arje-brain",
"crates/runtime/arje-echo",
# ============================================================
# compat/ — Shims D-Bus para correr software systemd-aware
# ============================================================
"crates/compat/ente-policy-provider",
"crates/compat/ente-logind-compat",
"crates/compat/ente-hostnamed-compat",
"crates/compat/ente-timedated-compat",
"crates/compat/ente-localed-compat",
"crates/compat/ente-journald-compat",
"crates/compat/ente-resolved-compat",
"crates/compat/ente-polkit-compat",
"crates/compat/ente-machined-compat",
"crates/compat/ente-tmpfiles-compat",
"crates/compat/ente-systemd1-compat",
"crates/compat/ente-notify-compat",
"crates/compat/ente-binfmt-compat",
"crates/compat/ente-timer-compat",
"crates/compat/arje-policy-provider",
"crates/compat/arje-logind-compat",
"crates/compat/arje-hostnamed-compat",
"crates/compat/arje-timedated-compat",
"crates/compat/arje-localed-compat",
"crates/compat/arje-journald-compat",
"crates/compat/arje-resolved-compat",
"crates/compat/arje-polkit-compat",
"crates/compat/arje-machined-compat",
"crates/compat/arje-tmpfiles-compat",
"crates/compat/arje-systemd1-compat",
"crates/compat/arje-notify-compat",
"crates/compat/arje-binfmt-compat",
"crates/compat/arje-timer-compat",
# ============================================================
# modules/semantic_dht/ (minga) — DHT semántico de código
@@ -106,13 +106,13 @@ members = [
"crates/modules/nakui/core",
# ============================================================
# modules/akasha/ — Explorador semántico de Mónadas (era nouser)
# modules/chasqui/ — Explorador semántico de nómadas (ex-nouser, ex-akasha)
# ============================================================
"crates/modules/akasha/card",
"crates/modules/akasha/core",
"crates/modules/akasha/nous",
"crates/modules/akasha/nous-mock",
"crates/modules/akasha/nous-real",
"crates/modules/chasqui/card",
"crates/modules/chasqui/core",
"crates/modules/chasqui/nous",
"crates/modules/chasqui/nous-mock",
"crates/modules/chasqui/nous-real",
# ============================================================
# modules/shuma/ — Runtime de espacios aislados (era shipote)
@@ -132,16 +132,16 @@ members = [
"crates/modules/gioser/gioser-canvas-web",
# ============================================================
# modules/pluma/ — Markdown agnóstico + visor web
# modules/fana/ — Writer DAG editor (absorbe pluma)
# ============================================================
"crates/modules/pluma/pluma-md",
"crates/modules/pluma/pluma-reader-web",
"crates/modules/fana/fana-md",
"crates/modules/fana/fana-md-reader-web",
# ============================================================
# modules/vista/ — Deck horizontal swipe (Flutter PageView)
# modules/revista/ — Deck horizontal swipe (Flutter PageView)
# ============================================================
"crates/modules/vista/vista-core",
"crates/modules/vista/vista-web",
"crates/modules/revista/revista-core",
"crates/modules/revista/revista-web",
# ============================================================
# modules/barra/ — Taskbar agnóstica estilo Windows
@@ -174,7 +174,7 @@ members = [
"crates/apps/nahual-database-explorer",
"crates/apps/nahual-text-viewer",
"crates/apps/nahual-image-viewer",
"crates/apps/akasha-explorer",
"crates/apps/chasqui-explorer",
"crates/apps/nakui-explorer",
"crates/apps/nakui-ui",
"crates/apps/minga-explorer",
@@ -1,5 +1,5 @@
[package]
name = "akasha-explorer"
name = "chasqui-explorer"
version.workspace = true
edition.workspace = true
license.workspace = true
@@ -8,7 +8,7 @@ description = "Explorador GPUI de Mónadas: panel que descubre al daemon nouser
[dependencies]
brahman-card = { path = "../../protocol/brahman-card" }
brahman-sidecar = { path = "../../protocol/brahman-sidecar" }
akasha-card = { path = "../../modules/akasha/card" }
chasqui-card = { path = "../../modules/chasqui/card" }
nahual-theme = { path = "../../modules/nahual/libs/theme" }
nahual-launcher = { path = "../../modules/nahual/libs/launcher" }
nahual-widget-banner = { path = "../../modules/nahual/widgets/banner" }
@@ -17,5 +17,5 @@ nahual-widget-app-header = { path = "../../modules/nahual/widgets/app-header" }
gpui = { workspace = true }
[[bin]]
name = "akasha-explorer"
name = "chasqui-explorer"
path = "src/main.rs"
@@ -1,8 +1,8 @@
//! `akasha-explorer` — panel GPUI que descubre al daemon `akasha`
//! `chasqui-explorer` — panel GPUI que descubre al daemon `chasqui`
//! vía broker brahman y muestra sus Mónadas en vivo.
//!
//! Diseño: ventana standalone que cada N segundos consulta el query
//! socket del daemon (`akasha_core::engine_socket::client::list_monads`).
//! socket del daemon (`chasqui_core::engine_socket::client::list_monads`).
//! El path del socket NO está hardcoded — se descubre vía
//! `brahman_sidecar::await_provider_blocking` para el flow
//! `monad-list:json`. Si el daemon cae, el socket cacheado se invalida
@@ -13,9 +13,9 @@
//!
//! Uso:
//! ```sh
//! cargo run -p akasha-explorer
//! cargo run -p chasqui-explorer
//! # con override del init socket (heredado de brahman-handshake):
//! BRAHMAN_INIT_SOCKET=/tmp/init.sock cargo run -p akasha-explorer
//! BRAHMAN_INIT_SOCKET=/tmp/init.sock cargo run -p chasqui-explorer
//! ```
use std::path::PathBuf;
@@ -25,9 +25,9 @@ use brahman_sidecar::{await_provider_blocking, build_consumer_card, ConsumerErro
use gpui::{
div, prelude::*, px, rgb, Context, IntoElement, Render, SharedString, Window,
};
use akasha_card::query::client as query_client;
use akasha_card::query::{transport, ListMonadsResponse, FLOW_MONAD_LIST, FLOW_TYPE_NAME};
use akasha_card::Lens;
use chasqui_card::query::client as query_client;
use chasqui_card::query::{transport, ListMonadsResponse, FLOW_MONAD_LIST, FLOW_TYPE_NAME};
use chasqui_card::Lens;
use nahual_launcher::launch_app;
use nahual_theme::Theme;
use nahual_widget_app_header::app_header;
@@ -176,7 +176,7 @@ fn resolve_socket() -> Result<(PathBuf, &'static str), String> {
/// Card con `flow.input = monad-list:json`, espera al primer
/// `MatchEvent::Available`, devuelve el `producer_service_socket`.
fn discover_via_broker() -> Result<PathBuf, ConsumerError> {
let card = build_consumer_card("akasha-explorer", FLOW_MONAD_LIST, FLOW_TYPE_NAME);
let card = build_consumer_card("chasqui-explorer", FLOW_MONAD_LIST, FLOW_TYPE_NAME);
await_provider_blocking(card, DISCOVERY_TIMEOUT)
}
@@ -184,7 +184,7 @@ impl Render for Explorer {
fn render(&mut self, _w: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
// Chrome viene del Theme global; los acentos por kind
// (engine cyan, data purple) son señales semánticas del
// dominio akasha y se mantienen locales.
// dominio chasqui y se mantienen locales.
let theme = Theme::global(cx).clone();
let bg = theme.bg_app.clone();
let text = theme.fg_text;
@@ -205,7 +205,7 @@ impl Render for Explorer {
.map(|w| format!(" · watching: {}", w))
.unwrap_or_default()
),
_ => "Buscando daemon akasha vía brahman-broker…".to_string(),
_ => "Buscando daemon chasqui vía brahman-broker…".to_string(),
};
// Header standard via widget compartido.
+2 -2
View File
@@ -11,8 +11,8 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
gioser-canvas-web = { path = "../../modules/gioser/gioser-canvas-web" }
pluma-reader-web = { path = "../../modules/pluma/pluma-reader-web" }
vista-web = { path = "../../modules/vista/vista-web" }
fana-md-reader-web = { path = "../../modules/fana/fana-md-reader-web" }
revista-web = { path = "../../modules/revista/revista-web" }
barra-web = { path = "../../modules/barra/barra-web" }
wasm-bindgen.workspace = true
wasm-bindgen-futures.workspace = true
+2 -2
View File
@@ -21,8 +21,8 @@ use std::rc::Rc;
use barra_web::{Task, TaskList};
use gioser_canvas_web::{tips, Renderer};
use pluma_reader_web::Reader;
use vista_web::Deck;
use fana_md_reader_web::Reader;
use revista_web::Deck;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{
+1 -1
View File
@@ -14,7 +14,7 @@
//!
//! Stack visual: nahual-theme + banner_themed + card_themed +
//! theme_switcher. Mismo patrón que `nakui-explorer` /
//! `akasha-explorer`.
//! `chasqui-explorer`.
//!
//! Uso:
//! ```sh
+1 -1
View File
@@ -10,7 +10,7 @@
//! producción que va escribiendo). Sin discovery dinámico vía broker
//! brahman porque nakui hoy es CLI/library/demos, no daemon — cuando
//! se daemonice, sustituir el lector de archivo por un sidecar
//! consumer (mismo patrón que `akasha-explorer`).
//! consumer (mismo patrón que `chasqui-explorer`).
//!
//! ## Uso
//!
+1 -1
View File
@@ -17,7 +17,7 @@ shuma-card = { path = "../../modules/shuma/shuma-card" }
shuma-protocol = { path = "../../modules/shuma/shuma-protocol" }
shuma-discern = { path = "../../modules/shuma/shuma-discern" }
shuma-core = { path = "../../modules/shuma/shuma-core" }
ente-incarnate = { path = "../../init/ente-incarnate" }
arje-incarnate = { path = "../../init/arje-incarnate" }
brahman-card = { path = "../../protocol/brahman-card" }
brahman-sidecar = { path = "../../protocol/brahman-sidecar" }
anyhow = { workspace = true }
+1 -1
View File
@@ -12,7 +12,7 @@
use anyhow::Context;
use brahman_card::{Card, CardKind, Flow, Flows, Lifecycle, Payload, Supervision, TypeRef};
use ente_incarnate::IncarnatorConfig;
use arje_incarnate::IncarnatorConfig;
use shuma_core::WorkspaceManager;
use shuma_discern::{DiscernPipeline, Hint};
use shuma_protocol::{
+17 -17
View File
@@ -1,7 +1,7 @@
# compat/ — Shims D-Bus systemd
**Propósito.** Permitir que software systemd-aware (GNOME, KDE,
PolicyKit, NetworkManager, etc.) corra sobre `ente-zero` sin systemd.
PolicyKit, NetworkManager, etc.) corra sobre `arje-zero` sin systemd.
Cada shim es un binario standalone que se anuncia con un nombre
well-known D-Bus y traduce las llamadas al bus interno.
@@ -9,24 +9,24 @@ well-known D-Bus y traduce las llamadas al bus interno.
| binario | reemplaza | D-Bus name |
| --------------------------- | --------------------- | ----------------------------------- |
| `ente-logind-compat` | systemd-logind | `org.freedesktop.login1` |
| `ente-hostnamed-compat` | systemd-hostnamed | `org.freedesktop.hostname1` |
| `ente-timedated-compat` | systemd-timedated | `org.freedesktop.timedate1` |
| `ente-localed-compat` | systemd-localed | `org.freedesktop.locale1` |
| `ente-journald-compat` | systemd-journald | `org.freedesktop.LogControl1` |
| `ente-resolved-compat` | systemd-resolved | `org.freedesktop.resolve1` |
| `ente-polkit-compat` | polkitd | `org.freedesktop.PolicyKit1` |
| `ente-machined-compat` | systemd-machined | `org.freedesktop.machine1` |
| `ente-systemd1-compat` | systemd Manager | `org.freedesktop.systemd1` |
| `ente-notify-compat` | sd_notify socket | `/run/systemd/notify` (datagram) |
| `ente-timer-compat` | systemd timers | (cron-like, sin D-Bus) |
| `ente-tmpfiles-compat` | systemd-tmpfiles | (aplica tmpfiles.d al boot) |
| `ente-binfmt-compat` | systemd-binfmt | (registra handlers binfmt_misc) |
| `ente-policy-provider` | (interno) | provider de decisiones polkit |
| `arje-logind-compat` | systemd-logind | `org.freedesktop.login1` |
| `arje-hostnamed-compat` | systemd-hostnamed | `org.freedesktop.hostname1` |
| `arje-timedated-compat` | systemd-timedated | `org.freedesktop.timedate1` |
| `arje-localed-compat` | systemd-localed | `org.freedesktop.locale1` |
| `arje-journald-compat` | systemd-journald | `org.freedesktop.LogControl1` |
| `arje-resolved-compat` | systemd-resolved | `org.freedesktop.resolve1` |
| `arje-polkit-compat` | polkitd | `org.freedesktop.PolicyKit1` |
| `arje-machined-compat` | systemd-machined | `org.freedesktop.machine1` |
| `arje-systemd1-compat` | systemd Manager | `org.freedesktop.systemd1` |
| `arje-notify-compat` | sd_notify socket | `/run/systemd/notify` (datagram) |
| `arje-timer-compat` | systemd timers | (cron-like, sin D-Bus) |
| `arje-tmpfiles-compat` | systemd-tmpfiles | (aplica tmpfiles.d al boot) |
| `arje-binfmt-compat` | systemd-binfmt | (registra handlers binfmt_misc) |
| `arje-policy-provider` | (interno) | provider de decisiones polkit |
## Dependencias
- Todos ← `zbus`, `ente-bus`, `protocol/brahman-card`. Sin tests
- Todos ← `zbus`, `arje-bus`, `protocol/brahman-card`. Sin tests
(esperado: stubs D-Bus que delegan al bus interno).
## Patrón común
@@ -35,7 +35,7 @@ Cada shim:
1. Se conecta a `/run/brahman/bus`.
2. Reclama un well-known name vía zbus.
3. Implementa los métodos de la interfaz mínima usada por el ecosistema.
4. Loggea eventos al audit log de `ente-brain`.
4. Loggea eventos al audit log de `arje-brain`.
## Estado
@@ -1,12 +1,12 @@
[package]
name = "ente-binfmt-compat"
name = "arje-binfmt-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-binfmt-compat"
name = "arje-binfmt-compat"
path = "src/main.rs"
[dependencies]
@@ -104,6 +104,6 @@ fn register(line: &str) -> Result<String, RegError> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_binfmt_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_binfmt_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-hostnamed-compat"
name = "arje-hostnamed-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-hostnamed-compat"
name = "arje-hostnamed-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
nix = { workspace = true }
libc = { workspace = true }
anyhow = { workspace = true }
@@ -8,8 +8,8 @@
//! Set* methods: log + forward al bus interno (no aplicamos cambios reales
//! en el stub — un siguiente paso es persistir a /etc/* y rehash).
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::sync::Mutex;
use tokio::signal::unix::{signal, SignalKind};
use tracing::{info, warn};
@@ -311,7 +311,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa0; 16]),
interface: arje_card::InterfaceId([0xa0; 16]),
version: 1,
}],
};
@@ -335,6 +335,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_hostnamed_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_hostnamed_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,22 +1,22 @@
[package]
name = "ente-journald-compat"
name = "arje-journald-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-journald-compat"
name = "arje-journald-compat"
path = "src/main.rs"
[[bin]]
name = "ente-journalctl"
name = "arje-journalctl"
path = "src/journalctl.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
ente-cas = { path = "../../runtime/ente-cas" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
arje-cas = { path = "../../runtime/arje-cas" }
nix = { workspace = true }
libc = { workspace = true }
anyhow = { workspace = true }
@@ -155,7 +155,7 @@ fn main() -> anyhow::Result<()> {
let mut out: Vec<(IndexEntry, String)> = entries.into_iter()
.filter_map(|e| {
let sha = parse_sha(&e.sha_hex)?;
let bytes = ente_cas::resolve(&sha).ok()?;
let bytes = arje_cas::resolve(&sha).ok()?;
let body = String::from_utf8_lossy(&bytes).into_owned();
Some((e, body))
})
@@ -7,8 +7,8 @@
//! Para una implementación real: persistir a CAS por timestamp+sha,
//! exponer query API, indexar por unidad/usuario.
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::os::fd::{AsRawFd, OwnedFd};
use std::path::{Path, PathBuf};
use std::sync::Mutex;
@@ -127,13 +127,13 @@ fn now_ms() -> u128 {
/// `<timestamp_ms>:<source>:<unit>:<sha_hex>`. Errores se logean pero
/// no abortan — perder un mensaje no debe romper journald.
fn persist_to_cas(buf: &[u8], source: &'static str, unit: Option<&str>) {
let sha = match ente_cas::store(buf) {
let sha = match arje_cas::store(buf) {
Ok(s) => s,
Err(e) => { warn!(?e, "CAS store falló"); return; }
};
let line = format!(
"{}:{}:{}:{}\n",
now_ms(), source, unit.unwrap_or("-"), ente_cas::hex(&sha)
now_ms(), source, unit.unwrap_or("-"), arje_cas::hex(&sha)
);
let path = index_path();
let _guard = INDEX_FILE.lock().unwrap();
@@ -213,6 +213,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_journald_compat=info,journal=info,syslog=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_journald_compat=info,journal=info,syslog=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-localed-compat"
name = "arje-localed-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-localed-compat"
name = "arje-localed-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
@@ -3,8 +3,8 @@
//! GNOME settings panel "Region & Language" llama aquí. Properties leen
//! /etc/locale.conf y /etc/vconsole.conf; setters log + forward.
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::sync::Mutex;
use tokio::signal::unix::{signal, SignalKind};
use tracing::{info, warn};
@@ -190,7 +190,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa2; 16]),
interface: arje_card::InterfaceId([0xa2; 16]),
version: 1,
}],
};
@@ -214,6 +214,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_localed_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_localed_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-polkit-compat"
name = "arje-logind-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-polkit-compat"
name = "arje-logind-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
@@ -18,8 +18,8 @@
//! El stub responde "no hay sesiones" y "sí puedo apagar" — suficiente para
//! que GNOME complete arranque sin marcar fallo.
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::sync::atomic::{AtomicU32, Ordering};
use std::time::Duration;
use tokio::signal::unix::{signal, SignalKind};
@@ -120,7 +120,7 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_logind_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_logind_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-machined-compat"
name = "arje-machined-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-machined-compat"
name = "arje-machined-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
@@ -13,8 +13,8 @@
//! Producción real: integrar con el graph del fractal — ListMachines query
//! BusRequest::ListEntes filtrado por `card.soma.namespaces.pid`.
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::collections::HashMap;
use tokio::signal::unix::{signal, SignalKind};
use tracing::{info, warn};
@@ -157,7 +157,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa5; 16]),
interface: arje_card::InterfaceId([0xa5; 16]),
version: 1,
}],
};
@@ -181,6 +181,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_machined_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_machined_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-notify-compat"
name = "arje-notify-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-notify-compat"
name = "arje-notify-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
nix = { workspace = true }
libc = { workspace = true }
anyhow = { workspace = true }
@@ -15,8 +15,8 @@
//! en el envp de cada Ente encarnado. Eso ya lo hace via build_env() —
//! aquí sólo necesitamos que el path sea coherente.
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::os::fd::{AsRawFd, OwnedFd};
use std::path::Path;
use tokio::io::unix::AsyncFd;
@@ -131,7 +131,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa7; 16]),
interface: arje_card::InterfaceId([0xa7; 16]),
version: 1,
}],
};
@@ -155,6 +155,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_notify_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_notify_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-policy-provider"
name = "arje-policy-provider"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-policy-provider"
name = "arje-policy-provider"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
serde = { workspace = true }
serde_json = { workspace = true }
anyhow = { workspace = true }
@@ -20,8 +20,8 @@
//! }
//! ```
use ente_bus::{BusResponse, BusServer, InvokeHandler, POLKIT_DECISION_IFACE};
use ente_card::Capability;
use arje_bus::{BusResponse, BusServer, InvokeHandler, POLKIT_DECISION_IFACE};
use arje_card::Capability;
use serde::Deserialize;
use std::sync::Arc;
use tokio::signal::unix::{signal, SignalKind};
@@ -216,6 +216,6 @@ fn load_policy() -> PolicyConfig {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_policy_provider=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_policy_provider=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-logind-compat"
name = "arje-polkit-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-logind-compat"
name = "arje-polkit-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
@@ -14,8 +14,8 @@
//! CheckAuthorization solicita un token al graph y devuelve true/false
//! según el resultado.
use ente_bus::{BusClient, BusRequest, BusResponse, POLKIT_DECISION_IFACE, POLKIT_SERVICE_IFACE};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse, POLKIT_DECISION_IFACE, POLKIT_SERVICE_IFACE};
use arje_card::Capability;
use std::collections::HashMap;
use tokio::signal::unix::{signal, SignalKind};
use tracing::{debug, info, warn};
@@ -259,6 +259,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_polkit_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_polkit_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-resolved-compat"
name = "arje-resolved-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-resolved-compat"
name = "arje-resolved-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
libc = { workspace = true }
anyhow = { workspace = true }
tokio = { workspace = true }
@@ -9,8 +9,8 @@
//! - ResolveAddress (address → name reverse)
//! - ResolveRecord (TXT/SRV/etc) — NotSupported (requiere DNS query directa)
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::net::IpAddr;
use tokio::signal::unix::{signal, SignalKind};
use tracing::{info, warn};
@@ -181,7 +181,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa3; 16]),
interface: arje_card::InterfaceId([0xa3; 16]),
version: 1,
}],
};
@@ -205,6 +205,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_resolved_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_resolved_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -0,0 +1,19 @@
[package]
name = "arje-systemd1-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "arje-systemd1-compat"
path = "src/main.rs"
[dependencies]
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
zbus = { version = "4", default-features = false, features = ["tokio"] }
@@ -18,8 +18,8 @@
//! - ListUnitFiles (vacío)
//! - GetVersion / Environment / Architecture (properties)
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::collections::HashMap;
use tokio::signal::unix::{signal, SignalKind};
use tracing::{info, warn};
@@ -223,7 +223,7 @@ impl SystemdManager {
}
/// Pregunta al bus interno por la lista de Entes vivos.
async fn query_list_entes() -> Option<Vec<ente_bus::EnteInfo>> {
async fn query_list_entes() -> Option<Vec<arje_bus::EnteInfo>> {
let mut client = match BusClient::from_env().await {
Ok(c) => c,
Err(e) => { warn!(?e, "no bus client — devuelvo vacío"); return None; }
@@ -248,7 +248,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa6; 16]),
interface: arje_card::InterfaceId([0xa6; 16]),
version: 1,
}],
};
@@ -272,7 +272,7 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_systemd1_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_systemd1_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -0,0 +1,19 @@
[package]
name = "arje-timedated-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "arje-timedated-compat"
path = "src/main.rs"
[dependencies]
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
zbus = { version = "4", default-features = false, features = ["tokio"] }
@@ -3,8 +3,8 @@
//! GNOME settings panel "Date & Time" llama aquí. Properties read-only se
//! mapean a syscalls/lecturas del sistema; setters log + forward.
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::signal::unix::{signal, SignalKind};
use tracing::{info, warn};
@@ -153,7 +153,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa1; 16]),
interface: arje_card::InterfaceId([0xa1; 16]),
version: 1,
}],
};
@@ -177,6 +177,6 @@ async fn wait_for_term() -> anyhow::Result<()> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_timedated_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_timedated_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,17 +1,17 @@
[package]
name = "ente-timer-compat"
name = "arje-timer-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-timer-compat"
name = "arje-timer-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
serde = { workspace = true }
serde_json = { workspace = true }
ulid = { workspace = true }
@@ -31,8 +31,8 @@
//! Para el demo: log "FIRE" cada vez que el schedule matchea, sin spawn real
//! (requiere mover SpawnRequest al protocolo del bus, fuera de scope).
use ente_bus::{BusClient, BusRequest, BusResponse};
use ente_card::Capability;
use arje_bus::{BusClient, BusRequest, BusResponse};
use arje_card::Capability;
use serde::Deserialize;
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::signal::unix::{signal, SignalKind};
@@ -209,7 +209,7 @@ async fn announce_to_fractal() {
if let Ok(mut client) = BusClient::from_env().await {
let req = BusRequest::Announce {
capabilities: vec![Capability::Endpoint {
interface: ente_card::InterfaceId([0xa8; 16]),
interface: arje_card::InterfaceId([0xa8; 16]),
version: 1,
}],
};
@@ -223,6 +223,6 @@ async fn announce_to_fractal() {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_timer_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_timer_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,12 +1,12 @@
[package]
name = "ente-tmpfiles-compat"
name = "arje-tmpfiles-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-tmpfiles-compat"
name = "arje-tmpfiles-compat"
path = "src/main.rs"
[dependencies]
@@ -276,6 +276,6 @@ fn lookup_gid(name: &str) -> anyhow::Result<u32> {
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_tmpfiles_compat=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_tmpfiles_compat=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
}
@@ -1,19 +0,0 @@
[package]
name = "ente-systemd1-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-systemd1-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
zbus = { version = "4", default-features = false, features = ["tokio"] }
@@ -1,19 +0,0 @@
[package]
name = "ente-timedated-compat"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-timedated-compat"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
zbus = { version = "4", default-features = false, features = ["tokio"] }
+9 -9
View File
@@ -1,6 +1,6 @@
# init/ — Init (PID 1) y encarnación Linux
**Propósito.** `ente-zero` arranca como PID 1 del fractal. Provee el
**Propósito.** `arje-zero` arranca como PID 1 del fractal. Provee el
bucle primordial (reap + bus + handshake), bootstrap del kernel
surface, encarnación de Cards en procesos aislados con namespaces +
cgroups, y snapshot/restore del grafo.
@@ -9,21 +9,21 @@ cgroups, y snapshot/restore del grafo.
| crate | tipo | rol |
| ---------------- | ------- | ----------------------------------------------------- |
| `ente-zero` | binario | PID 1: reap + handshake server + bus dispatcher |
| `ente-kernel` | lib | `bootstrap_kernel_surface`, subreaper, SIGCHLD/uevent |
| `ente-soma` | lib | Wrapper 44 LOC sobre `ente-incarnate` (compat API) |
| `ente-incarnate` | lib | `clone(2) + namespaces + cgroup + rlimits + cpu` |
| `ente-snapshot` | lib | `FractalSnapshot` JSON: checkpoint del grafo Cards |
| `arje-zero` | binario | PID 1: reap + handshake server + bus dispatcher |
| `arje-kernel` | lib | `bootstrap_kernel_surface`, subreaper, SIGCHLD/uevent |
| `arje-soma` | lib | Wrapper 44 LOC sobre `arje-incarnate` (compat API) |
| `arje-incarnate` | lib | `clone(2) + namespaces + cgroup + rlimits + cpu` |
| `arje-snapshot` | lib | `FractalSnapshot` JSON: checkpoint del grafo Cards |
## Dependencias
- `ente-kernel``nix`, `libc`, syscalls Linux puras.
- `ente-incarnate` reusable: shuma (sandboxes) y supervisores no-PID-1.
- `arje-kernel``nix`, `libc`, syscalls Linux puras.
- `arje-incarnate` reusable: shuma (sandboxes) y supervisores no-PID-1.
- Consume `protocol/` (handshake server, brahman-net opcional).
## Boot path
1. Kernel pasa control → `ente-zero` arranca como `/sbin/init`.
1. Kernel pasa control → `arje-zero` arranca como `/sbin/init`.
2. Levanta sockets: `/run/brahman/bus`, `/run/brahman/handshake`.
3. Lee `Card` semilla (`seeds/arje-{minimal,host,prod}.card.json`).
4. Para cada `genesis` child Card: `incarnate(card)` → spawn aislado.
@@ -1,5 +1,5 @@
[package]
name = "ente-incarnate"
name = "arje-incarnate"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
@@ -1,12 +1,12 @@
[package]
name = "ente-kernel"
name = "arje-kernel"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
arje-card = { path = "../../protocol/arje-card" }
nix = { workspace = true }
libc = { workspace = true }
tokio = { workspace = true }
@@ -5,7 +5,7 @@
//! continuar sin grafo de dispositivos.
use anyhow::Context;
use ente_card::DeviceClass;
use arje_card::DeviceClass;
use nix::sys::socket::{bind, socket, AddressFamily, NetlinkAddr, SockFlag, SockProtocol, SockType};
use std::collections::HashMap;
use std::os::fd::{AsRawFd, OwnedFd};
@@ -1,12 +1,12 @@
[package]
name = "ente-snapshot"
name = "arje-snapshot"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
arje-card = { path = "../../protocol/arje-card" }
serde = { workspace = true }
serde_json = { workspace = true }
ulid = { workspace = true }
@@ -9,7 +9,7 @@
//! - pending_invokes (en vuelo, se descartan)
//! - device presence (uevents reconstruyen el índice)
use ente_card::EntityCard;
use arje_card::EntityCard;
use serde::{Deserialize, Serialize};
use std::path::Path;
use ulid::Ulid;
+15
View File
@@ -0,0 +1,15 @@
[package]
name = "arje-soma"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
description = "Wrapper histórico sobre arje-incarnate para mantener la API set_bus_sock+incarnate que usa arje-zero. Toda la lógica vive en arje-incarnate."
[dependencies]
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
arje-incarnate = { path = "../arje-incarnate" }
nix = { workspace = true }
anyhow = { workspace = true }
tracing = { workspace = true }
@@ -1,17 +1,17 @@
//! `ente-soma` — wrapper histórico sobre [`ente_incarnate`].
//! `ente-soma` — wrapper histórico sobre [`arje_incarnate`].
//!
//! La rutina de namespacing fue extraída a `ente-incarnate` para que
//! shuma, exploradores y cualquier supervisor no-PID-1 puedan reusarla.
//! Este crate sobrevive como compat para `ente-zero` y otros que importan
//! `ente_soma::{set_bus_sock, incarnate}`.
//! `arje_soma::{set_bus_sock, incarnate}`.
//!
//! Semántica preservada:
//! - `BUS_SOCK_PATH` global vía `OnceLock` (init lo setea una vez).
//! - `NOTIFY_SOCKET=/run/systemd/notify` se inyecta automáticamente.
//! - `strict_caps = false` (errores no-fatales se loguean, encarnación sigue).
use ente_card::EntityCard;
use ente_incarnate::{Incarnator, IncarnatorConfig};
use arje_card::EntityCard;
use arje_incarnate::{Incarnator, IncarnatorConfig};
use nix::unistd::Pid;
use std::path::PathBuf;
use std::sync::OnceLock;
@@ -1,25 +1,25 @@
[package]
name = "ente-zero"
name = "arje-zero"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[[bin]]
name = "ente-zero"
name = "arje-zero"
path = "src/main.rs"
[dependencies]
# Lib crates del fractal — orden: contratos → infra → encarnación → orquestación
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
ente-cas = { path = "../../runtime/ente-cas" }
ente-kernel = { path = "../ente-kernel" }
ente-soma = { path = "../ente-soma" }
ente-wasm = { path = "../../runtime/ente-wasm" }
ente-snapshot = { path = "../ente-snapshot" }
ente-brain = { path = "../../runtime/ente-brain" }
ente-echo = { path = "../../runtime/ente-echo" } # solo para constantes del demo
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../../runtime/arje-bus" }
arje-cas = { path = "../../runtime/arje-cas" }
arje-kernel = { path = "../arje-kernel" }
arje-soma = { path = "../arje-soma" }
arje-wasm = { path = "../../runtime/arje-wasm" }
arje-snapshot = { path = "../arje-snapshot" }
arje-brain = { path = "../../runtime/arje-brain" }
arje-echo = { path = "../../runtime/arje-echo" } # solo para constantes del demo
# Brahman protocol — handshake para módulos brahman conscientes
brahman-handshake = { path = "../../protocol/brahman-handshake" }
@@ -1,7 +1,7 @@
//! Glue entre el bucle primordial y `ente-brain`.
//!
//! Tres responsabilidades:
//! 1. Traducir eventos del grafo (`GraphEvent`) a `ente_brain::EventKind`
//! 1. Traducir eventos del grafo (`GraphEvent`) a `arje_brain::EventKind`
//! + `SubjectInfo` para el observador y el motor.
//! 2. Implementar `ActionSink` para que las Acciones del cerebro tengan
//! un canal de salida hacia el grafo (Spawn → SpawnRequest, etc.).
@@ -10,8 +10,8 @@
use crate::events::GraphEvent;
use crate::graph::EnteGraph;
use ente_brain::{ActionSink, EventKind as BrainEventKind, SubjectInfo};
use ente_card::Capability;
use arje_brain::{ActionSink, EventKind as BrainEventKind, SubjectInfo};
use arje_card::Capability;
use serde::Deserialize;
use tokio::sync::mpsc;
use tracing::warn;
@@ -40,8 +40,8 @@ pub fn graph_event_to_brain<'a>(
}
GraphEvent::BusRequest { from, request, .. } => {
let kind = match request {
ente_bus::BusRequest::Announce { .. } => BrainEventKind::BusAnnounce,
ente_bus::BusRequest::Invoke { cap, .. } => {
arje_bus::BusRequest::Announce { .. } => BrainEventKind::BusAnnounce,
arje_bus::BusRequest::Invoke { cap, .. } => {
BrainEventKind::BusInvokeOf(cap.clone())
}
_ => BrainEventKind::BusInvoke,
@@ -83,7 +83,7 @@ pub struct GraphSink {
impl ActionSink for GraphSink {
fn spawn(&self, card_blob: &str) {
// El blob es JSON de EntityCard.
match serde_json::from_str::<ente_card::EntityCard>(card_blob) {
match serde_json::from_str::<arje_card::EntityCard>(card_blob) {
Ok(card) => {
let evt = GraphEvent::SpawnRequest { card, requester: self.requester };
if self.graph_tx.try_send(evt).is_err() {
@@ -112,11 +112,11 @@ impl ActionSink for GraphSink {
/// Helper para que el grafo exponga la Card de un Ente vivo. Lo añadimos como
/// trait extension porque graph::EnteGraph mantiene `incarnated` privado.
pub trait GraphCardLookup {
fn card_for(&self, id: &Ulid) -> Option<&ente_card::EntityCard>;
fn card_for(&self, id: &Ulid) -> Option<&arje_card::EntityCard>;
}
impl GraphCardLookup for EnteGraph {
fn card_for(&self, id: &Ulid) -> Option<&ente_card::EntityCard> {
fn card_for(&self, id: &Ulid) -> Option<&arje_card::EntityCard> {
// Acceso vía método público que añadiremos en graph/mod.rs.
self.peek_card(id)
}
@@ -10,7 +10,7 @@
//! escritura de su conexión y lo usa para forwardear.
use crate::events::GraphEvent;
use ente_bus::{read_frame, write_frame, BusMessage, BusPayload, BusResponse, PeerCreds};
use arje_bus::{read_frame, write_frame, BusMessage, BusPayload, BusResponse, PeerCreds};
use nix::sys::socket::{getsockopt, sockopt::PeerCredentials};
use std::path::PathBuf;
use tokio::net::{UnixListener, UnixStream};
@@ -19,7 +19,7 @@ use tracing::{error, info, trace, warn};
use ulid::Ulid;
pub fn default_socket_path() -> PathBuf {
if let Ok(p) = std::env::var(ente_bus::ENV_BUS_SOCK) {
if let Ok(p) = std::env::var(arje_bus::ENV_BUS_SOCK) {
return p.into();
}
let runtime = std::env::var("XDG_RUNTIME_DIR")
@@ -97,7 +97,7 @@ async fn handle_conn(stream: UnixStream, graph_tx: mpsc::Sender<GraphEvent>) ->
};
match msg.payload {
BusPayload::Request(req) => {
let is_announce = matches!(req, ente_bus::BusRequest::Announce { .. });
let is_announce = matches!(req, arje_bus::BusRequest::Announce { .. });
let (reply_tx, reply_rx) = oneshot::channel();
if graph_tx.send(GraphEvent::BusRequest {
peer,
@@ -8,8 +8,8 @@
#![allow(dead_code)]
use ente_bus::{BusMessage, BusRequest, BusResponse, PeerCreds};
use ente_card::{Capability, EntityCard};
use arje_bus::{BusMessage, BusRequest, BusResponse, PeerCreds};
use arje_card::{Capability, EntityCard};
use nix::sys::signal::Signal;
use tokio::sync::{mpsc, oneshot};
use ulid::Ulid;
@@ -8,8 +8,8 @@
//! - Cleanup en cierre de conexión
use super::{EnteGraph, SERVER_SEQ_FLAG};
use ente_bus::{BusMessage, BusPayload, BusRequest, BusResponse, EnteInfo, PeerCreds};
use ente_card::Capability;
use arje_bus::{BusMessage, BusPayload, BusRequest, BusResponse, EnteInfo, PeerCreds};
use arje_card::Capability;
use tokio::sync::{mpsc, oneshot};
use tracing::{debug, info, warn};
use ulid::Ulid;
@@ -6,7 +6,7 @@
use super::{quota_for_capability, ttl_for_capability, EnteGraph, GrantedCapability};
use crate::events::CapabilityGrant;
use ente_card::Capability;
use arje_card::Capability;
use std::time::Instant;
use tokio::sync::oneshot;
use tracing::debug;
@@ -3,8 +3,8 @@
use super::EnteGraph;
use crate::events::GraphEvent;
use ente_card::{Capability, DeviceClass};
use ente_kernel::{UAction, UEvent};
use arje_card::{Capability, DeviceClass};
use arje_kernel::{UAction, UEvent};
use tokio::sync::mpsc;
use tracing::{debug, info, warn};
@@ -5,8 +5,8 @@
use super::{EnteGraph, Incarnated};
use crate::events::{ExitStatus, GraphEvent};
use ente_bus::{BusMessage, BusPayload, BusRequest};
use ente_card::{Capability, EntityCard, Payload, Supervision};
use arje_bus::{BusMessage, BusPayload, BusRequest};
use arje_card::{Capability, EntityCard, Payload, Supervision};
use tokio::sync::mpsc;
use tracing::{info, warn};
use ulid::Ulid;
@@ -35,7 +35,7 @@ impl EnteGraph {
/// Spawn solicitado por un Ente con `Capability::Spawn`. Verifica auth,
/// requires del grafo, y delega la encarnación al backend correspondiente
/// (`ente_soma` para procesos, `ente_wasm` para Wasm).
/// (`arje_soma` para procesos, `arje_wasm` para Wasm).
pub async fn authorize_and_spawn(
&mut self,
mut card: EntityCard,
@@ -64,14 +64,14 @@ impl EnteGraph {
let pid = match &card.payload {
Payload::Virtual => None,
Payload::Native { .. } | Payload::Legacy { .. } => {
Some(ente_soma::incarnate(&card)?)
Some(arje_soma::incarnate(&card)?)
}
Payload::Wasm { module_sha256, entry } => {
// Wasm: hilo dedicado, sin PID. Su muerte se observa por
// estado del runtime, no por SIGCHLD.
let bytes = ente_cas::resolve(module_sha256)
let bytes = arje_cas::resolve(module_sha256)
.map_err(|e| anyhow::anyhow!("CAS resolve para {}: {e}", card.label))?;
ente_wasm::incarnate_wasm(&card, bytes, entry.clone())?;
arje_wasm::incarnate_wasm(&card, bytes, entry.clone())?;
None
}
};
@@ -142,7 +142,7 @@ impl EnteGraph {
seq,
payload: BusPayload::Request(BusRequest::Invoke {
cap: Capability::Endpoint {
interface: ente_card::InterfaceId([0xde; 16]),
interface: arje_card::InterfaceId([0xde; 16]),
version: 1,
},
blob: blob.into_bytes(),
@@ -16,8 +16,8 @@ mod lifecycle;
mod shutdown;
mod topology;
use ente_bus::{BusMessage, BusResponse};
use ente_card::{Capability, EntityCard};
use arje_bus::{BusMessage, BusResponse};
use arje_card::{Capability, EntityCard};
use nix::unistd::Pid;
use std::collections::{BTreeMap, BTreeSet, HashMap};
use tokio::sync::{mpsc, oneshot};
@@ -41,7 +41,7 @@ pub struct EnteGraph {
pub(in crate::graph) next_token: u64,
pub(in crate::graph) grants: HashMap<u64, GrantedCapability>,
/// Dispositivos del kernel presentes (devpath → última UEvent).
pub(in crate::graph) devices: HashMap<String, ente_kernel::UEvent>,
pub(in crate::graph) devices: HashMap<String, arje_kernel::UEvent>,
/// Cards genesis pendientes de instanciar (extraídas de la Semilla).
pub(in crate::graph) pending_genesis: Vec<EntityCard>,
/// Hijos directos por lineage. parent → [child, ...].
@@ -166,14 +166,14 @@ impl EnteGraph {
/// Captura el estado live como snapshot serializable. Excluye la Semilla
/// (será re-sintetizada al restore con su seed_id preservado).
pub fn snapshot(&self) -> ente_snapshot::FractalSnapshot {
pub fn snapshot(&self) -> arje_snapshot::FractalSnapshot {
let entes: Vec<EntityCard> = self.incarnated.iter()
.filter(|(id, _)| **id != self.seed.id)
.map(|(_, inc)| inc.card.clone())
.collect();
ente_snapshot::FractalSnapshot {
version: ente_snapshot::SNAPSHOT_VERSION,
timestamp_ms: ente_snapshot::now_ms(),
arje_snapshot::FractalSnapshot {
version: arje_snapshot::SNAPSHOT_VERSION,
timestamp_ms: arje_snapshot::now_ms(),
seed_id: self.seed.id,
seed_label: self.seed.label.clone(),
entes,
@@ -23,8 +23,8 @@ mod keypair_store;
mod seed;
use anyhow::Context;
use ente_brain::{BrainState, IntrospectServer};
use ente_kernel::{become_child_subreaper, bootstrap_kernel_surface, spawn_sigchld_stream, spawn_uevent_stream};
use arje_brain::{BrainState, IntrospectServer};
use arje_kernel::{become_child_subreaper, bootstrap_kernel_surface, spawn_sigchld_stream, spawn_uevent_stream};
use events::{ExitStatus, GraphEvent, ShutdownReason};
use graph::EnteGraph;
use nix::errno::Errno;
@@ -106,7 +106,7 @@ fn main() -> anyhow::Result<()> {
}
async fn primordial_loop(
seed_card: ente_card::EntityCard,
seed_card: arje_card::EntityCard,
dev_mode: bool,
checkpoint_path: Option<PathBuf>,
restore_path: Option<PathBuf>,
@@ -127,7 +127,7 @@ async fn primordial_loop(
Ok(rx) => rx,
Err(e) => {
warn!(?e, "uevents deshabilitados (probablemente falta CAP_NET_ADMIN)");
let (_keep_tx, rx) = mpsc::channel::<ente_kernel::UEvent>(1);
let (_keep_tx, rx) = mpsc::channel::<arje_kernel::UEvent>(1);
std::mem::forget(_keep_tx);
rx
}
@@ -137,7 +137,7 @@ async fn primordial_loop(
// tenga adónde llegar. Su path se inyecta en ENTE_BUS_SOCK por soma.
let bus_sock = bus::default_socket_path();
let bus_path = bus::spawn_bus(bus_sock, graph_tx.clone())?;
ente_soma::set_bus_sock(bus_path.to_string_lossy().into_owned());
arje_soma::set_bus_sock(bus_path.to_string_lossy().into_owned());
// Brahman protocol: handshake socket + broker compartido.
//
@@ -285,7 +285,7 @@ async fn primordial_loop(
// Umbrales relajados para que el demo (pocos eventos) produzca
// cristales observables. Con P(b|a) normalizada a [0,1], los
// valores típicos en muestras pequeñas son 0.2-0.5.
BrainState::with_params(1024, ente_brain::CrystallizationParams {
BrainState::with_params(1024, arje_brain::CrystallizationParams {
min_support: 2,
min_conditional_prob: 0.3,
min_pmi: 1.0,
@@ -300,13 +300,13 @@ async fn primordial_loop(
let mut obs = brain.observer.write().await;
// Reemplazar con un observer nuevo que tenga half-life. Estado
// anterior (vacío en este punto) descartado.
*obs = ente_brain::Observer::new(1024).with_half_life(hl);
*obs = arje_brain::Observer::new(1024).with_half_life(hl);
info!(hl_secs = hl, "observer con time-decay activo");
}
if let Some(secs) = autopromote_secs {
ente_brain::spawn_autopromote_loop(
arje_brain::spawn_autopromote_loop(
brain.clone(),
ente_brain::AutopromoteParams {
arje_brain::AutopromoteParams {
interval_secs: secs,
threshold: brain.params, // mismo threshold que crystals manuales
},
@@ -322,7 +322,7 @@ async fn primordial_loop(
Ok(snap) => {
let total = snap.total;
let kinds = snap.marginal.len();
let restored = ente_brain::Observer::from_snapshot(snap);
let restored = arje_brain::Observer::from_snapshot(snap);
*brain.observer.write().await = restored;
info!(
path = %brain_path.display(),
@@ -337,7 +337,7 @@ async fn primordial_loop(
// Si --audit-head, configuramos el head pointer y arrancamos auto-flush.
if let Some(head_path) = audit_head {
// Re-creamos el AuditLog con head pointer.
let new_audit = ente_brain::audit::AuditLog::new()
let new_audit = arje_brain::audit::AuditLog::new()
.with_head_pointer(head_path);
*brain.audit.write().await = new_audit;
spawn_audit_auto_flush(brain.clone());
@@ -345,7 +345,7 @@ async fn primordial_loop(
// Carga inicial de reglas desde JSON/JSONL si --rules path proporcionado.
if let Some(path) = &rules_path {
match ente_brain::load_rules_file(path) {
match arje_brain::load_rules_file(path) {
Ok(rules) => {
let mut engine = brain.engine.write().await;
for r in rules {
@@ -367,7 +367,7 @@ async fn primordial_loop(
Ok(addr) => {
let s = brain.clone();
tokio::spawn(async move {
if let Err(e) = ente_brain::serve_metrics(s, addr).await {
if let Err(e) = arje_brain::serve_metrics(s, addr).await {
warn!(?e, "metrics server cayó");
}
});
@@ -536,14 +536,14 @@ async fn emit_death(
fn spawn_echo_smoke_test(bus_path: PathBuf) {
tokio::spawn(async move {
tokio::time::sleep(Duration::from_millis(300)).await;
match ente_bus::BusClient::connect(&bus_path).await {
match arje_bus::BusClient::connect(&bus_path).await {
Ok(mut client) => {
let req = ente_bus::BusRequest::Invoke {
cap: ente_echo::echo_capability(),
let req = arje_bus::BusRequest::Invoke {
cap: arje_echo::echo_capability(),
blob: b"hola fractal forwardeado".to_vec(),
};
match client.call(req).await {
Ok(ente_bus::BusResponse::Invoked { result }) => {
Ok(arje_bus::BusResponse::Invoked { result }) => {
info!(echo = %String::from_utf8_lossy(&result), "Invoke ECHO round-trip OK");
}
Ok(other) => warn!(?other, "Invoke ECHO respuesta inesperada"),
@@ -555,7 +555,7 @@ fn spawn_echo_smoke_test(bus_path: PathBuf) {
});
}
fn write_brain_snapshot(path: &std::path::Path, snap: &ente_brain::observer::ObserverSnapshot) -> anyhow::Result<()> {
fn write_brain_snapshot(path: &std::path::Path, snap: &arje_brain::observer::ObserverSnapshot) -> anyhow::Result<()> {
let bytes = serde_json::to_vec_pretty(snap)?;
if let Some(parent) = path.parent() { let _ = std::fs::create_dir_all(parent); }
let tmp = path.with_extension("tmp");
@@ -564,16 +564,16 @@ fn write_brain_snapshot(path: &std::path::Path, snap: &ente_brain::observer::Obs
Ok(())
}
fn read_brain_snapshot(path: &std::path::Path) -> anyhow::Result<ente_brain::observer::ObserverSnapshot> {
fn read_brain_snapshot(path: &std::path::Path) -> anyhow::Result<arje_brain::observer::ObserverSnapshot> {
let bytes = std::fs::read(path)?;
let snap: ente_brain::observer::ObserverSnapshot = serde_json::from_slice(&bytes)?;
let snap: arje_brain::observer::ObserverSnapshot = serde_json::from_slice(&bytes)?;
Ok(snap)
}
fn init_tracing() {
use tracing_subscriber::{fmt, EnvFilter};
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_zero=debug,info"));
.unwrap_or_else(|_| EnvFilter::new("arje_zero=debug,info"));
fmt().with_env_filter(filter).with_target(true).init();
}
@@ -625,7 +625,7 @@ async fn feed_brain(
evt: &GraphEvent,
) {
let Some((kind, subj)) = brain_glue::graph_event_to_brain(evt, graph) else { return };
let history: Vec<ente_brain::TimedEvent> = {
let history: Vec<arje_brain::TimedEvent> = {
let mut obs = brain.observer.write().await;
obs.record(kind.clone());
// Snapshot de los últimos 16 eventos — suficiente para cualquier
@@ -637,7 +637,7 @@ async fn feed_brain(
engine.dispatch(&kind, &subj, &history)
};
if !rules.is_empty() {
ente_brain::dispatch_actions(&rules, sink).await;
arje_brain::dispatch_actions(&rules, sink).await;
}
}
@@ -8,7 +8,7 @@
//! todas las capacidades del fractal.
use anyhow::Context;
use ente_card::{
use arje_card::{
Capability, CardError, CgroupSpec, EntityCard, NamespaceSet, Payload,
ResourceLimits, SomaSpec, Supervision, CARD_SCHEMA_VERSION,
};
@@ -33,7 +33,7 @@ pub fn load(dev_mode: bool, restore: Option<&Path>) -> anyhow::Result<EntityCard
}
fn load_from_snapshot(path: &Path) -> anyhow::Result<EntityCard> {
let snap = ente_snapshot::FractalSnapshot::read(path)
let snap = arje_snapshot::FractalSnapshot::read(path)
.with_context(|| format!("read snapshot {}", path.display()))?;
info!(
path = %path.display(),
@@ -66,7 +66,7 @@ fn load_from_snapshot(path: &Path) -> anyhow::Result<EntityCard> {
fn load_or_synthesize(dev_mode: bool) -> anyhow::Result<EntityCard> {
// Buscamos primero `.json` (canónico), luego sin extensión por
// compatibilidad con instalaciones que dejan el archivo crudo. La puerta
// genética se cruza vía `ente_brain::load_card_file` que pasa por
// genética se cruza vía `arje_brain::load_card_file` que pasa por
// `validate()` extendido.
let candidates: &[&str] = if dev_mode {
&["seed.card.json", SEED_PATH_DEV]
@@ -76,7 +76,7 @@ fn load_or_synthesize(dev_mode: bool) -> anyhow::Result<EntityCard> {
for cand in candidates {
let path = PathBuf::from(cand);
if !path.exists() { continue; }
let card = ente_brain::load_card_file(&path)
let card = arje_brain::load_card_file(&path)
.with_context(|| format!("load {}", path.display()))?;
info!(path = %path.display(), "Tarjeta Semilla cargada y validada");
return Ok(card);
@@ -96,8 +96,8 @@ fn synthesize_dev_seed() -> EntityCard {
// Pre-registramos el módulo Wasm demo en el CAS y obtenemos su SHA real.
// Si el CAS no es escribible (raro en dev) caemos a un SHA cero — la
// resolución fallará y el Wasm no encarnará, pero el resto queda intacto.
let demo_wasm_sha = match ente_wasm::demo_module_bytes()
.and_then(|b| ente_cas::store(&b))
let demo_wasm_sha = match arje_wasm::demo_module_bytes()
.and_then(|b| arje_cas::store(&b))
{
Ok(sha) => sha,
Err(e) => {
@@ -134,7 +134,7 @@ fn synthesize_dev_seed() -> EntityCard {
if let Some(card) = optional_native_card(
"demo-echo", "target/debug/ente-echo",
[ente_echo::echo_capability()].into_iter().collect(),
[arje_echo::echo_capability()].into_iter().collect(),
restart_supervision(),
) {
genesis.push(card);
-15
View File
@@ -1,15 +0,0 @@
[package]
name = "ente-soma"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
description = "Wrapper histórico sobre ente-incarnate para mantener la API set_bus_sock+incarnate que usa ente-zero. Toda la lógica vive en ente-incarnate."
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../../runtime/ente-bus" }
ente-incarnate = { path = "../ente-incarnate" }
nix = { workspace = true }
anyhow = { workspace = true }
tracing = { workspace = true }
@@ -1,5 +1,5 @@
[package]
name = "akasha-card"
name = "chasqui-card"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
@@ -1,4 +1,4 @@
//! `akasha-card` — manifiesto de Mónada.
//! `chasqui-card` — manifiesto de Mónada.
//!
//! Una **Mónada** es una agrupación semántica de archivos: el archivo
//! físico no se mueve, pero su pertenencia se modela por un objeto
@@ -10,7 +10,7 @@
//!
//! Diferencia con `brahman-card::Card`:
//!
//! | brahman::Card | akasha::MonadManifest |
//! | brahman::Card | chasqui::MonadManifest |
//! |-------------------------------------|-------------------------------|
//! | Describe una **entidad runtime** | Describe una **agrupación** |
//! | Tiene `payload`/`soma`/`supervision`| No tiene proceso detrás |
@@ -18,7 +18,7 @@
//! | Fluye por handshake/postcard | Fluye por queries del backend |
//!
//! Este crate sólo define los tipos. La lógica de scan, cluster,
//! attraction vive en `akasha-core`.
//! attraction vive en `chasqui-core`.
#![forbid(unsafe_code)]
#![warn(rust_2018_idioms)]
@@ -1,12 +1,12 @@
//! Wire types para consultar al daemon `akasha` por sus Mónadas.
//! Wire types para consultar al daemon `chasqui` por sus Mónadas.
//!
//! El daemon expone un Unix socket (cuyo path se publica en
//! `Card.service_socket` y se descubre vía broker MatchEvent). Cada
//! conexión es single-shot: una request JSON terminada en `\n`,
//! una response JSON terminada en `\n`, cierre.
//!
//! Mismo patrón que `akasha-nous` (mock/real ↔ akasha-core), reusado
//! ahora para que la UI (`akasha-explorer`) descubra y consulte al
//! Mismo patrón que `chasqui-nous` (mock/real ↔ chasqui-core), reusado
//! ahora para que la UI (`chasqui-explorer`) descubra y consulte al
//! daemon sin hardcodear sockets ni pasar por brahman-admin.
//!
//! ## Contrato
@@ -118,7 +118,7 @@ impl MonadView {
/// Error de protocolo retornado en lugar de la response normal.
#[derive(Debug, Clone, Serialize, Deserialize, Error)]
#[error("akasha-engine: {error}")]
#[error("chasqui-engine: {error}")]
pub struct ErrorResponse {
pub error: String,
}
@@ -135,7 +135,7 @@ pub mod transport {
pub const SOCKET_ENV: &str = "NOUSER_ENGINE_SOCKET";
/// Nombre por defecto del socket.
pub const SOCKET_NAME: &str = "akasha-engine.sock";
pub const SOCKET_NAME: &str = "chasqui-engine.sock";
/// Ruta canónica al socket del daemon. Honra `NOUSER_ENGINE_SOCKET`
/// si está set, sino arma sobre `$XDG_RUNTIME_DIR` (con fallback
@@ -154,7 +154,7 @@ pub mod transport {
// =====================================================================
// Cliente blocking — vive con los wire types para que un consumer
// (UI, CLI, otro módulo) pueda hablar con el daemon importando sólo
// `akasha-card`, sin arrastrar `akasha-core` (notify/walkdir/sled/blake3).
// `chasqui-card`, sin arrastrar `chasqui-core` (notify/walkdir/sled/blake3).
// =====================================================================
/// Cliente síncrono para el query socket del daemon. Sólo Unix (el
@@ -1,5 +1,5 @@
[package]
name = "akasha-core"
name = "chasqui-core"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
@@ -9,8 +9,8 @@ publish.workspace = true
description = "Nouser — explorador de Mónadas: scanner, clustering determinista, DB en memoria."
[dependencies]
akasha-card = { path = "../card" }
akasha-nous = { path = "../nous" }
chasqui-card = { path = "../card" }
chasqui-nous = { path = "../nous" }
shuma-discern = { path = "../../shuma/shuma-discern" }
brahman-card = { path = "../../../protocol/brahman-card" }
brahman-handshake = { path = "../../../protocol/brahman-handshake" }
@@ -29,5 +29,5 @@ notify = { workspace = true }
tempfile = { workspace = true }
[[bin]]
name = "akasha"
name = "chasqui"
path = "src/bin/nouser.rs"
@@ -1,4 +1,4 @@
//! `akasha` CLI — explorador de Mónadas.
//! `chasqui` CLI — explorador de Mónadas.
//!
//! Subcomandos:
//!
@@ -13,14 +13,14 @@
use std::path::PathBuf;
use std::process::ExitCode;
use akasha_core::{
use chasqui_core::{
cluster, db, embed,
scanner::{self, ScanConfig},
};
fn main() -> ExitCode {
let args: Vec<String> = std::env::args().collect();
let prog = args.first().cloned().unwrap_or_else(|| "akasha".into());
let prog = args.first().cloned().unwrap_or_else(|| "chasqui".into());
let sub = match args.get(1).map(String::as_str) {
Some(s) => s,
None => {
@@ -41,7 +41,7 @@ fn main() -> ExitCode {
return ExitCode::SUCCESS;
}
other => {
eprintln!("akasha: comando desconocido '{other}'");
eprintln!("chasqui: comando desconocido '{other}'");
print_usage(&prog);
return ExitCode::from(2);
}
@@ -50,7 +50,7 @@ fn main() -> ExitCode {
match result {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("akasha: {e}");
eprintln!("chasqui: {e}");
ExitCode::from(1)
}
}
@@ -181,7 +181,7 @@ fn cmd_daemon(args: &[String]) -> Cmd {
// 1. Decidir el path del query socket ANTES de armar el engine
// Card (porque viaja como service_socket en la Card).
let query_socket = akasha_card::query::transport::default_socket_path();
let query_socket = chasqui_card::query::transport::default_socket_path();
// 2. Engine como Ente. Declara service_socket + flow.output para
// que el broker pueda emitir MatchEvent::Available a consumers
@@ -190,7 +190,7 @@ fn cmd_daemon(args: &[String]) -> Cmd {
let engine_id = engine_card.id;
let engine_label = engine_card.label.clone();
eprintln!(
"akasha daemon: publicando engine '{}' (kind=Ente, id={}, socket={})",
"chasqui daemon: publicando engine '{}' (kind=Ente, id={}, socket={})",
engine_label,
engine_id,
query_socket.display()
@@ -227,7 +227,7 @@ fn cmd_daemon(args: &[String]) -> Cmd {
hydrated += 1;
}
eprintln!(
"akasha daemon: hidratadas {} mónadas previas{} en O(1)",
"chasqui daemon: hidratadas {} mónadas previas{} en O(1)",
hydrated,
if skipped_model > 0 {
format!(" ({} dropeadas por centroid_model distinto)", skipped_model)
@@ -245,7 +245,7 @@ fn cmd_daemon(args: &[String]) -> Cmd {
let monads = cluster::by_directory_hydrated(&files, min_files(), Some(&db));
let scanned_count = monads.len();
eprintln!(
"akasha daemon: re-scan {} archivos en {} → {} mónadas",
"chasqui daemon: re-scan {} archivos en {} → {} mónadas",
n_files,
dir.display(),
scanned_count
@@ -276,7 +276,7 @@ fn cmd_daemon(args: &[String]) -> Cmd {
db.replace_monads(monads);
eprintln!(
"akasha daemon: 1 ente + {} mónadas vivas ({} nuevas vs hidratación)",
"chasqui daemon: 1 ente + {} mónadas vivas ({} nuevas vs hidratación)",
scanned_count, newly_spawned
);
@@ -285,8 +285,8 @@ fn cmd_daemon(args: &[String]) -> Cmd {
// Si el bind falla, seguimos sin él — la UI degrada a "no
// alcanzable" pero el daemon sigue procesando cambios.
let db_shared = std::sync::Arc::new(std::sync::Mutex::new(db));
let _query_listener = match akasha_core::engine_socket::spawn_listener(
akasha_core::engine_socket::ListenerConfig {
let _query_listener = match chasqui_core::engine_socket::spawn_listener(
chasqui_core::engine_socket::ListenerConfig {
socket_path: query_socket.clone(),
engine_id,
engine_label: engine_label.clone(),
@@ -296,14 +296,14 @@ fn cmd_daemon(args: &[String]) -> Cmd {
) {
Ok(h) => {
eprintln!(
"akasha daemon: query socket activo en {} (proto: akasha_card::query)",
"chasqui daemon: query socket activo en {} (proto: chasqui_card::query)",
query_socket.display()
);
Some(h)
}
Err(e) => {
eprintln!(
"akasha daemon: query socket NO disponible ({e}) — explorer no podrá consultar"
"chasqui daemon: query socket NO disponible ({e}) — explorer no podrá consultar"
);
None
}
@@ -322,14 +322,14 @@ fn cmd_daemon(args: &[String]) -> Cmd {
) {
Ok(w) => {
eprintln!(
"akasha daemon: watcher activo en {} (debounce 150ms, re-publish on) — Ctrl-C para terminar.",
"chasqui daemon: watcher activo en {} (debounce 150ms, re-publish on) — Ctrl-C para terminar.",
dir.display()
);
Some(w)
}
Err(e) => {
eprintln!(
"akasha daemon: watcher deshabilitado ({e}) — Ctrl-C para terminar."
"chasqui daemon: watcher deshabilitado ({e}) — Ctrl-C para terminar."
);
None
}
@@ -385,7 +385,7 @@ fn spawn_fs_watcher(
// Dispatcher: notify → filtro → canal de paths.
let dispatch_dir = dir.clone();
std::thread::Builder::new()
.name("akasha-watcher-dispatch".into())
.name("chasqui-watcher-dispatch".into())
.spawn(move || {
for res in notify_rx {
let event = match res {
@@ -416,7 +416,7 @@ fn spawn_fs_watcher(
// Coordinator: debounce + batch dispatch.
let coord_dir = dir;
std::thread::Builder::new()
.name("akasha-watcher-coord".into())
.name("chasqui-watcher-coord".into())
.spawn(move || {
let debounce = std::time::Duration::from_millis(WATCHER_DEBOUNCE_MS);
let mut pending: std::collections::HashMap<
@@ -494,7 +494,7 @@ fn process_change_batch(
}
};
let prior_monads: Vec<akasha_card::MonadManifest> = db_lock.monads().cloned().collect();
let prior_monads: Vec<chasqui_card::MonadManifest> = db_lock.monads().cloned().collect();
let prior_ref: &db::MonadDb = &db_lock;
let monads = cluster::by_directory_hydrated(&files, min_files(), Some(prior_ref));
@@ -601,8 +601,8 @@ fn cmd_attract(args: &[String]) -> Cmd {
.and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok())
.map(|d| d.as_millis() as u64)
.unwrap_or(0);
let target = akasha_card::FileEntry {
id: akasha_card::FileId::from(akasha_card::ulid::Ulid::new()),
let target = chasqui_card::FileEntry {
id: chasqui_card::FileId::from(chasqui_card::ulid::Ulid::new()),
path: file_path.clone(),
content_hash: None,
size: metadata.len(),
@@ -630,7 +630,7 @@ fn cmd_attract(args: &[String]) -> Cmd {
// Filtramos Mónadas cuyo centroid_model NO matchee. Mezclar
// 32-d con 384-d daría scores sin sentido (diferente semántica
// y cosine no compara cross-modelo).
let mut ranked: Vec<(&akasha_card::MonadManifest, f32)> = db
let mut ranked: Vec<(&chasqui_card::MonadManifest, f32)> = db
.monads()
.filter(|m| !m.centroid.is_empty())
.filter(|m| match &m.centroid_model {
@@ -700,7 +700,7 @@ fn cmd_attract(args: &[String]) -> Cmd {
/// Devuelve `(embedding, model_id)` — el caller necesita ambos para
/// comparar contra centroides taggeados con su mismo `centroid_model`.
fn remote_embed(
file: &akasha_card::FileEntry,
file: &chasqui_card::FileEntry,
) -> Result<(Vec<f32>, String), Box<dyn std::error::Error>> {
if let Ok(explicit) = std::env::var("NOUSER_NOUS_SOCKET") {
let sock = std::path::PathBuf::from(explicit);
@@ -708,9 +708,9 @@ fn remote_embed(
}
let consumer = brahman_sidecar::build_consumer_card(
"akasha.attract-cli",
akasha_nous::FLOW_EMBED_RESULT,
akasha_nous::FLOW_TYPE_NAME,
"chasqui.attract-cli",
chasqui_nous::FLOW_EMBED_RESULT,
chasqui_nous::FLOW_TYPE_NAME,
);
let producer_sock = brahman_sidecar::await_provider_blocking(
consumer,
@@ -719,12 +719,12 @@ fn remote_embed(
embed_via(&producer_sock, file)
}
/// RPC blocking contra un socket akasha-nous concreto. Devuelve
/// RPC blocking contra un socket chasqui-nous concreto. Devuelve
/// `(embedding, model_id)` — el `model_id` viaja en la response y
/// permite al caller saber qué centroides son comparables.
fn embed_via(
sock_path: &std::path::Path,
file: &akasha_card::FileEntry,
file: &chasqui_card::FileEntry,
) -> Result<(Vec<f32>, String), Box<dyn std::error::Error>> {
use std::io::{BufRead, BufReader, Write};
use std::os::unix::net::UnixStream;
@@ -734,9 +734,9 @@ fn embed_via(
}
let mut stream = UnixStream::connect(sock_path)?;
let req = akasha_nous::EmbedRequest {
kind: akasha_nous::RequestKind::EmbedFile,
payload: serde_json::to_value(akasha_nous::EmbedFilePayload {
let req = chasqui_nous::EmbedRequest {
kind: chasqui_nous::RequestKind::EmbedFile,
payload: serde_json::to_value(chasqui_nous::EmbedFilePayload {
path: file.path.display().to_string(),
extension: file.extension.clone(),
size: file.size,
@@ -752,14 +752,14 @@ fn embed_via(
let mut response = String::new();
reader.read_line(&mut response)?;
if response.is_empty() {
return Err("akasha-nous cerró sin respuesta".into());
return Err("chasqui-nous cerró sin respuesta".into());
}
if let Ok(resp) = serde_json::from_str::<akasha_nous::EmbedResponse>(&response) {
if let Ok(resp) = serde_json::from_str::<chasqui_nous::EmbedResponse>(&response) {
return Ok((resp.embedding, resp.model));
}
let err: akasha_nous::ErrorResponse = serde_json::from_str(&response)?;
Err(format!("akasha-nous: {}", err.error).into())
let err: chasqui_nous::ErrorResponse = serde_json::from_str(&response)?;
Err(format!("chasqui-nous: {}", err.error).into())
}
/// Card del propio engine (kind=Ente). Es el "ser" que produce y
@@ -771,7 +771,7 @@ fn embed_via(
/// brahman-admin.
fn build_engine_card(service_socket: std::path::PathBuf) -> brahman_card::Card {
use brahman_card::{Card, CardKind, Flow, Flows, Lifecycle, Payload, Priority, Supervision, TypeRef};
use akasha_card::query::{FLOW_MONAD_LIST, FLOW_TYPE_NAME};
use chasqui_card::query::{FLOW_MONAD_LIST, FLOW_TYPE_NAME};
Card {
payload: Payload::Virtual,
@@ -15,7 +15,7 @@
use std::collections::BTreeMap;
use std::path::PathBuf;
use akasha_card::{FileEntry, Lens, MonadManifest};
use chasqui_card::{FileEntry, Lens, MonadManifest};
use crate::embed;
@@ -236,7 +236,7 @@ fn shannon_entropy_normalized(files: &[&FileEntry]) -> f32 {
#[cfg(test)]
mod tests {
use super::*;
use akasha_card::FileId;
use chasqui_card::FileId;
use std::path::PathBuf;
use ulid::Ulid;
@@ -12,7 +12,7 @@
use std::collections::BTreeMap;
use std::path::Path;
use akasha_card::{FileEntry, FileId, MonadId, MonadManifest};
use chasqui_card::{FileEntry, FileId, MonadId, MonadManifest};
use thiserror::Error;
#[derive(Debug, Error)]
@@ -188,7 +188,7 @@ fn decode_key(k: &[u8]) -> Result<ulid::Ulid, MonadDbError> {
#[cfg(test)]
mod tests {
use super::*;
use akasha_card::Lens;
use chasqui_card::Lens;
use ulid::Ulid;
fn mk_file(path: &str) -> FileEntry {
@@ -27,7 +27,7 @@
//! - Dirs distintos + misma ext → similitud ~ 0.5.
//! - Sin parecido → similitud < 0.3.
use akasha_card::{FileEntry, MonadId, MonadManifest};
use chasqui_card::{FileEntry, MonadId, MonadManifest};
/// Dimensión del vector embedding.
pub const EMBED_DIM: usize = 32;
@@ -37,7 +37,7 @@ pub const EMBED_DIM: usize = 32;
/// este string contra el suyo antes de hacer cosine similarity.
/// Mezclar centroides de distinto MODEL_ID corrompe scores
/// silenciosamente (dimensiones distintas, semántica distinta).
pub const MODEL_ID: &str = "akasha-pseudo-32d";
pub const MODEL_ID: &str = "chasqui-pseudo-32d";
/// Computa el embedding de un archivo. Determinístico: misma input
/// → mismo vector. El vector queda L2-normalizado.
@@ -185,7 +185,7 @@ pub const DEFAULT_ATTRACTION_THRESHOLD: f32 = 0.7;
#[cfg(test)]
mod tests {
use super::*;
use akasha_card::FileId;
use chasqui_card::FileId;
use std::path::PathBuf;
use ulid::Ulid;
@@ -1,13 +1,13 @@
//! Listener Unix-socket que sirve [`akasha_card::query::QueryRequest`].
//! Listener Unix-socket que sirve [`chasqui_card::query::QueryRequest`].
//!
//! El daemon `akasha` lo monta para que cualquier consumer (UI, CLI,
//! El daemon `chasqui` lo monta para que cualquier consumer (UI, CLI,
//! otro módulo) pueda preguntarle por sus Mónadas sin pasar por
//! brahman-admin. El path del socket viaja en el `Card.service_socket`
//! del engine; el broker brahman lo enseña vía MatchEvent::Available
//! cuando un consumer declara `flow.input = monad-list:json`.
//!
//! Wire: line-delimited JSON, single-shot por conexión. Mismo patrón
//! que `akasha-nous` (mock/real ↔ akasha-core), reutilizado.
//! que `chasqui-nous` (mock/real ↔ chasqui-core), reutilizado.
//!
//! Threading: un thread dedicado, blocking I/O. No vale la pena traer
//! tokio acá — la frecuencia esperada es muy baja (UI poll cada 2s)
@@ -18,10 +18,10 @@ use std::os::unix::net::{UnixListener, UnixStream};
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use akasha_card::query::{
use chasqui_card::query::{
EngineInfo, ErrorResponse, ListMonadsResponse, MonadView, QueryRequest,
};
use akasha_card::ulid::Ulid;
use chasqui_card::ulid::Ulid;
use crate::db::MonadDb;
@@ -54,7 +54,7 @@ pub fn spawn_listener(
let listener = UnixListener::bind(&config.socket_path)?;
let handle = std::thread::Builder::new()
.name("akasha-engine-listener".into())
.name("chasqui-engine-listener".into())
.spawn(move || {
for conn in listener.incoming() {
match conn {
@@ -126,17 +126,17 @@ fn encode_error(msg: String) -> String {
serde_json::to_string(&err).unwrap_or_else(|_| "{\"error\":\"encode\"}".into())
}
// El cliente blocking vive en `akasha_card::query::client` — junto a
// El cliente blocking vive en `chasqui_card::query::client` — junto a
// los wire types — para que un consumer pueda hablar con el daemon
// importando sólo `akasha-card`, sin arrastrar el peso de
// `akasha-core` (scanner / db / sled / notify / walkdir / blake3).
// importando sólo `chasqui-card`, sin arrastrar el peso de
// `chasqui-core` (scanner / db / sled / notify / walkdir / blake3).
#[cfg(test)]
mod tests {
use super::*;
use crate::db::MonadDb;
use akasha_card::query::client as query_client;
use akasha_card::MonadManifest;
use chasqui_card::query::client as query_client;
use chasqui_card::MonadManifest;
use std::time::Duration;
fn fresh_socket_path(name: &str) -> PathBuf {
@@ -147,7 +147,7 @@ mod tests {
#[test]
fn list_monads_roundtrip_empty() {
let socket = fresh_socket_path("akasha-engine-test");
let socket = fresh_socket_path("chasqui-engine-test");
let db = Arc::new(Mutex::new(MonadDb::new()));
let engine_id = Ulid::new();
let _h = spawn_listener(
@@ -178,7 +178,7 @@ mod tests {
#[test]
fn list_monads_returns_views() {
let socket = fresh_socket_path("akasha-engine-test-views");
let socket = fresh_socket_path("chasqui-engine-test-views");
let db = Arc::new(Mutex::new(MonadDb::new()));
let m1 = MonadManifest::new("alpha");
let m2 = MonadManifest::new("beta");
@@ -209,7 +209,7 @@ mod tests {
#[test]
fn invalid_request_returns_error_response() {
let socket = fresh_socket_path("akasha-engine-test-bad");
let socket = fresh_socket_path("chasqui-engine-test-bad");
let db = Arc::new(Mutex::new(MonadDb::new()));
let _h = spawn_listener(
ListenerConfig {
@@ -1,4 +1,4 @@
//! `akasha-core` — el explorador de Mónadas.
//! `chasqui-core` — el explorador de Mónadas.
//!
//! Implementa la pipeline determinista descrita en el diseño de Kairos:
//!
@@ -31,4 +31,4 @@ pub mod embed;
pub mod engine_socket;
pub mod scanner;
pub use akasha_card::*;
pub use chasqui_card::*;
@@ -6,7 +6,7 @@
use std::path::{Path, PathBuf};
use std::time::UNIX_EPOCH;
use akasha_card::{FileEntry, FileId};
use chasqui_card::{FileEntry, FileId};
use thiserror::Error;
use ulid::Ulid;
use walkdir::WalkDir;
@@ -1,5 +1,5 @@
[package]
name = "akasha-nous-mock"
name = "chasqui-nous-mock"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
@@ -11,9 +11,9 @@ description = "Nouser — Nous mock determinístico: implementa el contrato nous
[dependencies]
brahman-card = { path = "../../../protocol/brahman-card" }
brahman-sidecar = { path = "../../../protocol/brahman-sidecar" }
akasha-card = { path = "../card" }
akasha-core = { path = "../core" }
akasha-nous = { path = "../nous" }
chasqui-card = { path = "../card" }
chasqui-core = { path = "../core" }
chasqui-nous = { path = "../nous" }
serde_json = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
@@ -21,5 +21,5 @@ tracing-subscriber = { workspace = true }
ulid = { workspace = true }
[[bin]]
name = "akasha-nous-mock"
name = "chasqui-nous-mock"
path = "src/main.rs"
@@ -1,7 +1,7 @@
//! `akasha-nous-mock` — proveedor de embeddings determinista (sin LLM).
//! `chasqui-nous-mock` — proveedor de embeddings determinista (sin LLM).
//!
//! Implementa el contrato `akasha-nous` usando los pseudo-embeddings
//! de Phase C (`akasha_core::embed`). Sirve como:
//! Implementa el contrato `chasqui-nous` usando los pseudo-embeddings
//! de Phase C (`chasqui_core::embed`). Sirve como:
//!
//! - **Mock para tests**: en `BRAHMAN_BROKER_CONTEXT=test`, el
//! `priority_offset` per-contexto declarado en su Card lo prioriza
@@ -16,7 +16,7 @@
//! `priority_contexts.test = { priority_offset: +1 }` lo prioriza
//! cuando el broker corre bajo contexto test.
//! 2. Bind del Unix socket en `$NOUSER_NOUS_SOCKET` (default
//! `$XDG_RUNTIME_DIR/akasha-nous.sock`).
//! `$XDG_RUNTIME_DIR/chasqui-nous.sock`).
//! 3. Loop: accept → read line JSON → process → write line JSON → close.
//! 4. Cada request se loggea (info) — útil para verificar que el
//! consumidor está usando este proveedor.
@@ -29,9 +29,9 @@ use brahman_card::{
ulid::Ulid, Card, CardKind, ContextBias, Flow, Flows, Lifecycle, Payload, Priority,
Supervision, TypeRef,
};
use akasha_card::FileEntry;
use akasha_core::embed;
use akasha_nous::{
use chasqui_card::FileEntry;
use chasqui_core::embed;
use chasqui_nous::{
transport, EmbedFilePayload, EmbedRequest, EmbedResponse, EmbedTextPayload, ErrorResponse,
PingResponse, RequestKind, FLOW_EMBED_REQUEST, FLOW_EMBED_RESULT, FLOW_TYPE_NAME,
};
@@ -39,11 +39,11 @@ use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::{UnixListener, UnixStream};
use tracing::{info, warn};
/// El mock implementa el MISMO algoritmo que `akasha_core::embed`,
/// El mock implementa el MISMO algoritmo que `chasqui_core::embed`,
/// así que reportamos el mismo `MODEL_ID` que él. De otro modo el
/// consumer filtraría las Mónadas como "modelo distinto" y los
/// scores quedarían vacíos.
const MODEL_ID: &str = akasha_core::embed::MODEL_ID;
const MODEL_ID: &str = chasqui_core::embed::MODEL_ID;
#[tokio::main(flavor = "current_thread")]
async fn main() -> std::io::Result<()> {
@@ -60,7 +60,7 @@ async fn main() -> std::io::Result<()> {
std::fs::create_dir_all(parent)?;
}
let listener = UnixListener::bind(&sock_path)?;
info!(socket = %sock_path.display(), "akasha-nous-mock escuchando");
info!(socket = %sock_path.display(), "chasqui-nous-mock escuchando");
// 2. Sidecar al brahman-init con la Card que declara el socket.
let card = build_card(sock_path.clone());
@@ -107,7 +107,7 @@ fn build_card(service_socket: std::path::PathBuf) -> Card {
Card {
schema_version: brahman_card::CARD_SCHEMA_VERSION,
id: Ulid::new(),
label: "akasha.nous_mock".into(),
label: "chasqui.nous_mock".into(),
payload: Payload::Virtual,
supervision: Supervision::Delegate,
lifecycle: Lifecycle::Daemon,
@@ -178,7 +178,7 @@ fn handle_embed_file(payload: serde_json::Value, started: Instant) -> Result<Str
info!(path = %p.path, "embed_file");
let file = FileEntry {
id: akasha_card::FileId::from(Ulid::new()),
id: chasqui_card::FileId::from(Ulid::new()),
path: PathBuf::from(p.path),
content_hash: None,
size: p.size,
@@ -204,7 +204,7 @@ fn handle_embed_text(payload: serde_json::Value, started: Instant) -> Result<Str
// resto del vector con ceros. No es semánticamente útil, pero respeta
// la forma para que el cliente no se rompa.
let synthetic = FileEntry {
id: akasha_card::FileId::from(Ulid::new()),
id: chasqui_card::FileId::from(Ulid::new()),
path: PathBuf::from(format!("synthetic://{}", p.text)),
content_hash: None,
size: p.text.len() as u64,
@@ -1,5 +1,5 @@
[package]
name = "akasha-nous-real"
name = "chasqui-nous-real"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
@@ -20,8 +20,8 @@ embeddings = ["dep:fastembed"]
[dependencies]
brahman-card = { path = "../../../protocol/brahman-card" }
brahman-sidecar = { path = "../../../protocol/brahman-sidecar" }
ente-cas = { path = "../../../runtime/ente-cas" }
akasha-nous = { path = "../nous" }
arje-cas = { path = "../../../runtime/arje-cas" }
chasqui-nous = { path = "../nous" }
serde_json = { workspace = true }
sled = { workspace = true }
tokio = { workspace = true }
@@ -36,5 +36,5 @@ fastembed = { version = "4", optional = true }
tempfile = { workspace = true }
[[bin]]
name = "akasha-nous-real"
name = "chasqui-nous-real"
path = "src/main.rs"
@@ -2,7 +2,7 @@
//!
//! Razón de existir: el modelo real (`fastembed-allMiniLML6V2`) es
//! caro (1-50 ms por archivo según tamaño y CPU). Cada vez que el
//! daemon de akasha re-publica una Mónada o el watcher dispara un
//! daemon de chasqui re-publica una Mónada o el watcher dispara un
//! re-cluster por cambio de FS, todos los archivos pasan otra vez
//! por embed. Para árboles de 1000 archivos, eso son segundos
//! desperdiciados re-embedidando contenido que no cambió.
@@ -17,7 +17,7 @@
//! little-endian (4 bytes por f32). Compacto, sin overhead de
//! bincode/postcard para datos numéricos puros.
//! - **Backend**: sled, tree único `embed_cache_v1`. Path:
//! `$XDG_CACHE_HOME/brahman/akasha-nous-real-embed-cache.sled`.
//! `$XDG_CACHE_HOME/brahman/chasqui-nous-real-embed-cache.sled`.
//!
//! ## Versionado
//!
@@ -102,7 +102,7 @@ fn default_path() -> PathBuf {
.map(|h| PathBuf::from(h).join(".cache"))
})
.unwrap_or_else(std::env::temp_dir);
base.join("brahman").join("akasha-nous-real-embed-cache.sled")
base.join("brahman").join("chasqui-nous-real-embed-cache.sled")
}
fn build_key(file_sha: &[u8; 32], model_id: &str) -> Vec<u8> {
@@ -139,7 +139,7 @@ mod tests {
use super::*;
fn sha(s: &[u8]) -> [u8; 32] {
ente_cas::sha256_of(s)
arje_cas::sha256_of(s)
}
#[test]
@@ -20,7 +20,7 @@ use std::sync::Arc;
use std::time::Instant;
use fastembed::{EmbeddingModel, InitOptions, TextEmbedding};
use akasha_nous::{
use chasqui_nous::{
EmbedFilePayload, EmbedRequest, EmbedResponse, EmbedTextPayload, ErrorResponse, PingResponse,
RequestKind,
};
@@ -135,13 +135,13 @@ fn handle_file(
// bajo la semántica del proveedor (el modelo nunca vio los bytes
// adicionales). Si la cabeza cambia, el hash cambia y caemos a
// re-embed naturalmente.
let file_sha = ente_cas::sha256_of(&buf);
let file_sha = arje_cas::sha256_of(&buf);
if let Some(cache) = cache {
if let Some(cached) = cache.get(&file_sha, model_id) {
info!(
path = %p.path,
sha = %ente_cas::hex(&file_sha),
sha = %arje_cas::hex(&file_sha),
bytes = n,
"embed_file: cache HIT"
);
@@ -156,7 +156,7 @@ fn handle_file(
info!(
path = %p.path,
sha = %ente_cas::hex(&file_sha),
sha = %arje_cas::hex(&file_sha),
bytes = n,
"embed_file: cache MISS — invocando modelo"
);
@@ -166,9 +166,9 @@ fn handle_file(
// el cache (sled lo es) pero deja un registro consultable por
// herramientas como `ente-cas gc` y permite que otros consumers
// resuelvan los bytes por hash.
if let Err(e) = ente_cas::store(&buf) {
if let Err(e) = arje_cas::store(&buf) {
// No-fatal: si CAS no escribe, cacheamos el embedding igual.
warn!(error = %e, "ente_cas::store falló (no-fatal)");
warn!(error = %e, "arje_cas::store falló (no-fatal)");
}
let text = String::from_utf8_lossy(&buf).to_string();
@@ -1,21 +1,21 @@
//! `akasha-nous-real` — proveedor Nous con LLM real (gated por feature).
//! `chasqui-nous-real` — proveedor Nous con LLM real (gated por feature).
//!
//! ## Build modes
//!
//! - `cargo build -p akasha-nous-real`
//! - `cargo build -p chasqui-nous-real`
//! Compila como **stub**: bin que arranca, sidecarea al brahman-init
//! pero rechaza toda request con un error explicando que falta la
//! feature. Útil para que `cargo build --workspace` no requiera ML
//! deps.
//!
//! - `cargo build -p akasha-nous-real --features embeddings`
//! - `cargo build -p chasqui-nous-real --features embeddings`
//! Compila con `fastembed` + ONNX Runtime descargado por Cargo.
//! Modelo default: `all-MiniLM-L6-v2` (384-d, ~80 MB descargado al
//! primer run y cacheado en `~/.cache/fastembed`).
//!
//! ## Diseño
//!
//! Mismo contrato wire que `akasha-nous-mock` (`akasha-nous` crate). La
//! Mismo contrato wire que `chasqui-nous-mock` (`chasqui-nous` crate). La
//! diferencia operativa: real produce 384-d con semantic content
//! (text-embedding del modelo); mock produce 32-d con metadata-hashing.
//! No son intercambiables a media-deployment — los centroides de
@@ -36,7 +36,7 @@ use brahman_card::{
ulid::Ulid, Card, CardKind, ContextBias, Flow, Flows, Lifecycle, Payload, Priority,
Supervision, TypeRef,
};
use akasha_nous::{transport, FLOW_EMBED_REQUEST, FLOW_EMBED_RESULT, FLOW_TYPE_NAME};
use chasqui_nous::{transport, FLOW_EMBED_REQUEST, FLOW_EMBED_RESULT, FLOW_TYPE_NAME};
use tokio::net::UnixListener;
use tracing::info;
@@ -63,11 +63,11 @@ async fn main() -> std::io::Result<()> {
#[cfg(not(feature = "embeddings"))]
info!(
"akasha-nous-real corriendo en modo STUB (compilá con \
"chasqui-nous-real corriendo en modo STUB (compilá con \
--features embeddings para activar el modelo)"
);
// 1. Resolver socket del data-plane (default `akasha-nous-real.sock`,
// 1. Resolver socket del data-plane (default `chasqui-nous-real.sock`,
// distinto del mock para coexistir).
let sock_path = transport::provider_socket_path("real");
if sock_path.exists() {
@@ -77,7 +77,7 @@ async fn main() -> std::io::Result<()> {
std::fs::create_dir_all(parent)?;
}
let listener = UnixListener::bind(&sock_path)?;
info!(socket = %sock_path.display(), "akasha-nous-real escuchando");
info!(socket = %sock_path.display(), "chasqui-nous-real escuchando");
// 2. Sidecar al brahman-init con Card declarando el socket.
let card = build_card(sock_path.clone());
@@ -144,7 +144,7 @@ fn init_tracing() {
}
/// Card que real-nous anuncia. Idéntica al mock excepto por:
/// - label distinto (`akasha.nous_real`) para que coexistan en el broker.
/// - label distinto (`chasqui.nous_real`) para que coexistan en el broker.
/// - `priority_contexts.prod = +1` (gana en contexto prod).
/// - `service_socket` propio para que clientes lo descubran directo.
fn build_card(service_socket: std::path::PathBuf) -> Card {
@@ -160,7 +160,7 @@ fn build_card(service_socket: std::path::PathBuf) -> Card {
Card {
schema_version: brahman_card::CARD_SCHEMA_VERSION,
id: Ulid::new(),
label: "akasha.nous_real".into(),
label: "chasqui.nous_real".into(),
payload: Payload::Virtual,
supervision: Supervision::Delegate,
lifecycle: Lifecycle::Daemon,
@@ -1,7 +1,7 @@
//! Modo stub: arranca el bin pero rechaza las requests con un error
//! que explica que falta la feature `embeddings`.
use akasha_nous::{EmbedRequest, ErrorResponse};
use chasqui_nous::{EmbedRequest, ErrorResponse};
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::UnixStream;
use tracing::warn;
@@ -21,8 +21,8 @@ pub async fn handle_conn(stream: UnixStream) -> std::io::Result<()> {
let resp = ErrorResponse {
error: format!(
"akasha-nous-real compilado sin la feature `embeddings`. \
Rebuild con: cargo build -p akasha-nous-real --features embeddings"
"chasqui-nous-real compilado sin la feature `embeddings`. \
Rebuild con: cargo build -p chasqui-nous-real --features embeddings"
),
};
let mut stream = reader.into_inner();
@@ -1,5 +1,5 @@
[package]
name = "akasha-nous"
name = "chasqui-nous"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
@@ -1,6 +1,6 @@
//! `akasha-nous` — el contrato del proveedor de embeddings.
//! `chasqui-nous` — el contrato del proveedor de embeddings.
//!
//! Define el wire-format compartido entre `akasha-core` (consumidor) y
//! Define el wire-format compartido entre `chasqui-core` (consumidor) y
//! cualquier implementación de Nous (mock determinista o LLM real). El
//! protocolo es **line-delimited JSON** sobre Unix socket: cada conexión
//! envía una request, recibe una response, y cierra. Single-shot por
@@ -21,8 +21,8 @@
//!
//! ## Por qué un crate aparte
//!
//! El consumidor (akasha-core) y el proveedor (akasha-nous-mock,
//! akasha-nous-real) deben acordar en types EXACTOS. Tener el contrato
//! El consumidor (chasqui-core) y el proveedor (chasqui-nous-mock,
//! chasqui-nous-real) deben acordar en types EXACTOS. Tener el contrato
//! en su crate evita que cada lado declare structs paralelos que se
//! desincronizan. Si bumpeás el wire, bumpeás aquí.
//!
@@ -32,7 +32,7 @@
//! el mismo `flow.output: { name: "embed-result", type: ... }` y
//! `flow.input: "embed-request"`. El broker brahman los matchea contra
//! los consumidores; el `priority_offset` per-contexto del Card hace que
//! mock-nous gane en `test` y real-nous en `prod`. akasha-core sólo
//! mock-nous gane en `test` y real-nous en `prod`. chasqui-core sólo
//! consume el flow, sin saber cuál implementación corre.
#![forbid(unsafe_code)]
@@ -118,7 +118,7 @@ pub mod transport {
pub const SOCKET_ENV: &str = "NOUSER_NOUS_SOCKET";
/// Nombre genérico del socket cuando hay un solo proveedor.
pub const SOCKET_NAME: &str = "akasha-nous.sock";
pub const SOCKET_NAME: &str = "chasqui-nous.sock";
/// Ruta canónica al socket cuando un único proveedor está activo
/// (consumidores que no quieren elegir).
@@ -136,7 +136,7 @@ pub mod transport {
if let Ok(p) = std::env::var(SOCKET_ENV) {
return PathBuf::from(p);
}
runtime_base().join(format!("akasha-nous-{}.sock", provider))
runtime_base().join(format!("chasqui-nous-{}.sock", provider))
}
fn runtime_base() -> PathBuf {
+71
View File
@@ -0,0 +1,71 @@
# modules/fana/ — Writer DAG editor (absorbe pluma)
**Propósito.** Editor de escritura multidimensional: el documento es un
DAG de átomos narrativos con ramas (timelines), tracking de coherencia,
e indexación semántica. Absorbe el linaje markdown de `pluma`. Prioridad
alta entre las apps.
## Estado
- **Existente (de pluma)**: `fana-md` (parser markdown, ex `pluma-md`),
`fana-md-reader-web` (lector DOM, ex `pluma-reader-web`, aún dep de
`gioser-web`).
- **Planeado**: el resto de sub-crates (writer DAG editor completo).
## Crates (objetivo)
| crate | tipo | rol |
| ---------------------- | ---- | ---------------------------------------------------- |
| `fana-core` | lib | `NarrativeAtom` + `NarrativeGraph` + `CoherenceState`|
| `fana-md` | lib | Parser markdown (ex pluma-md) |
| `fana-graph` | lib | DAG ops + `propagate_mutation` topológico |
| `fana-semantic` | lib | Cliente `verbo` + scoring de intensidad adjetiva |
| `fana-store` | lib | Persistencia sled/RocksDB + bincode/rkyv zero-copy |
| `fana-llm` | lib | Cliente HTTP a LLMs remotos (evaluación + merge) |
| `fana-render-plan` | lib | DrawCommands agnósticos (editor + sidepane + ghost) |
| `fana-editor-gpui` | lib | WorkspaceEditor View + OscilloscopeSidepane + Ghost |
| `fana-md-reader-web` | lib | Lector markdown DOM (ex pluma-reader-web) |
| `fana-editor-web` | lib | (futuro) editor WASM |
## Modelo de datos
```rust
enum CoherenceState { Valid, InConflict { origin, reason }, PendingEvaluation }
struct NarrativeAtom {
id: Uuid,
content_hash: [u8; 32], // SHA-256 estricto
content: Arc<String>, // texto compartido (zero-alloc al ramificar)
semantic_vectors: HashMap<String, f32>, // concepto → intensidad
dependencies: Vec<Uuid>, // nodos prerrequisito
branch_id: String,
coherence: CoherenceState,
}
struct NarrativeGraph {
nodes: HashMap<Uuid, NarrativeAtom>,
adjacency_list: HashMap<Uuid, Vec<Uuid>>, // padre → hijos dependientes
}
```
## Dependencias
- `fana-semantic``verbo` (embeddings, instancia modelo ligero ~384d).
- `fana-md` puro (sin deps de host).
- `fana-md-reader-web` + `fana-editor-web``wasm-bindgen`, `web-sys`.
- `fana-editor-gpui``gpui`, `nahual`.
- `gioser-web` sigue consumiendo `fana-md-reader-web`.
## Invariantes
- Toda mutación de texto valida contra el hash binario del contenido.
- Branches comparten texto vía `Arc<String>` — clonar una rama es O(1).
- `propagate_mutation` marca `PendingEvaluation` en cascada topológica
cuando un átomo origen cambia (shock-wave lógica).
- Separabilidad UI estricta: `fana-core/md/graph/semantic/store/llm/
render-plan` agnósticos; `fana-editor-{gpui,web}` intercambiables.
## Apps
- `apps/fana` — binario GPUI (prioridad alta).
- `apps/fana-web` — (futuro) cdylib WASM.

Some files were not shown because too many files have changed in this diff Show More