# mimirs-ha

![mimirs-ha concept](../docs/assets/mimirs_ha_concept.png)


High-availability replication layer: Raft consensus, write-ahead log, event bus, and pluggable storage backends.

## What It Does

- `ThingNode`: Raft consensus node. Manages agent participation in the cluster. `samykki()` proposes changes to the quorum.
- `Saga`: Write-ahead log (WAL). `skrifa()` appends entries. `lesa()` reads entries. `apply_to()` replays entries to a storage backend.
- `SagaEntry`: Enum with variants `Rista(Memory)`, `Tengja(String, String, String)`, `BlockAttached { block }`, `BlockDetached { block_id }`.
- `ApplyChange` trait: Implemented by storage backends to apply WAL entries.
- `MemorySignal`: Enum with 11 variants for real-time agent coordination (MemoryStored, MemoryRecalled, BlockAttached, BlockDetached, VerifiabilityChanged, ConsolidationCompleted, IdentityEvolved, ConflictDetected, ConsensusReached, NodeHeartbeat).
- `EventBus`: In-process pub/sub for `MemorySignal` events. `broadcast()`, `subscribe()`, `send_to_agent()`.
- `StorageBackend` trait: Async trait for pluggable persistence backends.
- `FileStorageBackend`: File-based implementation of `StorageBackend`.
- `ElderQuorum`, `Elder` trait: Quorum evaluation with `CognitiveShift` and `EvaluatorPersona` enums.
- `ZenohTransport`: Zenoh-based distributed transport layer.

## What It Does NOT Do

- No encoding, no reservoir computing, no OTOC, no identity management.
- No contradiction detection, no consolidation.

## Public API

```rust
pub struct ThingNode {
    /* internal: agent_id, bus, raft state */
}

impl ThingNode {
    pub fn new(agent_id: AgentId, bus: EventBus) -> Self;

    /// Proposes a change to the Raft quorum.
    pub async fn samykki(&self, entry: SagaEntry) -> Result<(), MimirError>;
}

pub struct Saga {
    /* internal: entries */
}

impl Saga {
    pub fn new() -> Self;
    pub fn skrifa(&mut self, entry: SagaEntry) -> Result<(), MimirError>;
    pub fn lesa(&self) -> Result<Vec<SagaEntry>, MimirError>;
    pub fn clear_up_to(&mut self, lsn: u64);
    pub fn apply_to(&self, backend: &dyn ApplyChange) -> Result<(), MimirError>;
}

pub enum SagaEntry {
    Rista(Memory),
    Tengja(String, String, String), // frandi, nidur, merki
    BlockAttached { agent_id: AgentId, block: MemoryBlock },
    BlockDetached { agent_id: AgentId, block_id: BlockId },
}

#[async_trait]
pub trait StorageBackend {
    async fn write_entry(&self, entry: &SagaEntry) -> Result<(), MimirError>;
    async fn read_entries(&self) -> Result<Vec<SagaEntry>, MimirError>;
    async fn last_lsn(&self) -> Result<u64, MimirError>;
}

pub trait ApplyChange {
    fn apply(&self, entry: SagaEntry) -> Result<(), MimirError>;
}

pub struct EventBus {
    /* internal: subscribers */
}

impl EventBus {
    pub fn new() -> Self;
    pub fn with_capacity(capacity: usize) -> Self;
    pub fn subscribe(&self) -> tokio::sync::broadcast::Receiver<MemorySignal>;
    pub fn broadcast(&self, signal: MemorySignal) -> Result<(), MimirError>;
    pub fn send_to_agent(&self, agent_id: AgentId, signal: MemorySignal) -> Result<(), MimirError>;
    pub fn subscriber_count(&self) -> usize;
}

pub struct ElderQuorum { /* internal */ }

impl ElderQuorum {
    pub fn new() -> Self;
}

pub trait Elder {
    fn persona(&self) -> EvaluatorPersona;
    async fn evaluate(&self, signal: &MemorySignal) -> Result<CognitiveShift, MimirError>;
}

pub enum CognitiveShift { Expansion, Contraction, Stability }
pub enum EvaluatorPersona { Architect, Security, Compliance }
```

## Usage Example

```rust
use mimirs_ha::{EventBus, MemorySignal, ThingNode, Saga, SagaEntry};
use mimirs_core::{AgentId, MemoryId, MemoryClass};

let bus = EventBus::new();
let agent_id = AgentId::new();
let thing = ThingNode::new(agent_id, bus.clone());

// Broadcast a signal
bus.broadcast(MemorySignal::MemoryStored {
    agent_id,
    memory_id: MemoryId::new(),
    memory_class: MemoryClass::Episodic,
}).unwrap();

// Subscribe to signals
let mut rx = bus.subscribe();
```

## Dependencies

- `mimirs-core`: Foundation types
- `raft-rs`: Raft consensus
- `bytes`: Byte buffer management
- `reqwest`: HTTP client (for Zenoh transport)
- `axum`, `tower`: HTTP server framework
- `bincode`: Binary serialization
- `tracing`, `tracing-subscriber`: Logging
- `pretty_assertions`, `tempfile` (dev): Testing

## Known Limitations

- **Simulated Raft consensus**: `ThingNode` contains a simplified consensus skeleton rather than a full, production-hardened distributed consensus engine. Advanced failure modes, split-brains, and network partition recovery are out of scope.
- **In-Memory Default WAL**: The standard `Saga` struct operates on an in-memory WAL buffer. Unless a persistent `StorageBackend` is explicitly attached and flushed, all logs are volatile and will be lost on process termination.
- **Broadcast Subscriber Lag**: `EventBus` leverages `tokio::sync::broadcast`. Extremely slow consumers will lag, causing them to miss broadcast `MemorySignal` events once the internal channel buffer capacity is exhausted.
