Skip to main content

noether_store/
lifecycle.rs

1use noether_core::stage::StageLifecycle;
2
3/// Validate a lifecycle transition.
4///
5/// Allowed transitions:
6/// - Draft → Active (stage passes test harness)
7/// - Active → Deprecated (superseded by successor)
8/// - Active → Tombstone (security removal)
9pub fn validate_transition(from: &StageLifecycle, to: &StageLifecycle) -> Result<(), String> {
10    match (from, to) {
11        (StageLifecycle::Draft, StageLifecycle::Active) => Ok(()),
12        (StageLifecycle::Active, StageLifecycle::Deprecated { .. }) => Ok(()),
13        (StageLifecycle::Active, StageLifecycle::Tombstone) => Ok(()),
14        (from, to) => Err(format!("invalid lifecycle transition: {from:?} → {to:?}")),
15    }
16}
17
18#[cfg(test)]
19mod tests {
20    use super::*;
21    use noether_core::stage::StageId;
22
23    #[test]
24    fn valid_transitions() {
25        assert!(validate_transition(&StageLifecycle::Draft, &StageLifecycle::Active).is_ok());
26        assert!(validate_transition(
27            &StageLifecycle::Active,
28            &StageLifecycle::Deprecated {
29                successor_id: StageId("abc".into())
30            }
31        )
32        .is_ok());
33        assert!(validate_transition(&StageLifecycle::Active, &StageLifecycle::Tombstone).is_ok());
34    }
35
36    #[test]
37    fn invalid_transitions() {
38        assert!(validate_transition(&StageLifecycle::Draft, &StageLifecycle::Tombstone).is_err());
39        assert!(validate_transition(
40            &StageLifecycle::Deprecated {
41                successor_id: StageId("x".into())
42            },
43            &StageLifecycle::Active
44        )
45        .is_err());
46        assert!(validate_transition(&StageLifecycle::Tombstone, &StageLifecycle::Active).is_err());
47        assert!(validate_transition(&StageLifecycle::Draft, &StageLifecycle::Draft).is_err());
48    }
49}