1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9pub type SessionId = String;
11
12pub type TargetCoordinate = String;
14
15pub type EntryId = String;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
20pub enum GestaltType {
21 Manmade,
23 Natural,
25 Movement,
27 Energy,
29 Water,
31 Land,
33}
34
35impl GestaltType {
36 pub fn all() -> &'static [GestaltType] {
38 &[
39 GestaltType::Manmade,
40 GestaltType::Natural,
41 GestaltType::Movement,
42 GestaltType::Energy,
43 GestaltType::Water,
44 GestaltType::Land,
45 ]
46 }
47
48 pub fn index(&self) -> usize {
50 match self {
51 GestaltType::Manmade => 0,
52 GestaltType::Natural => 1,
53 GestaltType::Movement => 2,
54 GestaltType::Energy => 3,
55 GestaltType::Water => 4,
56 GestaltType::Land => 5,
57 }
58 }
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct StageIData {
64 pub stroke: Vec<(f32, f32)>,
66 pub spontaneous_descriptor: String,
68 pub classification: GestaltType,
70 pub confidence: f32,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
76pub enum SensoryModality {
77 Texture,
79 Color,
81 Temperature,
83 Sound,
85 Smell,
87 Taste,
89 Dimension,
91 Luminosity,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize)]
97pub struct StageIIData {
98 pub impressions: Vec<(SensoryModality, String)>,
100 pub feature_vector: Option<Vec<f32>>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct StageIIIData {
107 pub sketch_elements: Vec<SketchElement>,
109 pub relationships: Vec<SpatialRelationship>,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct SketchElement {
116 pub label: String,
118 pub kind: GeometricKind,
120 pub position: (f32, f32),
122 pub scale: Option<f32>,
124}
125
126#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
128pub enum GeometricKind {
129 Point,
130 Line,
131 Curve,
132 Rectangle,
133 Circle,
134 Triangle,
135 Polygon,
136 Freeform,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct SpatialRelationship {
142 pub from: String,
144 pub to: String,
146 pub relation: SpatialRelationType,
148 pub strength: f32,
150}
151
152#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
154pub enum SpatialRelationType {
155 Adjacent,
156 Contains,
157 Above,
158 Below,
159 Inside,
160 Surrounding,
161 Connected,
162 Separated,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct StageIVData {
168 pub emotional_impact: Vec<(String, f32)>,
170 pub tangibles: Vec<String>,
172 pub intangibles: Vec<String>,
174 pub aol_detections: Vec<AOLDetection>,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct AOLDetection {
185 pub content: String,
187 pub timestamp_ms: u64,
189 pub flagged: bool,
191 pub anomaly_score: f32,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct StageVData {
199 pub probes: Vec<SignalLineProbe>,
201 pub cross_references: Vec<CrossReference>,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct SignalLineProbe {
208 pub query: String,
210 pub target_stage: u8,
212 pub attention_weights: Vec<f32>,
214 pub top_candidates: Vec<usize>,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct CrossReference {
221 pub from_stage: u8,
223 pub from_entry: usize,
225 pub to_stage: u8,
227 pub to_entry: usize,
229 pub score: f32,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct StageVIData {
236 pub partitions: Vec<TargetPartition>,
238 pub composite_description: String,
240 pub partition_confidence: Vec<f32>,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct TargetPartition {
247 pub label: String,
249 pub member_entries: Vec<(u8, usize)>,
251 pub centroid: Vec<f32>,
253 pub separation_strength: f32,
255}
256
257#[derive(Debug, Clone, Serialize, Deserialize)]
259pub struct CrvSessionEntry {
260 pub session_id: SessionId,
262 pub coordinate: TargetCoordinate,
264 pub stage: u8,
266 pub embedding: Vec<f32>,
268 pub metadata: HashMap<String, serde_json::Value>,
270 pub timestamp_ms: u64,
272}
273
274#[derive(Debug, Clone, Serialize, Deserialize)]
276pub struct CrvConfig {
277 pub dimensions: usize,
279 pub curvature: f32,
281 pub aol_threshold: f32,
283 pub refractory_period_ms: f64,
285 pub snn_dt: f64,
287 pub search_temperature: f32,
289 pub convergence_threshold: f32,
291}
292
293impl Default for CrvConfig {
294 fn default() -> Self {
295 Self {
296 dimensions: 384,
297 curvature: 1.0,
298 aol_threshold: 0.7,
299 refractory_period_ms: 50.0,
300 snn_dt: 1.0,
301 search_temperature: 1.0,
302 convergence_threshold: 0.75,
303 }
304 }
305}
306
307#[derive(Debug, Clone, Serialize, Deserialize)]
309pub struct ConvergenceResult {
310 pub session_pairs: Vec<(SessionId, SessionId)>,
312 pub scores: Vec<f32>,
314 pub convergent_stages: Vec<u8>,
316 pub consensus_embedding: Option<Vec<f32>>,
318}
319
320#[cfg(test)]
321mod tests {
322 use super::*;
323
324 #[test]
325 fn test_gestalt_type_all() {
326 let all = GestaltType::all();
327 assert_eq!(all.len(), 6);
328 }
329
330 #[test]
331 fn test_gestalt_type_index() {
332 assert_eq!(GestaltType::Manmade.index(), 0);
333 assert_eq!(GestaltType::Land.index(), 5);
334 }
335
336 #[test]
337 fn test_default_config() {
338 let config = CrvConfig::default();
339 assert_eq!(config.dimensions, 384);
340 assert_eq!(config.curvature, 1.0);
341 assert_eq!(config.aol_threshold, 0.7);
342 }
343
344 #[test]
345 fn test_session_entry_serialization() {
346 let entry = CrvSessionEntry {
347 session_id: "sess-001".to_string(),
348 coordinate: "1234-5678".to_string(),
349 stage: 1,
350 embedding: vec![0.1, 0.2, 0.3],
351 metadata: HashMap::new(),
352 timestamp_ms: 1000,
353 };
354
355 let json = serde_json::to_string(&entry).unwrap();
356 let deserialized: CrvSessionEntry = serde_json::from_str(&json).unwrap();
357 assert_eq!(deserialized.session_id, "sess-001");
358 assert_eq!(deserialized.stage, 1);
359 }
360}