Skip to main content

subcog/config/
features.rs

1//! Feature flags for optional functionality.
2
3use super::ConfigFileFeatures;
4
5/// Feature flags for controlling optional subcog features.
6#[derive(Debug, Clone, Default)]
7#[allow(clippy::struct_excessive_bools)]
8pub struct FeatureFlags {
9    /// Enable secret detection and filtering.
10    pub secrets_filter: bool,
11    /// Enable PII detection and filtering.
12    pub pii_filter: bool,
13    /// Enable multi-domain support.
14    pub multi_domain: bool,
15    /// Enable audit logging.
16    pub audit_log: bool,
17    /// Enable LLM-powered features.
18    pub llm_features: bool,
19    /// Enable auto-capture during hooks.
20    pub auto_capture: bool,
21    /// Enable memory consolidation.
22    pub consolidation: bool,
23    /// Enable org-scope storage (PostgreSQL shared storage).
24    pub org_scope_enabled: bool,
25    /// Enable automatic entity extraction during memory capture.
26    ///
27    /// When enabled, entities (people, organizations, technologies, concepts)
28    /// are automatically extracted from captured memories and stored in the
29    /// knowledge graph for graph-augmented retrieval.
30    pub auto_extract_entities: bool,
31}
32
33impl FeatureFlags {
34    /// Creates feature flags with all features disabled.
35    #[must_use]
36    pub const fn none() -> Self {
37        Self {
38            secrets_filter: false,
39            pii_filter: false,
40            multi_domain: false,
41            audit_log: false,
42            llm_features: false,
43            auto_capture: false,
44            consolidation: false,
45            org_scope_enabled: false,
46            auto_extract_entities: false,
47        }
48    }
49
50    /// Creates feature flags with core features enabled.
51    #[must_use]
52    pub const fn core() -> Self {
53        Self {
54            secrets_filter: true,
55            pii_filter: true,
56            multi_domain: false,
57            audit_log: false,
58            llm_features: false,
59            auto_capture: false,
60            consolidation: false,
61            org_scope_enabled: false,
62            auto_extract_entities: true,
63        }
64    }
65
66    /// Creates feature flags with all features enabled.
67    #[must_use]
68    pub const fn all() -> Self {
69        Self {
70            secrets_filter: true,
71            pii_filter: true,
72            multi_domain: true,
73            audit_log: true,
74            llm_features: true,
75            auto_capture: true,
76            consolidation: true,
77            org_scope_enabled: true,
78            auto_extract_entities: true,
79        }
80    }
81
82    /// Creates feature flags from config file settings.
83    ///
84    /// ARCH-HIGH-002: Delegated from `SubcogConfig::apply_config_file`.
85    #[must_use]
86    pub fn from_config_file(file: &ConfigFileFeatures) -> Self {
87        let mut flags = Self::default();
88        if let Some(v) = file.secrets_filter {
89            flags.secrets_filter = v;
90        }
91        if let Some(v) = file.pii_filter {
92            flags.pii_filter = v;
93        }
94        if let Some(v) = file.multi_domain {
95            flags.multi_domain = v;
96        }
97        if let Some(v) = file.audit_log {
98            flags.audit_log = v;
99        }
100        if let Some(v) = file.llm_features {
101            flags.llm_features = v;
102        }
103        if let Some(v) = file.auto_capture {
104            flags.auto_capture = v;
105        }
106        if let Some(v) = file.consolidation {
107            flags.consolidation = v;
108        }
109        if let Some(v) = file.org_scope_enabled {
110            flags.org_scope_enabled = v;
111        }
112        if let Some(v) = file.auto_extract_entities {
113            flags.auto_extract_entities = v;
114        }
115        flags
116    }
117
118    /// Merges another set of flags into this one.
119    ///
120    /// Only overrides fields that are set in the source.
121    pub const fn merge_from(&mut self, file: &ConfigFileFeatures) {
122        if let Some(v) = file.secrets_filter {
123            self.secrets_filter = v;
124        }
125        if let Some(v) = file.pii_filter {
126            self.pii_filter = v;
127        }
128        if let Some(v) = file.multi_domain {
129            self.multi_domain = v;
130        }
131        if let Some(v) = file.audit_log {
132            self.audit_log = v;
133        }
134        if let Some(v) = file.llm_features {
135            self.llm_features = v;
136        }
137        if let Some(v) = file.auto_capture {
138            self.auto_capture = v;
139        }
140        if let Some(v) = file.consolidation {
141            self.consolidation = v;
142        }
143        if let Some(v) = file.org_scope_enabled {
144            self.org_scope_enabled = v;
145        }
146        if let Some(v) = file.auto_extract_entities {
147            self.auto_extract_entities = v;
148        }
149    }
150}