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