wasm4pm 26.6.10

High-performance process mining algorithms in WebAssembly for JavaScript/TypeScript
Documentation
//! Lifecycle State Machine module — synthesized by ggen manufacturing machinery
//!
//! This module implements the complete process intelligence lifecycle with autonomic
//! state transitions, quality gates, and MAPE-K loop integration.
//!
//! Generated from: templates/lifecycle/state_machine.rs.j2
//! License: Executable only under wasm4pm graduation bridge
//! Authority: Blue River Dam Doctrine, Process Intelligence Research Foundry
//!
//! Lifecycle States
//!
//! The lifecycle implements 13 interconnected states spanning the complete process
//! intelligence feedback loop:
//!
//! - Design: Knowledge & Plan phases (structural design, soundness verification)
//! - Simulation: Analyze phase (behavioral bounds, state space exploration)
//! - Construction: Plan & Execute phases (WASM compilation, unit testing)
//! - Activation: Execute & Plan phases (go-live validation, system binding)
//! - Operation: Monitor & Execute phases (live transaction processing)
//! - Monitoring: Monitor phase (conformance auditing, anomaly detection)
//! - Repair: Execute phase (autonomic corrections, deadlock resolution)
//! - Optimization: Analyze & Plan phases (process debt reduction, discovery)
//! - BoardProjection: Knowledge & Plan phases (executive dashboarding)
//! - Decommission: Execute & Knowledge phases (safe retirement, archival)
//! - Acquisition: Knowledge & Plan phases (pre-merger ingestion)
//! - Integration: Execute phase (post-merger enterprise binding)
//! - Archive: Knowledge phase (cold data storage, historical audit)

// Use core wasm4pm types and models (HashMap used in LifecycleStateMachine)
use std::collections::HashMap;

/// Lifecycle state enumeration
///
/// These states form a directed acyclic graph (DAG) of valid transitions,
/// enforced by the Blue River Dam quality gates. No illegal transitions are
/// possible at the type level.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum LifecycleState {
    /// Design: Model creation and structural soundness verification
    Design = 0,
    /// Simulation: Behavioral bounds and state-space validation
    Simulation = 1,
    /// Construction: WASM bytecode compilation and unit testing
    Construction = 2,
    /// Activation: Go-live validation and system binding
    Activation = 3,
    /// Operation: Live transaction processing and enforcement
    Operation = 4,
    /// Monitoring: Conformance auditing and metric computation
    Monitoring = 5,
    /// Repair: Autonomic corrections and deadlock resolution
    Repair = 6,
    /// Optimization: Process debt reduction via discovery
    Optimization = 7,
    /// BoardProjection: Executive dashboard and claim translation
    BoardProjection = 8,
    /// Decommission: Safe retirement and cryptographic archival
    Decommission = 9,
    /// Acquisition: Pre-merger target ingestion
    Acquisition = 10,
    /// Integration: Post-merger enterprise binding
    Integration = 11,
    /// Archive: Cold storage and historical audit retention
    Archive = 12,
}

impl LifecycleState {
    /// Convert state to human-readable name
    pub fn name(&self) -> &'static str {
        match self {
            LifecycleState::Design => "Design",
            LifecycleState::Simulation => "Simulation",
            LifecycleState::Construction => "Construction",
            LifecycleState::Activation => "Activation",
            LifecycleState::Operation => "Operation",
            LifecycleState::Monitoring => "Monitoring",
            LifecycleState::Repair => "Repair",
            LifecycleState::Optimization => "Optimization",
            LifecycleState::BoardProjection => "BoardProjection",
            LifecycleState::Decommission => "Decommission",
            LifecycleState::Acquisition => "Acquisition",
            LifecycleState::Integration => "Integration",
            LifecycleState::Archive => "Archive",
        }
    }

    /// Check if this state is terminal (no outgoing transitions)
    pub fn is_terminal(&self) -> bool {
        matches!(self, LifecycleState::Archive)
    }

    /// Get all valid next states from current state
    pub fn valid_transitions(&self) -> &'static [LifecycleState] {
        match self {
            LifecycleState::Design => &[LifecycleState::Simulation],
            LifecycleState::Simulation => &[LifecycleState::Construction, LifecycleState::Design],
            LifecycleState::Construction => &[LifecycleState::Activation, LifecycleState::Design],
            LifecycleState::Activation => &[LifecycleState::Operation],
            LifecycleState::Operation => &[
                LifecycleState::Monitoring,
                LifecycleState::Repair,
                LifecycleState::Optimization,
            ],
            LifecycleState::Monitoring => &[
                LifecycleState::Repair,
                LifecycleState::Optimization,
                LifecycleState::Decommission,
            ],
            LifecycleState::Repair => &[LifecycleState::Operation, LifecycleState::Optimization],
            LifecycleState::Optimization => {
                &[LifecycleState::Operation, LifecycleState::Decommission]
            }
            LifecycleState::BoardProjection => {
                &[LifecycleState::Optimization, LifecycleState::Decommission]
            }
            LifecycleState::Decommission => &[LifecycleState::Archive],
            LifecycleState::Acquisition => &[LifecycleState::Design, LifecycleState::Simulation],
            LifecycleState::Integration => &[LifecycleState::Operation],
            LifecycleState::Archive => &[],
        }
    }
}

