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