Skip to main content

cortexkit_usage_steps/
open_set.rs

1//! String value sets that a newer provider may extend.
2//!
3//! Each set decodes a value it does not know as `Other`, keeping the exact
4//! string, so an older reader never fails on a newer provider's value and
5//! re-encodes it unchanged.
6
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9macro_rules! open_set {
10    (
11        $(#[$meta:meta])*
12        pub enum $name:ident {
13            $( $(#[$vmeta:meta])* $variant:ident => $wire:literal, )+
14        }
15    ) => {
16        $(#[$meta])*
17        #[derive(Clone, Debug, PartialEq, Eq, Hash)]
18        #[non_exhaustive]
19        pub enum $name {
20            $( $(#[$vmeta])* $variant, )+
21            /// A value this version of the contract does not know, kept
22            /// exactly as received. Build values from strings with
23            /// `from_wire`, so a known string never lands here.
24            Other(String),
25        }
26
27        impl $name {
28            /// Every value this version knows, as sent on the wire.
29            pub const KNOWN: &'static [&'static str] = &[$($wire),+];
30
31            /// Decodes a wire string; an unknown string becomes `Other`.
32            pub fn from_wire(value: &str) -> Self {
33                match value {
34                    $( $wire => Self::$variant, )+
35                    other => Self::Other(other.to_owned()),
36                }
37            }
38
39            /// The wire string.
40            pub fn as_str(&self) -> &str {
41                match self {
42                    $( Self::$variant => $wire, )+
43                    Self::Other(other) => other,
44                }
45            }
46
47            /// Whether this version of the contract knows the value.
48            pub fn is_known(&self) -> bool {
49                !matches!(self, Self::Other(_))
50            }
51        }
52
53        impl Serialize for $name {
54            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
55                serializer.serialize_str(self.as_str())
56            }
57        }
58
59        impl<'de> Deserialize<'de> for $name {
60            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
61                let value = String::deserialize(deserializer)?;
62                Ok(Self::from_wire(&value))
63            }
64        }
65    };
66}
67
68open_set! {
69    /// A step's prompt-cache verdict. The rules that choose it are in
70    /// `CONTRACT.md` and are computed over the step's whole session in time
71    /// order.
72    ///
73    /// `Unknown` is a real verdict: the cache's health cannot be judged for
74    /// this step. `Other` is a value this version does not know (a newer
75    /// verdict); show it as received rather than treating it as `Unknown`.
76    pub enum Verdict {
77        /// The session's first step.
78        ColdStart => "cold_start",
79        /// Retention of at least 0.95, or no usable earlier step to compare.
80        Stable => "stable",
81        /// Retention of at least 0.80 and below 0.95.
82        Warning => "warning",
83        /// Retention below 0.80 with a positive cache read.
84        Bust => "bust",
85        /// A cache read of zero.
86        FullBust => "full_bust",
87        /// The cache's health cannot be judged for this step.
88        Unknown => "unknown",
89    }
90}
91
92open_set! {
93    /// Where the provider learned of a step.
94    pub enum StepSource {
95        /// Read from a harness store or a runner's durable log.
96        File => "file",
97        /// Known so far only from a runner's bus event.
98        Runner => "runner",
99    }
100}
101
102open_set! {
103    /// On a prompt drop, whether the request body shrank compared with the
104    /// earlier step.
105    pub enum RequestSize {
106        /// The current request body is shorter than the earlier step's.
107        Smaller => "smaller",
108        /// The current request body is not shorter.
109        NotSmaller => "not_smaller",
110    }
111}