Skip to main content

maple_runtime/types/
coupling.rs

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