impl std::fmt::Display for LifecycleState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.name())
    }
}

/// Blue River Dam quality gate for state transitions
#[derive(Debug, Clone)]
pub struct QualityGate {
    /// Gate identifier
    pub name: String,
    /// Gate criterion (human-readable description)
    pub criterion: String,
    /// Whether gate has been passed
    pub passed: bool,
    /// Evidence artifacts supporting gate passage
    pub evidence: Vec<String>,
}

impl QualityGate {
    /// Create a new quality gate
    pub fn new(name: impl Into<String>, criterion: impl Into<String>) -> Self {
        QualityGate {
            name: name.into(),
            criterion: criterion.into(),
            passed: false,
            evidence: Vec::new(),
        }
    }

    /// Mark gate as passed with supporting evidence
    pub fn pass_with_evidence(&mut self, evidence: impl Into<String>) {
        self.passed = true;
        self.evidence.push(evidence.into());
    }
}

/// Lifecycle state machine with type-safe transitions
pub struct LifecycleStateMachine {
    /// Current state
    state: LifecycleState,
    /// Quality gates for transition validation
    gates: std::collections::HashMap<String, QualityGate>,
    /// Event log (witness trail)
    events: Vec<(String, LifecycleState, u64)>,
}

impl LifecycleStateMachine {
    /// Create a new lifecycle state machine (always starts in Design)
    pub fn new() -> Self {
        LifecycleStateMachine {
            state: LifecycleState::Design,
            gates: std::collections::HashMap::new(),
            events: Vec::new(),
        }
    }

    /// Get current state
    pub fn current(&self) -> LifecycleState {
        self.state
    }

    /// Attempt a state transition
    ///
    /// Returns Ok(new_state) if transition is valid, Err(refusal) otherwise.
    pub fn transition(
        &mut self,
        target: LifecycleState,
        witness: &str,
    ) -> Result<LifecycleState, LifecycleRefusal> {
        // Check if target is in valid transitions
        if !self.state.valid_transitions().contains(&target) {
            return Err(LifecycleRefusal::InvalidTransition {
                from: self.state,
                to: target,
            });
        }

        // Record event
        let timestamp = 0u64;
        self.events.push((witness.to_string(), target, timestamp));

        self.state = target;
        Ok(target)
    }

    /// Get all enabled transitions from current state
    pub fn enabled_transitions(&self) -> &'static [LifecycleState] {
        self.state.valid_transitions()
    }

    /// Get event log
    pub fn event_log(&self) -> &[(String, LifecycleState, u64)] {
        &self.events
    }

    /// Register a quality gate
    pub fn register_gate(&mut self, gate: QualityGate) {
        self.gates.insert(gate.name.clone(), gate);
    }

    /// Check if a gate has been passed
    pub fn gate_passed(&self, gate_name: &str) -> bool {
        self.gates.get(gate_name).map(|g| g.passed).unwrap_or(false)
    }
}

impl Default for LifecycleStateMachine {
    fn default() -> Self {
        Self::new()
    }
}

/// Refusal reasons for invalid state transitions
#[derive(Debug, Clone)]
pub enum LifecycleRefusal {
    /// Transition not defined in Blue River Dam specification
    InvalidTransition {
        from: LifecycleState,
        to: LifecycleState,
    },
    /// Quality gate not passed
    GateNotPassed(String),
    /// Process model not sound (WF-net violation)
    SoundnessViolation,
    /// Process contains deadlock
    DeadlockDetected,
    /// Conformance fitness below threshold
    ConformanceViolation(f64),
}

