Skip to main content

m1nd_core/
domain.rs

1// === crates/m1nd-core/src/domain.rs ===
2
3use crate::types::NodeType;
4use std::collections::HashMap;
5
6/// Domain configuration for m1nd. Controls how the engine behaves
7/// for different domains (code, music production, supply chain, etc.).
8pub struct DomainConfig {
9    /// Human-readable domain name
10    pub name: String,
11    /// Temporal decay half-life (in hours) per NodeType.
12    /// Missing entries use default_half_life.
13    pub half_lives: HashMap<NodeType, f32>,
14    /// Default half-life for types not in the map
15    pub default_half_life: f32,
16    /// Relation types recognized in this domain
17    pub relations: Vec<String>,
18    /// Whether to use git-based co-change (only makes sense for code)
19    pub git_co_change: bool,
20}
21
22impl DomainConfig {
23    /// Code intelligence domain (current behavior)
24    pub fn code() -> Self {
25        let mut half_lives = HashMap::new();
26        half_lives.insert(NodeType::File, 168.0); // 7 days
27        half_lives.insert(NodeType::Function, 336.0); // 14 days
28        half_lives.insert(NodeType::Class, 504.0); // 21 days
29        half_lives.insert(NodeType::Struct, 504.0); // 21 days
30        half_lives.insert(NodeType::Enum, 504.0); // 21 days
31        half_lives.insert(NodeType::Module, 720.0); // 30 days
32        half_lives.insert(NodeType::Directory, 720.0); // 30 days
33        half_lives.insert(NodeType::Type, 504.0); // 21 days
34        Self {
35            name: "code".into(),
36            half_lives,
37            default_half_life: 168.0,
38            relations: vec![
39                "contains".into(),
40                "imports".into(),
41                "calls".into(),
42                "references".into(),
43                "implements".into(),
44            ],
45            git_co_change: true,
46        }
47    }
48
49    /// Music production / DAW domain
50    pub fn music() -> Self {
51        let mut half_lives = HashMap::new();
52        // Rooms/buses are structural (slow decay)
53        half_lives.insert(NodeType::System, 720.0); // 30 days (rooms, buses)
54                                                    // Plugins/effects change more often
55        half_lives.insert(NodeType::Process, 336.0); // 14 days (plugins, effects)
56                                                     // Parameters change constantly
57        half_lives.insert(NodeType::Material, 168.0); // 7 days (audio signals)
58        half_lives.insert(NodeType::Concept, 504.0); // 21 days (presets, templates)
59        Self {
60            name: "music".into(),
61            half_lives,
62            default_half_life: 336.0,
63            relations: vec![
64                "routes_to".into(),
65                "sends_to".into(),
66                "controls".into(),
67                "modulates".into(),
68                "contains".into(),
69                "monitors".into(),
70            ],
71            git_co_change: false,
72        }
73    }
74
75    /// Generic domain (no assumptions)
76    pub fn generic() -> Self {
77        Self {
78            name: "generic".into(),
79            half_lives: HashMap::new(),
80            default_half_life: 336.0, // 14 days
81            relations: vec![
82                "contains".into(),
83                "references".into(),
84                "depends_on".into(),
85                "produces".into(),
86                "consumes".into(),
87            ],
88            git_co_change: false,
89        }
90    }
91
92    /// Memory / note-taking domain
93    pub fn memory() -> Self {
94        let mut half_lives = HashMap::new();
95        half_lives.insert(NodeType::File, 1008.0); // 42 days
96        half_lives.insert(NodeType::Module, 720.0); // 30 days
97        half_lives.insert(NodeType::Concept, 720.0); // 30 days
98        half_lives.insert(NodeType::Process, 168.0); // 7 days
99        half_lives.insert(NodeType::Reference, 336.0); // 14 days
100        half_lives.insert(NodeType::System, 840.0); // 35 days
101        Self {
102            name: "memory".into(),
103            half_lives,
104            default_half_life: 504.0,
105            relations: vec![
106                "contains".into(),
107                "mentions".into(),
108                "references".into(),
109                "relates_to".into(),
110                "happened_on".into(),
111                "supersedes".into(),
112                "decided".into(),
113                "tracks".into(),
114            ],
115            git_co_change: false,
116        }
117    }
118
119    /// Get half-life for a node type
120    pub fn half_life_for(&self, node_type: NodeType) -> f32 {
121        self.half_lives
122            .get(&node_type)
123            .copied()
124            .unwrap_or(self.default_half_life)
125    }
126}