Skip to main content

zeitgeist_protocol/
trajectory.rs

1//! Trajectory tracking via Hurst exponent estimation
2
3use serde::{Deserialize, Serialize};
4
5/// Trend enum
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[repr(u8)]
8pub enum Trend {
9    Stable = 0,
10    Rising = 1,
11    Falling = 2,
12    Chaotic = 3,
13}
14
15impl From<u8> for Trend {
16    fn from(v: u8) -> Self {
17        match v {
18            0 => Trend::Stable,
19            1 => Trend::Rising,
20            2 => Trend::Falling,
21            _ => Trend::Chaotic,
22        }
23    }
24}
25
26/// Trajectory state captures trend direction and momentum
27/// via Hurst exponent estimation.
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
29pub struct TrajectoryState {
30    /// Hurst exponent estimate (0-1)
31    pub hurst: f64,
32    /// Current trend
33    pub trend: Trend,
34    /// Rate of change (velocity)
35    pub velocity: f64,
36}
37
38impl TrajectoryState {
39    pub fn new(hurst: f64, trend: Trend, velocity: f64) -> Self {
40        Self { hurst, trend, velocity }
41    }
42
43    pub fn default() -> Self {
44        Self {
45            hurst: 0.5,
46            trend: Trend::Stable,
47            velocity: 0.0,
48        }
49    }
50
51    /// Check alignment: Hurst must be 0-1
52    pub fn check_alignment(&self) -> Vec<String> {
53        let mut violations = Vec::new();
54        if !(0.0..=1.0).contains(&self.hurst) {
55            violations.push("trajectory.hurst must be 0-1".into());
56        }
57        violations
58    }
59
60    /// Merge: min hurst (conservative), pick dominant trend (Chaotic on disagreement),
61    /// max velocity (most urgent signal). All semilattice operations.
62    pub fn merge(&self, other: &Self) -> Self {
63        Self {
64            hurst: self.hurst.min(other.hurst),
65            trend: if self.trend == other.trend { self.trend } else { Trend::Chaotic },
66            velocity: self.velocity.max(other.velocity),
67        }
68    }
69}