impl std::fmt::Display for LifecycleRefusal {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::InvalidTransition { from, to } => {
                write!(f, "Invalid transition: {} -> {}", from.name(), to.name())
            }
            Self::GateNotPassed(gate) => write!(f, "Quality gate not passed: {}", gate),
            Self::SoundnessViolation => write!(f, "WF-net soundness violation"),
            Self::DeadlockDetected => write!(f, "Deadlock detected in reachability graph"),
            Self::ConformanceViolation(fitness) => {
                write!(f, "Conformance fitness below threshold: {}", fitness)
            }
        }
    }
}

/// MAPE-K loop phase mapping for each lifecycle state
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MAPEKPhase {
    /// Monitor: Observe system behavior
    Monitor,
    /// Analyze: Diagnose root causes
    Analyze,
    /// Plan: Create action sequences
    Plan,
    /// Execute: Actuate changes
    Execute,
    /// Knowledge: Persist learnings
    Knowledge,
}

impl LifecycleState {
    /// Get primary MAPE-K phases for this state
    pub fn mape_k_phases(&self) -> &'static [MAPEKPhase] {
        match self {
            LifecycleState::Design => &[MAPEKPhase::Knowledge, MAPEKPhase::Plan],
            LifecycleState::Simulation => &[MAPEKPhase::Analyze],
            LifecycleState::Construction => &[MAPEKPhase::Plan, MAPEKPhase::Execute],
            LifecycleState::Activation => &[MAPEKPhase::Execute, MAPEKPhase::Plan],
            LifecycleState::Operation => &[MAPEKPhase::Monitor, MAPEKPhase::Execute],
            LifecycleState::Monitoring => &[MAPEKPhase::Monitor],
            LifecycleState::Repair => &[MAPEKPhase::Execute],
            LifecycleState::Optimization => &[MAPEKPhase::Analyze, MAPEKPhase::Plan],
            LifecycleState::BoardProjection => &[MAPEKPhase::Knowledge, MAPEKPhase::Plan],
            LifecycleState::Decommission => &[MAPEKPhase::Execute, MAPEKPhase::Knowledge],
            LifecycleState::Acquisition => &[MAPEKPhase::Knowledge, MAPEKPhase::Plan],
            LifecycleState::Integration => &[MAPEKPhase::Execute],
            LifecycleState::Archive => &[MAPEKPhase::Knowledge],
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_state_transitions_are_sound() {
        // Design -> Simulation -> Construction -> Activation -> Operation is a valid path
        let mut sm = LifecycleStateMachine::new();
        assert_eq!(sm.current(), LifecycleState::Design);

        sm.transition(LifecycleState::Simulation, "gate_1_passed")
            .unwrap();
        assert_eq!(sm.current(), LifecycleState::Simulation);

        sm.transition(LifecycleState::Construction, "gate_2_passed")
            .unwrap();
        assert_eq!(sm.current(), LifecycleState::Construction);

        sm.transition(LifecycleState::Activation, "compilation_success")
            .unwrap();
        assert_eq!(sm.current(), LifecycleState::Activation);

        sm.transition(LifecycleState::Operation, "alive_checkpoint_passed")
            .unwrap();
        assert_eq!(sm.current(), LifecycleState::Operation);
    }

    #[test]
    fn test_invalid_transitions_rejected() {
        let mut sm = LifecycleStateMachine::new();

        // Cannot jump directly from Design to Operation
        let result = sm.transition(LifecycleState::Operation, "invalid");
        assert!(result.is_err());
        assert_eq!(sm.current(), LifecycleState::Design);
    }

    #[test]
    fn test_enabled_transitions() {
        let mut sm = LifecycleStateMachine::new();
        let enabled = sm.enabled_transitions();
        assert_eq!(enabled, &[LifecycleState::Simulation]);

        // Move to Simulation
        sm.transition(LifecycleState::Simulation, "test").unwrap();
        let enabled = sm.enabled_transitions();
        assert!(enabled.contains(&LifecycleState::Construction));
        assert!(enabled.contains(&LifecycleState::Design));
    }

    #[test]
    fn test_decommission_is_terminal() {
        assert!(LifecycleState::Archive.is_terminal());
        assert!(!LifecycleState::Design.is_terminal());
        assert!(!LifecycleState::Operation.is_terminal());
    }

    #[test]
    fn test_mape_k_mappings() {
        // Design should map to Knowledge and Plan
        let phases = LifecycleState::Design.mape_k_phases();
        assert!(phases.contains(&MAPEKPhase::Knowledge));
        assert!(phases.contains(&MAPEKPhase::Plan));

        // Operation should map to Monitor and Execute
        let phases = LifecycleState::Operation.mape_k_phases();
        assert!(phases.contains(&MAPEKPhase::Monitor));
        assert!(phases.contains(&MAPEKPhase::Execute));
    }
}