Проблема
Сейчас 31 крейт workspace'а растут органически без единого протокола связи. Агенты общаются через ad-hoc serde_json::Value, нет типизированного шины сообщений, нет стандартного способа подключить новый крейт в one-shot без знания всей системы.
Цель
One-shot integration: любой новый агент/крейт подключается через единый trios-bus trait за ≤ 10 строк кода. Коммуникация между агентами — типизированная, async, через Tokio-каналы с phi-приоритетами.
Текущая карта crates (6 слоёв)
L0 Kernel — trios-core, trios-golden-float, trios-ternary, trios-physics, trios-sacred, trios-crypto
L1 Engine — trios-vm, trios-vsa, trios-hdc, trios-kg, trios-model, trios-data
L2 Agent — trios-llm, trios-agents, trios-zig-agents, zig-agents, zig-knowledge-graph, trios-ca-mask, trios-phi-schedule
L3 Learn — trios-training, trios-training-ffi, trios-train-cpu, trios-trinity-init
L4 Infra — trios-git, trios-gb, precision-router, trios-hybrid, trios-bridge, trios-tri
L5 Public — trios-sdk, trios-server, trinity-brain
Диагноз: AgentMessage в trios-agents содержит только content: String + agent_id. Нет msg_type, нет priority, нет correlation_id, нет reply_to. Агенты слепые — не знают кто им пишет и зачем.
🧩 ПЛАН ДЕКОМПОЗИЦИИ
Шаг 1 — trios-proto: единый протокол сообщений (L0)
Новый микро-крейт, 0 бизнес-логики, только типы:
// crates/trios-proto/src/lib.rs
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Envelope<T> {
pub id: Ulid, // уникальный ID сообщения
pub correlation_id: Option<Ulid>, // для request/reply
pub from: AgentId,
pub to: Routing, // Direct(AgentId) | Broadcast | Topic(String)
pub priority: PhiPriority, // φ-based: P0..P8 (Fibonacci)
pub payload: T,
pub ts: u64, // unix millis
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Routing {
Direct(AgentId),
Broadcast,
Topic(String),
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum PhiPriority {
P0 = 1, P1 = 1, P2 = 2, P3 = 3,
P4 = 5, P5 = 8, P6 = 13, P7 = 21, P8 = 34,
// Fibonacci = φ-sequence приоритеты
}
Зависимости: только serde, ulid. Никаких tokio/axum в proto.
Шаг 2 — trios-bus: шина сообщений (L1)
// crates/trios-bus/src/lib.rs
/// Trait, который реализует любой агент для one-shot интеграции
#[async_trait]
pub trait TriosAgent: Send + Sync + 'static {
fn agent_id(&self) -> AgentId;
fn subscriptions(&self) -> Vec<String>; // topics
async fn handle(&self, env: Envelope<serde_json::Value>) -> Option<Envelope<serde_json::Value>>;
}
/// Центральная шина — регистр агентов + роутинг
pub struct Bus {
agents: DashMap<AgentId, Arc<dyn TriosAgent>>,
topics: DashMap<String, Vec<AgentId>>,
tx: broadcast::Sender<Envelope<serde_json::Value>>,
}
impl Bus {
pub fn new(capacity: usize) -> Self { ... }
/// One-shot регистрация агента
pub fn register(&self, agent: Arc<dyn TriosAgent>) {
for topic in agent.subscriptions() {
self.topics.entry(topic).or_default().push(agent.agent_id());
}
self.agents.insert(agent.agent_id(), agent);
}
pub async fn publish(&self, env: Envelope<serde_json::Value>) { ... }
pub async fn request(&self, env: Envelope<serde_json::Value>)
-> Result<Envelope<serde_json::Value>> { ... }
}
Паттерн: Actor Model через Tokio broadcast + DashMap (lock-free registry). Ref: Actix Architecture, [Bastion paper 2020].
Шаг 3 — Мигрировать trios-agents на новый протокол
Текущий AgentMessage { agent_id, content, timestamp } → заменить на Envelope<AgentPayload>:
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum AgentPayload {
Task { description: String, params: serde_json::Value },
Result { task_id: Ulid, data: serde_json::Value },
Status { state: AgentState },
Ping,
Pong { latency_ms: u64 },
}
Шаг 4 — trios-orchestrator: заменяет ручной spawn (L2)
pub struct Orchestrator {
bus: Arc<Bus>,
phi_scheduler: Arc<PhiScheduler>, // из trios-phi-schedule
}
impl Orchestrator {
/// One-shot запуск всей системы агентов
pub async fn boot(config: TriosConfig) -> Result<Self> {
let bus = Arc::new(Bus::new(1024));
// Автодискавери агентов через inventory pattern
for agent in config.agents {
bus.register(agent);
}
Ok(Self { bus, phi_scheduler: ... })
}
/// Отправить задачу в систему, получить результат
pub async fn run_task(&self, task: AgentTask) -> Result<TaskResult> {
let env = Envelope::new(task.into(), PhiPriority::P5);
let result = self.bus.request(env).await?;
Ok(result.payload.try_into()?)
}
}
Шаг 5 — trios-sdk обёртка (один import)
// После рефакторинга — всё в одном:
use trios_sdk::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
let trios = Trios::boot(TriosConfig::default()).await?;
let result = trios.run("analyze physics constants").await?;
println!("{result:?}");
Ok(())
}
📐 Граф зависимостей (после рефакторинга)
trios-proto (L0, no-std compatible)
↑
trios-bus (L1, tokio)
↑
trios-agents / trios-llm / trios-phi-schedule ... (L2, implements TriosAgent)
↑
trios-orchestrator (L2, координирует)
↑
trios-sdk (L5, public API)
Правило: зависимости только вниз по слоям. L0 не знает о L1+.
📋 Чеклист задач
Фаза 1: Протокол (≈2 дня)
Фаза 2: Шина (≈3 дня)
Фаза 3: Миграция агентов (≈2 дня)
Фаза 4: Оркестратор (≈2 дня)
Фаза 5: SDK one-shot (≈1 день)
Фаза 6: CI
🔬 Научные основы
| Паттерн |
Источник |
| Actor Model + typed mailbox |
Hewitt 1973, адаптация Actix/Bastion |
| Phi-priority scheduling |
Fibonacci heap scheduling, Fredman & Tarjan 1987 |
| Hexagonal Architecture |
Alistair Cockburn 2005 — ports & adapters |
| Lock-free registry |
DashMap — Porcupine 2020 (Rust lock-free HashMap) |
| Envelope pattern |
EIP — Gregor Hohpe "Enterprise Integration Patterns" 2003 |
| One-shot integration |
Unix philosophy + Cargo workspace resolver v2 |
Workspace изменения
# Cargo.toml — добавить:
[workspace.dependencies]
ulid = "1"
dashmap = "6"
# Новые members:
"crates/trios-proto",
"crates/trios-bus",
"crates/trios-orchestrator",
Метрики успеха
cargo build --workspace за < 60s (cold)
- Новый агент =
impl TriosAgent за ≤ 10 строк
Trios::boot() поднимает всю систему за ≤ 500ms
- Нет
serde_json::Value в публичных API (только в payload envelope)
- 0
unwrap() в bus/orchestrator
Проблема
Сейчас 31 крейт workspace'а растут органически без единого протокола связи. Агенты общаются через ad-hoc
serde_json::Value, нет типизированного шины сообщений, нет стандартного способа подключить новый крейт в one-shot без знания всей системы.Цель
Текущая карта crates (6 слоёв)
Диагноз:
AgentMessageвtrios-agentsсодержит толькоcontent: String+agent_id. Нетmsg_type, нетpriority, нетcorrelation_id, нетreply_to. Агенты слепые — не знают кто им пишет и зачем.🧩 ПЛАН ДЕКОМПОЗИЦИИ
Шаг 1 —
trios-proto: единый протокол сообщений (L0)Новый микро-крейт, 0 бизнес-логики, только типы:
Зависимости: только
serde,ulid. Никаких tokio/axum в proto.Шаг 2 —
trios-bus: шина сообщений (L1)Паттерн: Actor Model через Tokio broadcast + DashMap (lock-free registry). Ref: Actix Architecture, [Bastion paper 2020].
Шаг 3 — Мигрировать
trios-agentsна новый протоколТекущий
AgentMessage { agent_id, content, timestamp }→ заменить наEnvelope<AgentPayload>:Шаг 4 —
trios-orchestrator: заменяет ручной spawn (L2)Шаг 5 —
trios-sdkобёртка (один import)📐 Граф зависимостей (после рефакторинга)
Правило: зависимости только вниз по слоям. L0 не знает о L1+.
📋 Чеклист задач
Фаза 1: Протокол (≈2 дня)
crates/trios-protoсEnvelope<T>,Routing,PhiPriority,AgentIdulidв workspace dependenciesФаза 2: Шина (≈3 дня)
crates/trios-busс трейтомTriosAgent+Busdashmapв workspace dependenciesФаза 3: Миграция агентов (≈2 дня)
trios-agents:AgentMessage→Envelope<AgentPayload>trios-llm: добавитьimpl TriosAgenttrios-phi-schedule: подключить кBusФаза 4: Оркестратор (≈2 дня)
crates/trios-orchestratorOrchestrator::boot()с autodiscoveryprecision-routerкак middleware шиныФаза 5: SDK one-shot (≈1 день)
trios-sdkprelude::*Trios::boot()+Trios::run()examples/one_shot.rsФаза 6: CI
cargo deny checkдля граф зависимостей🔬 Научные основы
Workspace изменения
Метрики успеха
cargo build --workspaceза < 60s (cold)impl TriosAgentза ≤ 10 строкTrios::boot()поднимает всю систему за ≤ 500msserde_json::Valueв публичных API (только вpayloadenvelope)unwrap()в bus/orchestrator