nizaam-core 1.0.1

Domain-agnostic Rust infrastructure core for building secure, observable, reliable, and extensible Nizaam engines.
Documentation
mod context;
mod dispatch;
mod event;
mod instance;
mod sink;
mod system;
mod validation;

pub use context::{LogContext, LogScope, LogSource};
pub use dispatch::{DispatchError, DispatchOutcome};
pub use event::{LogEvent, LogEventType, LogLevel, LogMetadata};
pub use instance::{InstanceError, LoggingInstance};
pub use sink::LogSink;
pub use system::LoggingSystem;
pub use validation::LogValidationError;

#[cfg(test)]
mod tests {
    use std::sync::{Arc, Mutex, mpsc};
    use std::time::Duration;

    use super::*;
    use crate::events::EventName;
    use crate::identity::{CorrelationId, EngineId, MessageId, OperationId};
    use crate::operation::{Operation, OperationContext};

    struct RecordingSink {
        sender: Mutex<mpsc::Sender<LogEvent>>,
    }

    impl RecordingSink {
        fn new(sender: mpsc::Sender<LogEvent>) -> Self {
            Self {
                sender: Mutex::new(sender),
            }
        }
    }

    impl LogSink for RecordingSink {
        fn publish(&self, event: &LogEvent) {
            let _ = self
                .sender
                .lock()
                .expect("recording sink mutex must not be poisoned")
                .send(event.clone());
        }
    }

    fn operation_context() -> OperationContext {
        OperationContext::new(Operation::new(
            OperationId::new("logging-operation").unwrap(),
            CorrelationId::new("logging-correlation").unwrap(),
        ))
    }

    fn global_event() -> LogEvent {
        LogEvent::new(
            EventName::new("logging.event").unwrap(),
            LogLevel::Info,
            LogSource::Core,
            LogScope::Global,
            "logging-test",
            LogContext::new(operation_context()),
            "global log event",
            LogEventType::Diagnostic,
        )
        .unwrap()
    }

    fn local_engine_event(engine_id: EngineId) -> LogEvent {
        LogEvent::new(
            EventName::new("engine.event").unwrap(),
            LogLevel::Info,
            LogSource::Engine(engine_id.clone()),
            LogScope::Local,
            "engine-component",
            LogContext::new(operation_context()).from_engine(engine_id),
            "local engine event",
            LogEventType::RequestReceived,
        )
        .unwrap()
    }

    #[test]
    fn log_event_constructs_universal_event_internally() {
        let message_id = MessageId::new("message-1").unwrap();

        let event = LogEvent::new(
            EventName::new("logging.event").unwrap(),
            LogLevel::Info,
            LogSource::Core,
            LogScope::Global,
            "logging-test",
            LogContext::new(operation_context()).for_message(message_id.clone()),
            "log event",
            LogEventType::Diagnostic,
        )
        .unwrap();

        assert!(!event.event_id().as_str().is_empty());
        assert_eq!(event.message_id(), &message_id);
        assert_eq!(event.event_name().as_str(), "logging.event");
        assert_eq!(event.event_type(), "diagnostic");
        assert_eq!(event.event_scope(), "global");
        assert_eq!(event.context.message_id.as_ref(), Some(&message_id));
    }

    #[test]
    fn level_2_logging_system_composes_event_instance_dispatch_and_sink() {
        let system = LoggingSystem::new(8).unwrap();
        let (sender, receiver) = mpsc::channel();
        system.subscribe(Arc::new(RecordingSink::new(sender)));

        let instance = system.instance(LogScope::Global, LogSource::Core);
        let event = global_event();

        assert_eq!(
            instance.publish(event.clone()).unwrap(),
            DispatchOutcome::Queued
        );

        let received = receiver
            .recv_timeout(Duration::from_secs(1))
            .expect("queued event should reach the subscribed sink");

        assert_eq!(received, event);
        system.shutdown().unwrap();
    }

    #[test]
    fn level_2_engine_instance_isolation_is_enforced_by_logging_instance() {
        let system = LoggingSystem::new(8).unwrap();
        let engine = EngineId::new("quran-engine").unwrap();

        let global_instance = system.instance(LogScope::Global, LogSource::Core);
        let local_instance = system.instance(LogScope::Local, LogSource::Engine(engine.clone()));

        assert_eq!(
            global_instance.publish(local_engine_event(engine.clone())),
            Err(InstanceError::ScopeMismatch)
        );

        assert_eq!(
            local_instance.publish(global_event()),
            Err(InstanceError::ScopeMismatch)
        );

        system.shutdown().unwrap();
    }

    #[test]
    fn level_2_validation_rejects_source_and_context_mismatch() {
        let system = LoggingSystem::new(8).unwrap();
        let quran = EngineId::new("quran-engine").unwrap();
        let hadith = EngineId::new("hadith-engine").unwrap();

        let event = LogEvent::new(
            EventName::new("engine.event").unwrap(),
            LogLevel::Info,
            LogSource::Engine(quran),
            LogScope::Local,
            "engine-component",
            LogContext::new(operation_context()).from_engine(hadith),
            "mismatched engine context",
            LogEventType::RequestReceived,
        );

        assert_eq!(event, Err(LogValidationError::SourceContextMismatch));

        let local_instance = system.instance(
            LogScope::Local,
            LogSource::Engine(EngineId::new("quran-engine").unwrap()),
        );

        assert_eq!(
            local_instance.publish(global_event()),
            Err(InstanceError::ScopeMismatch)
        );

        system.shutdown().unwrap();
    }

    #[test]
    fn level_2_metadata_and_context_survive_end_to_end_dispatch() {
        let system = LoggingSystem::new(8).unwrap();
        let (sender, receiver) = mpsc::channel();
        system.subscribe(Arc::new(RecordingSink::new(sender)));

        let engine = EngineId::new("quran-engine").unwrap();
        let instance = system.instance(LogScope::Local, LogSource::Engine(engine.clone()));

        let event = LogEvent::new(
            EventName::new("quran.request").unwrap(),
            LogLevel::Warning,
            LogSource::Engine(engine.clone()),
            LogScope::Local,
            "quran-api",
            LogContext::new(operation_context())
                .from_engine(engine.clone())
                .for_message(MessageId::new("message-1").unwrap())
                .with_trace_context("trace-context-1"),
            "request is degraded",
            LogEventType::Warning,
        )
        .unwrap()
        .with_metadata("component", "quran-api")
        .with_metadata("state", "degraded");

        instance.publish(event.clone()).unwrap();

        let received = receiver
            .recv_timeout(Duration::from_secs(1))
            .expect("event should be delivered");

        assert_eq!(received, event);
        assert_eq!(
            received.context.message_id.as_ref().unwrap().as_str(),
            "message-1"
        );
        assert_eq!(
            received.context.trace_context.as_deref(),
            Some("trace-context-1")
        );
        assert_eq!(
            received.metadata.get("component").map(String::as_str),
            Some("quran-api")
        );
        assert_eq!(
            received.metadata.get("state").map(String::as_str),
            Some("degraded")
        );
        assert_eq!(received.event_name().as_str(), "quran.request");
        assert_eq!(received.event_type(), "warning");
        assert_eq!(received.event_scope(), "engine:quran-engine");

        system.shutdown().unwrap();
    }

    #[test]
    fn level_2_invalid_capacity_is_rejected_at_system_boundary() {
        assert!(matches!(
            LoggingSystem::new(0),
            Err(DispatchError::InvalidCapacity)
        ));
    }
}