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:
@@ -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 }
|
||||
+3
-3
@@ -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]`.
|
||||
+2
-2
@@ -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;
|
||||
+1
-1
@@ -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"
|
||||
+2
-2
@@ -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};
|
||||
Reference in New Issue
Block a user