# Provisioning Daemon Validator let daemon_schema = import "../schemas/provisioning-daemon.ncl" in let constraints = import "../constraints/constraints.toml" in { validate_daemon_config | daemon_schema.DaemonConfig -> Array String = fun config => let errors = [] in # Daemon configuration validation let errors = if config.daemon.poll_interval < constraints.daemon.poll_interval.min then errors @ ["Poll interval below minimum (#{constraints.daemon.poll_interval.min})s"] else if config.daemon.poll_interval > constraints.daemon.poll_interval.max then errors @ ["Poll interval above maximum (#{constraints.daemon.poll_interval.max})s"] else errors in let errors = if config.daemon.max_workers < constraints.daemon.max_workers.min then errors @ ["Max workers below minimum (#{constraints.daemon.max_workers.min})"] else if config.daemon.max_workers > constraints.daemon.max_workers.max then errors @ ["Max workers above maximum (#{constraints.daemon.max_workers.max})"] else errors in let errors = if config.daemon.startup_delay < 0 || config.daemon.startup_delay > 300 then errors @ ["Startup delay must be between 0 and 300 seconds"] else errors in let errors = if config.daemon.graceful_shutdown_timeout < 5 || config.daemon.graceful_shutdown_timeout > 300 then errors @ ["Graceful shutdown timeout must be between 5 and 300 seconds"] else errors in # Logging configuration validation let errors = if std.array.length config.logging.file == 0 then errors @ ["Log file path cannot be empty"] else errors in let errors = if config.logging.max_size < 1 || config.logging.max_size > 1000 then errors @ ["Max log size must be between 1 and 1000 MB"] else errors in let errors = if config.logging.retention_days < 1 || config.logging.retention_days > 365 then errors @ ["Log retention days must be between 1 and 365"] else errors in # Actions configuration validation let errors = if config.actions.cleanup_interval < 1 || config.actions.cleanup_interval > 168 then errors @ ["Cleanup interval must be between 1 and 168 hours"] else errors in let errors = if config.actions.sync_interval < 5 || config.actions.sync_interval > 1440 then errors @ ["Sync interval must be between 5 and 1440 minutes"] else errors in # Workers configuration validation let errors = if config.workers.thread_pool_size < 1 || config.workers.thread_pool_size > 32 then errors @ ["Thread pool size must be between 1 and 32"] else errors in let errors = if config.workers.max_task_queue_depth < 10 || config.workers.max_task_queue_depth > 100000 then errors @ ["Max task queue depth must be between 10 and 100000"] else errors in let errors = if config.workers.task_timeout < 10 || config.workers.task_timeout > 3600 then errors @ ["Task timeout must be between 10 and 3600 seconds"] else errors in let errors = if config.workers.worker_idle_timeout < 10 || config.workers.worker_idle_timeout > 600 then errors @ ["Worker idle timeout must be between 10 and 600 seconds"] else errors in # Health configuration validation let errors = if config.health.health_check_interval < 10 || config.health.health_check_interval > 600 then errors @ ["Health check interval must be between 10 and 600 seconds"] else errors in let errors = if config.health.liveness_timeout < 30 || config.health.liveness_timeout > 600 then errors @ ["Liveness timeout must be between 30 and 600 seconds"] else errors in let errors = if config.health.readiness_timeout < 5 || config.health.readiness_timeout > 300 then errors @ ["Readiness timeout must be between 5 and 300 seconds"] else errors in let errors = if config.health.metrics_port < 1024 || config.health.metrics_port > 65535 then errors @ ["Metrics port must be between 1024 and 65535"] else errors in let errors = if config.health.alert_threshold < 10 || config.health.alert_threshold > 100 then errors @ ["Alert threshold must be between 10 and 100 percent"] else errors in # Ensure timeout consistency let errors = if config.health.liveness_timeout <= config.health.readiness_timeout then errors @ ["Liveness timeout must be greater than readiness timeout"] else errors in errors, }