//! # main.rs — BEDS Entry Point //! //! Application entry point. Invokes the IPL (Initial Program Load) sequence //! which bootstraps all required services before the node enters its //! operational state. //! //! ## Calling Agents //! None — this is the process entry point. //! //! ## Inputs //! - `BEDS_ENV` environment variable selects the env config file (default: dev) //! //! ## Outputs //! - Running BEDS node, blocked on signal handler (not yet implemented) //! - On fatal IPL failure: error output to console, process exits non-zero //! //! **Author:** ms //! **Version:** 1.0 //! //! ## History //! * `2026-04-02` - mks - original coding //! * `2026-04-02` - mks - refactored startup sequence into ipl() mod amqp; mod config; mod logging; /// Executes the BEDS Initial Program Load (IPL) sequence. /// /// IPL bootstraps the node in strict order. Each step must succeed before /// the next is attempted. In production environments, any failure is fatal /// and the process exits with a console error report. In development /// environments, non-critical failures are logged and IPL continues. /// /// ## IPL Sequence /// 1. Load configuration (beds.toml + env override) /// 2. Initialize logging /// 3. Connect to required services (AMQP, store adapters) — not yet implemented /// 4. Declare queues based on node role — not yet implemented /// 5. Node green /// /// # Returns /// /// `Ok(())` if all required services are available and the node is ready. /// `Err(String)` with a descriptive error message if IPL cannot complete. /// /// # History /// /// * `2026-04-02` - mks - original coding fn ipl() -> Result<(), String> { // load configuration — fatal in all environments if this fails let cfg = config::load().map_err(|e| format!("Failed to load config: {}", e))?; // initialize logging — must come before any tracing calls logging::init_from_config(cfg.syslog, cfg.syslog_mirror_console); tracing::info!("BEDS IPL starting, node={} env={}", cfg.id.wbid, cfg.id.env_name); tracing::info!("Configuration loaded"); tracing::info!("Logging initialized"); // validate broker reachability — fatal in production, non-fatal in all other envs match amqp::validate(&cfg.broker_services) { Ok(()) => tracing::info!("RabbitMQ reachable"), Err(e) => { if cfg.id.env_name == "production" { return Err(e); } tracing::warn!("RabbitMQ unreachable (non-fatal in {}): {}", cfg.id.env_name, e); } } Ok(()) } fn main() { if let Err(e) = ipl() { eprintln!("[BEDS] [FATAL] [IPL] {}", e); std::process::exit(1); } }