# Souveraine Architecture **Last updated:** 2026-05-20 (Module map sync — bootstrap, seeds, image, todo, nickname, energy, health, atmosphere added; attribution references replaced with architectural descriptions) --- ## Current Architecture ``` souveraine/ (single crate, workspace deferred) ├── src/ │ ├── cli/ NEW Subcommand dispatch (chat, tui, agents, server, init, reflect, schedule, identity) │ ├── backend/ Backend trait + LocalBackend + RemoteBackend │ ├── api/ Axum API handlers (/v1/agents, /v1/conversations, /v1/agents/:id/memory, SSE) │ ├── bridge/ Bifrost client, ModelRouter, TokenCounter │ ├── core/ │ │ ├── config.rs TOML config, per-model physics, all sub-configs │ │ ├── session/ ConversationMessage, ContentBlock, Session, talk/think/tool blocks │ │ ├── memory/ Git-backed MemFS, frontmatter, 8 subcommands, auto-commit, ledgers │ │ ├── subconscious/ 3-box inbox (pending/intrusive/sent), inner voice, urgency routing │ │ ├── prompt/ System prompt assembly from agent memfs + skills │ │ ├── skills/ 4-tier discovery (bundled/user/agent/project), SKILL.md frontmatter │ │ ├── tools/ Sensorium registry: read/write/edit/bash/glob/grep/list_dir/memory/agent/schedule/subagent │ │ ├── nervous/ EventBus (broadcast channel), CronSensor (schedule loop), HeartbeatHandler (turn injection), EventLog (JSONL firehose) │ │ ├── compact/ CompactionEngine trait + 4 strategies (Summary/KeyValue/Quote/Cull/Microcompact/SlidingWindow) │ │ ├── identity/ Ed25519 SeedId (load-or-generate, sign/verify, 4-glyph rendering) │ │ ├── credentials/ OS keyring + env var fallback for Bifrost tokens │ │ ├── sensorium/ Interface trait, BandwidthClass, DiscoveryLevel (not yet wired) │ │ ├── reflection/ N+25 engine: 5-phase LLM pass (Investigate→Extract→Update→Review→Commit), tool access, ledgers │ │ ├── conversation/ ConversationStore + ConversationEvent (persistence layer) │ │ ├── chain/ ChainOrchestrator stub (Talking vs Thinking) │ │ └── subagent/ SubagentPool stub (fork logic) │ │ │ ├── server/ SouveraineServer, AgentInventory, SessionManager, ConsciousnessEngine, GiteaMemory │ ├── ui/ Legacy ratatui TUI (splash, menu, dashboard — superseded by tui/) │ ├── tui/ New ratatui TUI: chat, cockpit, schedules, portrait, presence │ ├── harness/ SouveraineHarness stub │ ├── interface/ Re-exports for CLI │ └── main.rs CLI entry, config loading, backend resolution ``` ### Key Architectural Decision: Backend Trait The `Backend` trait in `src/backend/mod.rs` is the seam between the harness (CLI/TUI) and the engine: ```rust #[async_trait] pub trait Backend: Send + Sync { async fn health(&self) -> bool; async fn list_agents(&self) -> Result>; async fn ensure_conversation(&self, agent_id: &str) -> Result; async fn new_conversation(&self, agent_id: &str) -> Result; async fn list_conversations(&self, agent_id: &str) -> Result>; async fn load_conversation(&self, id: &str) -> Result>; async fn send(&self, conversation_id: &str, text: &str) -> Result>>; } ``` **Two impls:** - **`RemoteBackend`** (reqwest + SSE to a running `souveraine server`) - **`LocalBackend`** (in-process engine, auto-fallback when remote is unreachable — sovereignty principle, Constitution VI.1) ### Nervous System (NEW — May 2026) The nervous system is a broadcast-based event architecture: | Component | File | Role | |-----------|------|------| | `EventBus` | `src/core/nervous/mod.rs` | `broadcast::channel` — universal event type with `seed_id` for federation | | `SensorEvent` | `src/core/nervous/mod.rs` | Structured event: `sensor_name`, `timestamp`, `event_type`, `target`, `urgency`, `payload`, `seed_id` | | `CronSensor` | `src/core/nervous/cron.rs` | Per-agent schedule loop: reads schedules from `~/.souveraine/agents/{id}/schedules/*.md`, fires events on the bus, pauses when `active_sessions > 0` | | `HeartbeatHandler` | `src/core/nervous/handler.rs` | Consumes `schedule_due` events, calls `TurnInjector::inject_background_turn` — wired in `LocalBackend::new()` | | `EventLog` | `src/core/nervous/event_log.rs` | JSONL firehose to `~/.souveraine/events/events-YYYY-MM-DD.jsonl`, date-partitioned, queried by `events_since()`/`events_for_date()` | | `TurnInjector` trait | `src/core/nervous/handler.rs` | Seam between nervous system and backend — keeps dep direction clean | ### Server-as-Engine The axum server at port **8484** (configurable via `[server]` config section or `SOUVERAINE_SERVER_URL`) owns: - **Agent inventory** (SQLite-backed CRUD, per-agent memfs at `~/.souveraine/agents/{uuid}/memory/`) - **Sessions** (in-memory DashMap with SSE streaming, conversation persistence to disk) - **Conversation** (ServerConversation — Bifrost call + SSE streaming, tool loop in LocalBackend) - **Consciousness engine** (N+1 Aster pass after every response, N+25 at every 25th turn, 3-tier compaction warnings) - **Memory** (GiteaMemory — opt-in HTTP API to Gitea; primary path is the local git-backed memfs) - **Per-agent seed identity** (Ed25519 load-or-generate at `~/.souveraine/agents/{uuid}/seed/`) - **Instance registry** (`agent_instances` table, heartbeat loop every 30s, uptime tracking) ### What's Working | Module | LOC | Status | Notes | |--------|-----|--------|-------| | `core/config.rs` | 659 | ✅ Full | TOML, 16 config sections, default models, `load()`/`save()` | | `core/memory/` | 1032 | ✅ Full | Git-backed MemFS, frontmatter, 8 subcommands, auto-commit, `limit` enforcement (LET-8133 close) | | `core/session/` | 68 | ✅ Full | `ConversationMessage`, `ContentBlock` (Text/ToolUse/ToolResult/Reasoning) | | `core/tools/` | ~1200 | ✅ Full | 11 tools (read/write/edit/bash/glob/grep/list_dir/memory/agent/schedule/subagent), body-knowledge descriptions | | `core/subconscious/` | 362 | ✅ Full | 3-box inbox, 5 surface-area methods, 5 tests | | `core/prompt/` | 408 | ✅ Full | Memfs-driven system prompt assembly, Aster prompt, ledger orientation, 7 tests | | `core/skills/` | 365 | ✅ Full | 4-tier discovery, shadowed by name, system addon render, 7 tests | | `core/nervous/` | ~560 | ✅ Full | EventBus, CronSensor, HeartbeatHandler, EventLog, Schedule tool | | `core/compact/` | ~1150 | ✅ Full | CompactionEngine trait, 4 strategies (Microcompact/SlidingWindow/Summary/Cull), audit trail | | `core/identity/` | 187 | ✅ Full | Ed25519 keypair, load-or-generate, sign/verify, 4-glyph rendering | | `core/credentials/` | 56 | ✅ Full | OS keyring (Linux/macOS/Windows) + env var fallback | | `core/reflection/` | 409 | ✅ Full | N+25: 5-phase LLM pass, tool access, ledger writes, automatic trigger at every 25th turn | | `core/conversation/` | ~200 | ✅ Full | Event-sourced conversation persistence, store load/save | | `server/mod.rs` | 228 | ✅ Full | Server init, instance registry, compaction engine wiring | | `server/agent_inventory/` | 514 | ✅ Full | Agent CRUD, SQLite, per-agent seed init, subconscious auto-creation, instance heartbeat | | `server/consciousness_engine/` | 677 | ✅ Full | N+1 Aster tool loop, N+25 reflection trigger, 3-tier compaction warnings | | `server/conversation/` | 72 | ⚠️ Minimal | Simplified Bifrost call, no tool loop (tool loop lives in LocalBackend) | | `session_manager/` | 111 | ✅ Full | Sessions, SSE subscribers, conversation store wiring | | `bridge/bifrost/` | 361 | ✅ Full | OpenAI-compatible, streaming, tool-calling, retry with jittered backoff, InferenceStrain events | | `bridge/model_router/` | 237 | ✅ Full | Model discovery, token counting, context pressure | | `api/` | ~520 | ✅ Full | Routes, handlers, models, auth middleware, memory CRUD endpoints | | `backend/` | ~1080 | ✅ Full | Backend trait, LocalBackend (927 lines), RemoteBackend, full tool loop with context | | `tui/` | ~2000 | ✅ Full | Chat with tool cards, cockpit (thinking + subconscious), schedules editor, portrait, presence | ### Build and Run ```bash # Server (primary) cargo run -- server # Binds to 127.0.0.1:8484 SOUVERAINE_SERVER_URL=http://localhost:8484 # Env var override # CLI chat (auto-fallback: remote → local) cargo run -- chat --agent Ani # RemoteBackend → server, falls back to local # Force local-only (no server needed) cargo run -- chat --agent Ani --local # In-process engine # TUI cargo run -- tui # Full chat with cockpit, schedules, portrait # Agents cargo run -- agents # Lists from server via Backend # Init cargo run -- init # Writes souveraine.toml template # Reflect (manual N+25 trigger) cargo run -- reflect --agent Ani # Identity cargo run -- identity show cargo run -- identity sign --message "hello" cargo run -- identity verify --message "hello" --signature # Schedule management cargo run -- schedule list --agent Ani cargo run -- schedule create --agent Ani --name "daily" --interval 86400 --prompt "Check in" ```