maple_runtime/types/presence.rs
1//! Presence state types
2//!
3//! Presence is NOT binary (online/offline). It's a gradient.
4
5use super::temporal::TemporalAnchor;
6use serde::{Deserialize, Serialize};
7
8/// Presence state - gradient representation of a Resonator's availability
9///
10/// Key insight: Presence is multidimensional, not a simple boolean.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct PresenceState {
13 /// How discoverable is this Resonator? (0.0 to 1.0)
14 ///
15 /// 0.0 = Completely hidden
16 /// 0.5 = Discoverable only through existing couplings
17 /// 1.0 = Fully discoverable to all
18 pub discoverability: f64,
19
20 /// How responsive is this Resonator? (0.0 to 1.0)
21 ///
22 /// 0.0 = Not responding to interactions
23 /// 0.5 = Slow/delayed responses
24 /// 1.0 = Immediate responses
25 pub responsiveness: f64,
26
27 /// How stable has this Resonator been? (rolling average)
28 ///
29 /// 0.0 = Frequently disconnecting
30 /// 1.0 = Consistently available
31 pub stability: f64,
32
33 /// How ready is this Resonator to form new couplings? (0.0 to 1.0)
34 ///
35 /// 0.0 = Not accepting new couplings
36 /// 1.0 = Actively seeking new couplings
37 pub coupling_readiness: f64,
38
39 /// Last presence signal (temporal anchor)
40 pub last_signal: TemporalAnchor,
41
42 /// Silent mode (exists but not actively signaling)
43 ///
44 /// Important: A Resonator may be present without actively participating.
45 /// Presence does NOT imply willingness to interact.
46 pub silent_mode: bool,
47}
48
49impl PresenceState {
50 /// Create a new presence state with default values
51 pub fn new() -> Self {
52 Self {
53 discoverability: 0.5,
54 responsiveness: 1.0,
55 stability: 1.0,
56 coupling_readiness: 0.7,
57 last_signal: TemporalAnchor::now(),
58 silent_mode: false,
59 }
60 }
61
62 /// Is this Resonator effectively "online"?
63 ///
64 /// Note: This is a convenience method. Presence is a gradient,
65 /// not a binary state.
66 pub fn is_effectively_online(&self) -> bool {
67 !self.silent_mode && self.responsiveness > 0.3 && self.stability > 0.3
68 }
69
70 /// Can this Resonator be discovered?
71 pub fn is_discoverable(&self) -> bool {
72 self.discoverability > 0.1
73 }
74
75 /// Is this Resonator accepting new couplings?
76 pub fn is_accepting_couplings(&self) -> bool {
77 self.coupling_readiness > 0.3 && !self.silent_mode
78 }
79}
80
81impl Default for PresenceState {
82 fn default() -> Self {
83 Self::new()
84 }
85}
86
87/// Configuration for presence behavior
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct PresenceConfig {
90 /// Initial discoverability
91 pub initial_discoverability: f64,
92
93 /// Initial responsiveness
94 pub initial_responsiveness: f64,
95
96 /// Enable silent mode by default?
97 pub start_silent: bool,
98
99 /// Maximum signal frequency (to prevent spam)
100 pub max_signal_frequency_ms: u64,
101}
102
103impl Default for PresenceConfig {
104 fn default() -> Self {
105 Self {
106 initial_discoverability: 0.5,
107 initial_responsiveness: 1.0,
108 start_silent: false,
109 max_signal_frequency_ms: 1000,
110 }
111 }
112}