Skip to main content

maple_runtime/types/
coupling.rs

1//! Coupling relationship types
2
3use serde::{Deserialize, Serialize};
4use super::ids::{CouplingId, ResonatorId};
5use super::temporal::TemporalAnchor;
6
7/// A coupling relationship between Resonators
8///
9/// Coupling describes the strength and character of interaction.
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct Coupling {
12    pub id: CouplingId,
13    pub source: ResonatorId,
14    pub target: ResonatorId,
15
16    // ═══════════════════════════════════════════════════════════════════
17    // COUPLING DIMENSIONS (from Resonance Architecture)
18    // ═══════════════════════════════════════════════════════════════════
19
20    /// Intensity: How much influence is allowed (0.0 to 1.0)
21    pub strength: f64,
22
23    /// Persistence: How long the coupling lasts
24    pub persistence: CouplingPersistence,
25
26    /// Scope: Which aspects of state are affected
27    pub scope: CouplingScope,
28
29    /// Symmetry: Whether influence is mutual
30    pub symmetry: SymmetryType,
31
32    // ═══════════════════════════════════════════════════════════════════
33    // ATTENTION BINDING
34    // ═══════════════════════════════════════════════════════════════════
35
36    /// Attention allocated to this coupling
37    pub attention_allocated: u64,
38
39    // ═══════════════════════════════════════════════════════════════════
40    // COUPLING HEALTH
41    // ═══════════════════════════════════════════════════════════════════
42
43    /// How well does meaning converge between these Resonators?
44    pub meaning_convergence: f64,
45
46    /// Interaction count
47    pub interaction_count: u64,
48
49    /// Created at (temporal anchor)
50    pub created_at: TemporalAnchor,
51
52    /// Last resonance through this coupling
53    pub last_resonance: TemporalAnchor,
54}
55
56impl Coupling {
57    /// Is this coupling healthy?
58    pub fn is_healthy(&self) -> bool {
59        self.meaning_convergence > 0.3 && self.strength > 0.1
60    }
61
62    /// Should this coupling be strengthened?
63    pub fn should_strengthen(&self) -> bool {
64        self.meaning_convergence > 0.7 && self.strength < 0.8
65    }
66
67    /// Should this coupling be weakened?
68    pub fn should_weaken(&self) -> bool {
69        self.meaning_convergence < 0.2 && self.strength > 0.2
70    }
71}
72
73/// How long does a coupling last?
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
75pub enum CouplingPersistence {
76    /// Coupling lasts for a single interaction
77    Transient,
78
79    /// Coupling lasts for a session
80    Session,
81
82    /// Coupling persists indefinitely
83    Persistent,
84
85    /// Coupling lasts for a specific duration (in seconds)
86    Timed(u64),
87}
88
89/// Which aspects of state are affected by coupling?
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
91pub enum CouplingScope {
92    /// Full coupling: state, intent, and commitment visibility
93    Full,
94
95    /// Only state is shared
96    StateOnly,
97
98    /// Only intent is shared
99    IntentOnly,
100
101    /// Only observation, no influence
102    ObservationalOnly,
103}
104
105/// Is influence mutual or one-way?
106#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
107pub enum SymmetryType {
108    /// Both Resonators influence each other equally
109    Symmetric,
110
111    /// Asymmetric influence (primary has more influence)
112    Asymmetric { primary: ResonatorId },
113}
114
115/// Parameters for establishing a new coupling
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct CouplingParams {
118    pub source: ResonatorId,
119    pub target: ResonatorId,
120
121    /// Initial coupling strength (MUST be <= 0.3 to prevent abrupt escalation)
122    pub initial_strength: f64,
123
124    /// Initial attention cost
125    pub initial_attention_cost: u64,
126
127    /// Persistence
128    pub persistence: CouplingPersistence,
129
130    /// Scope
131    pub scope: CouplingScope,
132
133    /// Symmetry
134    pub symmetry: SymmetryType,
135}
136
137impl CouplingParams {
138    /// Validate parameters before coupling
139    pub fn validate(&self) -> Result<(), CouplingValidationError> {
140        // ARCHITECTURAL RULE: Initial strength cannot be too aggressive
141        if self.initial_strength > 0.3 {
142            return Err(CouplingValidationError::InitialStrengthTooHigh);
143        }
144
145        if self.initial_strength < 0.0 || self.initial_strength > 1.0 {
146            return Err(CouplingValidationError::InvalidStrength);
147        }
148
149        if self.initial_attention_cost == 0 {
150            return Err(CouplingValidationError::ZeroAttentionCost);
151        }
152
153        Ok(())
154    }
155}
156
157/// Affinity specification for preferred coupling patterns
158#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct CouplingAffinitySpec {
160    /// Preferred coupling strength
161    pub preferred_strength: f64,
162
163    /// Preferred persistence
164    pub preferred_persistence: CouplingPersistence,
165
166    /// Preferred scope
167    pub preferred_scope: CouplingScope,
168
169    /// Maximum number of concurrent couplings
170    pub max_concurrent_couplings: Option<usize>,
171}
172
173impl Default for CouplingAffinitySpec {
174    fn default() -> Self {
175        Self {
176            preferred_strength: 0.3,
177            preferred_persistence: CouplingPersistence::Session,
178            preferred_scope: CouplingScope::Full,
179            max_concurrent_couplings: Some(100),
180        }
181    }
182}
183
184/// Coupling validation errors
185#[derive(Debug, Clone, thiserror::Error)]
186pub enum CouplingValidationError {
187    #[error("Initial coupling strength too high (max 0.3)")]
188    InitialStrengthTooHigh,
189
190    #[error("Invalid strength value (must be 0.0-1.0)")]
191    InvalidStrength,
192
193    #[error("Attention cost cannot be zero")]
194    ZeroAttentionCost,
195}
196
197/// Configuration for coupling behavior
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct CouplingConfig {
200    /// Maximum initial strength
201    pub max_initial_strength: f64,
202
203    /// Maximum strengthening per interaction
204    pub max_strengthening_rate: f64,
205
206    /// Enable automatic coupling adjustment?
207    pub enable_auto_adjustment: bool,
208
209    /// Minimum meaning convergence to maintain coupling
210    pub min_meaning_convergence: f64,
211}
212
213impl Default for CouplingConfig {
214    fn default() -> Self {
215        Self {
216            max_initial_strength: 0.3,
217            max_strengthening_rate: 0.1,
218            enable_auto_adjustment: true,
219            min_meaning_convergence: 0.1,
220        }
221    }
222}