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
+9 -9
View File
@@ -8,18 +8,18 @@ rule engine + audit log, y un ente de smoke test.
| crate | tipo | rol |
| ------------- | ---- | ----------------------------------------------------------- |
| `ente-bus` | lib | Unix SOCK_STREAM + postcard framing. Announce/Invoke/List |
| `ente-cas` | lib | Content-addressed storage SHA-256: blobs Wasm + audit log |
| `ente-wasm` | lib | Encarna `Payload::Wasm` vía `wasmi` en thread dedicado |
| `ente-brain` | lib | Rule engine + observer estadístico + audit chain con CAS |
| `ente-echo` | bin | Ente prueba — provee `Capability::Endpoint(echo)` |
| `arje-bus` | lib | Unix SOCK_STREAM + postcard framing. Announce/Invoke/List |
| `arje-cas` | lib | Content-addressed storage SHA-256: blobs Wasm + audit log |
| `arje-wasm` | lib | Encarna `Payload::Wasm` vía `wasmi` en thread dedicado |
| `arje-brain` | lib | Rule engine + observer estadístico + audit chain con CAS |
| `arje-echo` | bin | Ente prueba — provee `Capability::Endpoint(echo)` |
## Dependencias
- `ente-bus``tokio` + `postcard`. Consumido por `init/ente-zero`.
- `ente-cas``sha2` + `sled`. Consumido por `ente-brain` (audit log)
y `ente-wasm` (blobs).
- `ente-brain``ente-bus`, `ente-cas`. Consumido por Init para
- `arje-bus``tokio` + `postcard`. Consumido por `init/arje-zero`.
- `arje-cas``sha2` + `sled`. Consumido por `arje-brain` (audit log)
y `arje-wasm` (blobs).
- `arje-brain``arje-bus`, `arje-cas`. Consumido por Init para
observabilidad estadística + reglas declarativas.
## Invariantes
@@ -1,13 +1,13 @@
[package]
name = "ente-brain"
name = "arje-brain"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-cas = { path = "../ente-cas" }
arje-card = { path = "../../protocol/arje-card" }
arje-cas = { path = "../arje-cas" }
serde = { workspace = true }
serde_json = { workspace = true }
ulid = { workspace = true }
@@ -9,7 +9,7 @@
//!
//! Path del socket: $ENTE_BRAIN_SOCK o $XDG_RUNTIME_DIR/ente-brain.sock
use ente_brain::introspect::{call, IntrospectRequest, IntrospectResponse};
use arje_brain::introspect::{call, IntrospectRequest, IntrospectResponse};
use std::path::{Path, PathBuf};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::UnixStream;
@@ -164,10 +164,10 @@ fn print_response(r: &IntrospectResponse) {
println!("{} cristales pattern detectados:", ps.len());
for p in ps {
match p {
ente_brain::crystallize::PatternCrystal::Burst { kind, count, frequency_per_sec } => {
arje_brain::crystallize::PatternCrystal::Burst { kind, count, frequency_per_sec } => {
println!(" burst: {kind:?} count={count} freq={frequency_per_sec:.2} Hz");
}
ente_brain::crystallize::PatternCrystal::Silence { kind, last_count, since_secs } => {
arje_brain::crystallize::PatternCrystal::Silence { kind, last_count, since_secs } => {
println!(" silence: {kind:?} last_count={last_count} ausente={since_secs:.1}s");
}
}
@@ -125,7 +125,7 @@ impl AuditLog {
/// snapshots externos — el log en memoria sigue intacto.
pub fn persist_to_cas(entry: &AuditEntry) -> anyhow::Result<[u8; 32]> {
let bytes = serde_json::to_vec(entry)?;
let sha = ente_cas::store(&bytes)?;
let sha = arje_cas::store(&bytes)?;
Ok(sha)
}
@@ -142,7 +142,7 @@ impl AuditLog {
for entry in &self.entries {
if entry.seq < self.flushed_count { continue; }
let bytes = canonical_bytes(entry);
let sha = ente_cas::store(&bytes)?;
let sha = arje_cas::store(&bytes)?;
debug_assert_eq!(sha, entry.sha,
"CAS sha != entry.sha — fórmula canónica rota");
last_sha = Some(sha);
@@ -230,7 +230,7 @@ pub fn verify_chain_from_cas(start_sha: [u8; 32]) -> VerificationReport {
let mut last_seen: Option<AuditEntry> = None;
while let Some(sha) = current {
let path = ente_cas::cas_root().join(ente_cas::hex(&sha));
let path = arje_cas::cas_root().join(arje_cas::hex(&sha));
let bytes = match std::fs::read(&path) {
Ok(b) => b,
Err(e) => return VerificationReport {
@@ -241,14 +241,14 @@ pub fn verify_chain_from_cas(start_sha: [u8; 32]) -> VerificationReport {
},
};
// Verificación 1: el blob hashea a la SHA esperada (CAS contract).
let actual = ente_cas::sha256_of(&bytes);
let actual = arje_cas::sha256_of(&bytes);
if actual != sha {
return VerificationReport {
verified,
broken_at_seq: last_seen.as_ref().map(|e| e.seq),
error: Some(format!(
"CAS tamper en {}: expected {} got {}",
path.display(), ente_cas::hex(&sha), ente_cas::hex(&actual)
path.display(), arje_cas::hex(&sha), arje_cas::hex(&actual)
)),
genesis_sha: None,
};
@@ -288,7 +288,7 @@ pub fn reachable_from_head(start_sha: [u8; 32]) -> std::collections::HashSet<[u8
let mut current = Some(start_sha);
while let Some(sha) = current {
if !set.insert(sha) { break; } // ciclo (no debería pasar) — corta
let path = ente_cas::cas_root().join(ente_cas::hex(&sha));
let path = arje_cas::cas_root().join(arje_cas::hex(&sha));
let bytes = match std::fs::read(&path) { Ok(b) => b, Err(_) => break };
let entry: AuditEntry = match serde_json::from_slice(&bytes) {
Ok(e) => e, Err(_) => break,
@@ -305,7 +305,7 @@ pub fn collect_chain_from_cas(start_sha: [u8; 32]) -> anyhow::Result<Vec<AuditEn
let mut entries = Vec::new();
let mut current = Some(start_sha);
while let Some(sha) = current {
let path = ente_cas::cas_root().join(ente_cas::hex(&sha));
let path = arje_cas::cas_root().join(arje_cas::hex(&sha));
let bytes = std::fs::read(&path)?;
let mut entry: AuditEntry = serde_json::from_slice(&bytes)?;
entry.sha = sha;
@@ -370,11 +370,11 @@ fn now_ms() -> u64 {
}
/// SHA256 sobre el entry en forma canónica (sha=[0;32]). Hash y CAS storage
/// ven los mismos bytes, así que `ente_cas::store(canonical)` devuelve el
/// ven los mismos bytes, así que `arje_cas::store(canonical)` devuelve el
/// mismo SHA que `compute_sha(entry)`.
fn compute_sha(entry: &AuditEntry) -> [u8; 32] {
let bytes = canonical_bytes(entry);
ente_cas::sha256_of(&bytes)
arje_cas::sha256_of(&bytes)
}
/// Forma canónica: el entry serializado JSON con `sha = [0; 32]`.
@@ -14,7 +14,7 @@ pub trait ActionSink: Send + Sync {
/// Spawn una Card decodificada. Implementación: GraphEvent::SpawnRequest.
fn spawn(&self, card_blob: &str);
/// Invoke por bus. blob crudo; el sink lo enruta vía bus_mediator.
fn invoke(&self, target_cap: ente_card::Capability, blob: Vec<u8>);
fn invoke(&self, target_cap: arje_card::Capability, blob: Vec<u8>);
/// Notifica a un Ente específico (target_id). Implementación: forward por bus.
fn notify(&self, target_id: ulid::Ulid, message: &str);
/// Inhibe un comportamiento (placeholder; semántica depende del sink).
@@ -28,7 +28,7 @@ impl ActionSink for NullSink {
fn spawn(&self, card_blob: &str) {
info!(blob_len = card_blob.len(), "NullSink::spawn (no-op)");
}
fn invoke(&self, target_cap: ente_card::Capability, blob: Vec<u8>) {
fn invoke(&self, target_cap: arje_card::Capability, blob: Vec<u8>) {
info!(?target_cap, blob_len = blob.len(), "NullSink::invoke (no-op)");
}
fn notify(&self, target_id: ulid::Ulid, message: &str) {
@@ -7,7 +7,7 @@
use crate::observer::TimedEvent;
use crate::rules::{EventKind, EventPattern, Rule, Scope};
use ente_card::Capability;
use arje_card::Capability;
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
@@ -396,7 +396,7 @@ impl IntrospectServer {
reachable.extend(crate::audit::reachable_from_head(head));
}
reachable.extend(extra_roots);
match ente_cas::gc(&reachable) {
match arje_cas::gc(&reachable) {
Ok((deleted, freed_bytes)) => IntrospectResponse::GcResult { deleted, freed_bytes },
Err(e) => IntrospectResponse::Error(format!("gc: {e}")),
}
@@ -9,7 +9,7 @@
//! adicionales aquí cuando duela escribir JSON a mano. Hoy: una sola rama.
use crate::rules::Rule;
use ente_card::EntityCard;
use arje_card::EntityCard;
use std::path::Path;
use tracing::info;
@@ -128,7 +128,7 @@ async fn format_metrics(state: &BrainState) -> String {
out.push_str("# TYPE ente_brain_audit_head_info gauge\n");
out.push_str(&format!(
"ente_brain_audit_head_info{{sha=\"{}\"}} 1\n",
ente_cas::hex(&sha)
arje_cas::hex(&sha)
));
}
@@ -5,7 +5,7 @@
//! acepta Rules construidas a mano sin pasar por validate() — ver
//! `engine::insert`.
use ente_card::Capability;
use arje_card::Capability;
use serde::{Deserialize, Serialize};
use ulid::Ulid;
@@ -1,12 +1,12 @@
[package]
name = "ente-bus"
name = "arje-bus"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
arje-card = { path = "../../protocol/arje-card" }
serde = { workspace = true }
postcard = { workspace = true }
ulid = { workspace = true }
@@ -15,7 +15,7 @@ anyhow = { workspace = true }
tracing = { workspace = true }
[dev-dependencies]
ente-echo = { path = "../ente-echo" }
arje-echo = { path = "../arje-echo" }
[[example]]
name = "busctl"
@@ -7,7 +7,7 @@
//!
//! Si `ENTE_BUS_SOCK` no está en el entorno, cae al path dev por defecto.
use ente_bus::{BusClient, BusRequest};
use arje_bus::{BusClient, BusRequest};
use std::env;
#[tokio::main(flavor = "current_thread")]
@@ -36,7 +36,7 @@ async fn main() -> anyhow::Result<()> {
"invoke-echo" => {
let msg = args.get(2).map(|s| s.as_str()).unwrap_or("hola");
BusRequest::Invoke {
cap: ente_echo::echo_capability(),
cap: arje_echo::echo_capability(),
blob: msg.as_bytes().to_vec(),
}
}
@@ -6,7 +6,7 @@
//! Identidad: cada Ente hijo recibe `ENTE_BUS_SOCK` y `ENTE_ID` en su entorno.
//! El cliente lee ambos vía `BusClient::from_env`.
use ente_card::Capability;
use arje_card::Capability;
use serde::{Deserialize, Serialize};
use std::path::Path;
use std::str::FromStr;
@@ -23,14 +23,14 @@ pub const MAX_FRAME: usize = 1 << 20; // 1 MiB — protección contra OOM
/// `Capability::Endpoint { interface: POLKIT_DECISION_IFACE, version: 1 }`
/// para arbitrar autorizaciones. Recibe blob:
/// `pid_be | uid_be | action_id_utf8` → responde 1 byte: 1=allow, 0=deny.
pub const POLKIT_DECISION_IFACE: ente_card::InterfaceId =
ente_card::InterfaceId([0xb0; 16]);
pub const POLKIT_DECISION_IFACE: arje_card::InterfaceId =
arje_card::InterfaceId([0xb0; 16]);
/// Interface UUID auto-anunciado por compat-polkit. Diferente al de
/// decisión para evitar recursión (polkit-compat invoca DECISION pero
/// no es proveedor de DECISION; se anuncia como SERVICE).
pub const POLKIT_SERVICE_IFACE: ente_card::InterfaceId =
ente_card::InterfaceId([0xa4; 16]);
pub const POLKIT_SERVICE_IFACE: arje_card::InterfaceId =
arje_card::InterfaceId([0xa4; 16]);
/// Credenciales del peer extraídas vía SO_PEERCRED al accept del bus.
/// Imposibles de falsear desde el cliente — el kernel las inyecta.
@@ -132,7 +132,7 @@ pub struct BusClient {
/// forwarda. Sync por simplicidad — un handler async se cubre con
/// `tokio::task::block_in_place` o un canal hacia un task externo.
pub trait InvokeHandler {
fn handle(&mut self, cap: ente_card::Capability, blob: Vec<u8>) -> BusResponse;
fn handle(&mut self, cap: arje_card::Capability, blob: Vec<u8>) -> BusResponse;
}
/// Conexión long-lived para Entes que proveen capacidades. A diferencia de
@@ -157,7 +157,7 @@ impl BusServer {
Ok(Self { stream, self_id })
}
pub async fn announce(&mut self, capabilities: Vec<ente_card::Capability>) -> anyhow::Result<()> {
pub async fn announce(&mut self, capabilities: Vec<arje_card::Capability>) -> anyhow::Result<()> {
let req = BusMessage {
from: Some(self.self_id),
seq: 1,
@@ -1,5 +1,5 @@
[package]
name = "ente-cas"
name = "arje-cas"
version = "0.0.1"
edition.workspace = true
license.workspace = true
@@ -1,21 +1,21 @@
[package]
name = "ente-echo"
name = "arje-echo"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[lib]
name = "ente_echo"
name = "arje_echo"
path = "src/lib.rs"
[[bin]]
name = "ente-echo"
name = "arje-echo"
path = "src/main.rs"
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
ente-bus = { path = "../ente-bus" }
arje-card = { path = "../../protocol/arje-card" }
arje-bus = { path = "../arje-bus" }
anyhow = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
@@ -1,7 +1,7 @@
//! Constantes públicas del Ente echo. Lib aparte del bin para que `busctl`
//! y otros consumidores puedan importar el InterfaceId sin enlazar el binario.
use ente_card::{Capability, InterfaceId};
use arje_card::{Capability, InterfaceId};
/// UUID estable del interface "echo". Genera nuevo por sed si forkeas.
pub const ECHO_IFACE: InterfaceId = InterfaceId([
@@ -2,9 +2,9 @@
//! responde a invokes echando el blob recibido. Vehículo para validar el
//! forwarding bus → proveedor → bus → originator.
use ente_bus::{BusResponse, BusServer, InvokeHandler};
use ente_card::Capability;
use ente_echo::{echo_capability, ECHO_IFACE, ECHO_VERSION};
use arje_bus::{BusResponse, BusServer, InvokeHandler};
use arje_card::Capability;
use arje_echo::{echo_capability, ECHO_IFACE, ECHO_VERSION};
use tracing::{info, warn};
use tracing_subscriber::EnvFilter;
@@ -31,7 +31,7 @@ impl InvokeHandler for EchoHandler {
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("ente_echo=info"));
.unwrap_or_else(|_| EnvFilter::new("arje_echo=info"));
tracing_subscriber::fmt().with_env_filter(filter).with_target(true).init();
info!("ente-echo arrancando");
@@ -1,12 +1,12 @@
[package]
name = "ente-wasm"
name = "arje-wasm"
version = "0.0.1"
edition.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
ente-card = { path = "../../protocol/ente-card" }
arje-card = { path = "../../protocol/arje-card" }
wasmi = { workspace = true }
wat = { workspace = true }
ulid = { workspace = true }
@@ -11,7 +11,7 @@
//!
//! Más adelante: `ente.bus_call`, `ente.cap_invoke`, etc.
use ente_card::EntityCard;
use arje_card::EntityCard;
use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::Arc;
use tracing::{error, info, warn};