lean_ctx_protocol/
experiment.rs1use crate::MoneyV1;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub enum ExperimentArm {
7 Control,
8 Optimized,
9 Shadow,
10}
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub struct ExperimentAssignmentV1 {
15 pub experiment_id: String,
16 pub subject_id: String,
17 pub arm: ExperimentArm,
18 pub configuration_ref: String,
19 pub expires_at: String,
20 pub max_incremental_cost: MoneyV1,
21 pub allowed_providers: Vec<String>,
22 pub allowed_models: Vec<String>,
23 pub data_classification: DataClassification,
24 pub side_effect_policy: SideEffectPolicy,
25 pub kill_switch_ref: String,
26 pub signature: String,
27}
28
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub enum DataClassification {
31 Public,
32 Internal,
33 Confidential,
34 Restricted,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38pub enum SideEffectPolicy {
39 NoSideEffects,
40 ReadOnly,
41 AllowWrites,
42}
43
44#[cfg(test)]
45mod tests {
46 use crate::{
47 DataClassification, ExperimentArm, ExperimentAssignmentV1, MoneyV1, SideEffectPolicy,
48 };
49
50 #[test]
51 fn serialization_round_trip() {
52 let assignment = ExperimentAssignmentV1 {
53 experiment_id: "exp-1".to_owned(),
54 subject_id: "subject-1".to_owned(),
55 arm: ExperimentArm::Optimized,
56 configuration_ref: "config:1".to_owned(),
57 expires_at: "2026-01-01T00:00:00Z".to_owned(),
58 max_incremental_cost: MoneyV1 {
59 currency: "USD".to_owned(),
60 coefficient: 25,
61 scale: 4,
62 },
63 allowed_providers: vec!["provider".to_owned()],
64 allowed_models: vec!["model".to_owned()],
65 data_classification: DataClassification::Internal,
66 side_effect_policy: SideEffectPolicy::ReadOnly,
67 kill_switch_ref: "kill:1".to_owned(),
68 signature: "signature".to_owned(),
69 };
70 let json = serde_json::to_string(&assignment).expect("assignment should serialize");
71 let decoded = serde_json::from_str(&json).expect("assignment should deserialize");
72 assert_eq!(assignment, decoded);
73 }
74}