Skip to main content

maple_runtime/temporal/
mod.rs

1//! Temporal coordination without global clocks
2//!
3//! The Resonance Architecture does NOT assume synchronized clocks.
4//! Time is defined relationally through temporal anchors.
5
6use crate::types::TemporalConfig as TemporalCoordinatorConfig;
7use crate::types::*;
8use dashmap::DashMap;
9use std::sync::Arc;
10use tokio::sync::RwLock;
11
12/// Temporal Coordinator manages temporal relationships without global clocks
13pub struct TemporalCoordinator {
14    /// Per-Resonator local timelines
15    timelines: DashMap<ResonatorId, LocalTimeline>,
16
17    /// Causal graph derived from temporal anchors
18    #[allow(dead_code)]
19    causality_graph: Arc<RwLock<CausalityGraph>>,
20
21    /// Temporal anchor registry
22    anchors: DashMap<AnchorId, TemporalAnchor>,
23
24    /// Configuration
25    #[allow(dead_code)]
26    config: TemporalCoordinatorConfig,
27}
28
29impl TemporalCoordinator {
30    pub fn new(config: &TemporalCoordinatorConfig) -> Self {
31        Self {
32            timelines: DashMap::new(),
33            causality_graph: Arc::new(RwLock::new(CausalityGraph::new())),
34            anchors: DashMap::new(),
35            config: config.clone(),
36        }
37    }
38
39    /// Create a temporal anchor for an event
40    ///
41    /// This enables causal ordering without relying on global clocks.
42    pub fn anchor(&self, event: &ResonanceEvent, resonator: ResonatorId) -> TemporalAnchor {
43        // Get or create timeline for this Resonator
44        let mut timeline = self
45            .timelines
46            .entry(resonator)
47            .or_insert_with(|| LocalTimeline::new());
48
49        let local_time = timeline.next_timestamp();
50
51        let causal_deps = self.compute_causal_dependencies(event);
52
53        let anchor = TemporalAnchor {
54            id: AnchorId::generate(),
55            local_time,
56            causal_deps: causal_deps.clone(),
57            commitment: event.commitment_id(),
58        };
59
60        // Register anchor
61        self.anchors.insert(anchor.id, anchor.clone());
62
63        // Add to causality graph
64        // (would be done asynchronously in real implementation)
65
66        tracing::trace!("Created temporal anchor {} for {}", anchor.id, resonator);
67
68        anchor
69    }
70
71    /// Compute causal dependencies for an event
72    fn compute_causal_dependencies(&self, event: &ResonanceEvent) -> Vec<AnchorId> {
73        // Extract causal dependencies from event context
74        // For now, placeholder
75        event.causal_context().iter().copied().collect()
76    }
77
78    /// Determine causal ordering between events
79    ///
80    /// Returns None if events are concurrent (no causal relationship)
81    pub fn causal_order(
82        &self,
83        a: &TemporalAnchor,
84        b: &TemporalAnchor,
85    ) -> Option<std::cmp::Ordering> {
86        // Check if a happened-before b
87        if self.happened_before(a, b) {
88            return Some(std::cmp::Ordering::Less);
89        }
90
91        // Check if b happened-before a
92        if self.happened_before(b, a) {
93            return Some(std::cmp::Ordering::Greater);
94        }
95
96        // Concurrent (no causal relationship)
97        None
98    }
99
100    /// Check if anchor 'a' happened-before anchor 'b'
101    fn happened_before(&self, a: &TemporalAnchor, b: &TemporalAnchor) -> bool {
102        // a happened-before b if:
103        // 1. a is in b's causal dependencies, OR
104        // 2. There exists c such that a happened-before c and c happened-before b
105
106        if b.causal_deps.contains(&a.id) {
107            return true;
108        }
109
110        // Check transitive dependencies (with cycle detection)
111        // Simplified implementation - real version would use graph traversal
112        for dep_id in &b.causal_deps {
113            if let Some(dep) = self.anchors.get(dep_id) {
114                if self.happened_before(a, &dep) {
115                    return true;
116                }
117            }
118        }
119
120        false
121    }
122
123    /// Get an anchor by ID
124    pub fn get_anchor(&self, id: &AnchorId) -> Option<TemporalAnchor> {
125        self.anchors.get(id).map(|r| r.clone())
126    }
127
128    /// Check if two events are concurrent
129    pub fn are_concurrent(&self, a: &TemporalAnchor, b: &TemporalAnchor) -> bool {
130        self.causal_order(a, b).is_none()
131    }
132}
133
134/// Local timeline for a Resonator
135struct LocalTimeline {
136    current_sequence: u64,
137}
138
139impl LocalTimeline {
140    fn new() -> Self {
141        Self {
142            current_sequence: 0,
143        }
144    }
145
146    fn next_timestamp(&mut self) -> LocalTimestamp {
147        let seq = self.current_sequence;
148        self.current_sequence += 1;
149        LocalTimestamp::with_sequence(seq)
150    }
151}
152
153/// Causality graph for detecting happened-before relationships
154struct CausalityGraph {
155    // Placeholder - in real implementation, would use a proper graph structure
156}
157
158impl CausalityGraph {
159    fn new() -> Self {
160        Self {}
161    }
162}
163
164/// Resonance event for temporal anchoring
165#[derive(Debug, Clone)]
166pub struct ResonanceEvent {
167    causal_context: Vec<AnchorId>,
168    commitment: Option<CommitmentId>,
169}
170
171impl ResonanceEvent {
172    pub fn new() -> Self {
173        Self {
174            causal_context: Vec::new(),
175            commitment: None,
176        }
177    }
178
179    pub fn with_causal_context(mut self, context: Vec<AnchorId>) -> Self {
180        self.causal_context = context;
181        self
182    }
183
184    pub fn with_commitment(mut self, commitment: CommitmentId) -> Self {
185        self.commitment = Some(commitment);
186        self
187    }
188
189    pub fn causal_context(&self) -> &[AnchorId] {
190        &self.causal_context
191    }
192
193    pub fn commitment_id(&self) -> Option<CommitmentId> {
194        self.commitment
195    }
196}
197
198impl Default for ResonanceEvent {
199    fn default() -> Self {
200        Self::new()
201    }
202}