/// Typed representation of `.ontoref/config.ncl`. /// /// Every section that the daemon reads from its own config file is captured /// here with `#[derive(ConfigFields)]` so that `inventory` registers the /// consumed fields at link time. The coherence endpoint can then compare /// these registrations against the live NCL export without needing a /// hand-maintained `fields` list in `manifest.ncl`. /// /// All fields carry `#[serde(default)]` — a project may omit any section and /// the daemon degrades gracefully rather than failing to start. use ontoref_ontology::ConfigFields; use serde::Deserialize; /// Full deserialized view of `.ontoref/config.ncl`. #[derive(Debug, Deserialize, Default)] pub struct DaemonNclConfig { #[serde(default)] pub nickel_import_paths: Vec, #[serde(default)] pub ui: UiConfig, #[serde(default)] pub log: LogConfig, #[serde(default)] pub mode_run: ModeRunConfig, #[serde(default)] pub nats_events: NatsEventsConfig, #[serde(default)] pub actor_init: Vec, #[serde(default)] pub quick_actions: Vec, #[serde(default)] pub daemon: DaemonRuntimeConfig, #[cfg(feature = "db")] #[serde(default)] pub db: DbConfig, } /// `ui` section — template and asset paths, optional TLS cert overrides. #[derive(Debug, Deserialize, Default, ConfigFields)] #[config_section(id = "ui", ncl_file = ".ontoref/config.ncl")] pub struct UiConfig { #[serde(default)] pub templates_dir: String, #[serde(default)] pub public_dir: String, #[serde(default)] pub tls_cert: String, #[serde(default)] pub tls_key: String, #[serde(default)] pub logo: String, #[serde(default)] pub logo_dark: String, } /// `log` section — structured logging policy. #[derive(Debug, Deserialize, ConfigFields)] #[config_section(id = "log", ncl_file = ".ontoref/config.ncl")] pub struct LogConfig { #[serde(default = "default_log_level")] pub level: String, #[serde(default = "default_log_path")] pub path: String, #[serde(default = "default_rotation")] pub rotation: String, #[serde(default)] pub compress: bool, #[serde(default = "default_log_archive")] pub archive: String, #[serde(default = "default_max_files")] pub max_files: u32, } impl Default for LogConfig { fn default() -> Self { Self { level: default_log_level(), path: default_log_path(), rotation: default_rotation(), compress: false, archive: default_log_archive(), max_files: default_max_files(), } } } fn default_log_level() -> String { "info".into() } fn default_log_path() -> String { "logs".into() } fn default_rotation() -> String { "daily".into() } fn default_log_archive() -> String { "logs-archive".into() } fn default_max_files() -> u32 { 7 } /// `nats_events` section — NATS JetStream integration. #[derive(Debug, Deserialize, Default, ConfigFields)] #[config_section(id = "nats_events", ncl_file = ".ontoref/config.ncl")] pub struct NatsEventsConfig { #[serde(default)] pub enabled: bool, #[serde(default = "default_nats_url")] pub url: String, #[serde(default)] pub emit: Vec, #[serde(default)] pub subscribe: Vec, #[serde(default)] pub handlers_dir: String, #[serde(default)] pub nkey_seed: Option, #[serde(default)] pub require_signed_messages: bool, #[serde(default)] pub trusted_nkeys: Vec, #[serde(default)] pub streams_config: String, } fn default_nats_url() -> String { "nats://localhost:4222".into() } /// `mode_run` section — per-actor mode execution ACL. #[derive(Debug, Deserialize, Default, ConfigFields)] #[config_section(id = "mode_run", ncl_file = ".ontoref/config.ncl")] pub struct ModeRunConfig { #[serde(default)] pub rules: Vec, } #[derive(Debug, Deserialize, Default)] pub struct ModeRunRule { #[serde(default)] pub when: ModeRunWhen, #[serde(default)] pub allow: bool, #[serde(default)] pub reason: String, } #[derive(Debug, Deserialize, Default)] pub struct ModeRunWhen { #[serde(default)] pub mode_id: Option, #[serde(default)] pub actor: Option, } /// One entry in the `actor_init` array. #[derive(Debug, Deserialize, Default)] pub struct ActorInit { #[serde(default)] pub actor: String, #[serde(default)] pub mode: String, #[serde(default)] pub auto_run: bool, } /// One entry in the `quick_actions` array. #[derive(Debug, Deserialize, Default)] pub struct QuickAction { #[serde(default)] pub id: String, #[serde(default)] pub label: String, #[serde(default)] pub icon: String, #[serde(default)] pub category: String, #[serde(default)] pub mode: String, #[serde(default)] pub actors: Vec, } /// `daemon` section — overrides for CLI defaults set at startup. #[derive(Debug, Deserialize, Default, ConfigFields)] #[config_section(id = "daemon", ncl_file = ".ontoref/config.ncl")] pub struct DaemonRuntimeConfig { #[serde(default)] pub port: Option, #[serde(default)] pub idle_timeout: Option, #[serde(default)] pub invalidation_interval: Option, #[serde(default)] pub actor_sweep_interval: Option, #[serde(default)] pub actor_stale_timeout: Option, #[serde(default)] pub max_notifications: Option, #[serde(default)] pub notification_ack_required: Vec, } /// `db` section — SurrealDB connection (feature-gated). #[cfg(feature = "db")] #[derive(Debug, Deserialize, Default, ConfigFields)] #[config_section(id = "db", ncl_file = ".ontoref/config.ncl")] pub struct DbConfig { #[serde(default)] pub enabled: bool, #[serde(default)] pub url: String, #[serde(default)] pub namespace: String, #[serde(default)] pub username: String, #[serde(default)] pub password: String, }