Skip to main content

scirs2_core/stability/
advanced_implementations.rs

1//! Advanced implementations for the stability framework
2//!
3//! This module contains the implementation details for formal verification,
4//! runtime validation, performance modeling, and cryptographic audit trails.
5
6use super::*;
7use crate::performance_optimization::PerformanceMetrics;
8use std::collections::hash_map::DefaultHasher;
9use std::hash::Hasher;
10use std::sync::atomic::{AtomicUsize, Ordering};
11use std::thread;
12
13/// A concrete, runnable measurement of the API under verification.
14///
15/// [`FormalVerificationEngine::verify_contract`] cannot confirm a
16/// contract's performance/memory/thread-safety bounds against nothing:
17/// those are runtime properties of actually *calling* the API. Without a
18/// probe, verification honestly reports [`VerificationStatus::NotVerified`]
19/// (via a `verified: false` [`VerificationResult`]) rather than fabricating
20/// a pass.
21pub struct VerificationProbe {
22    /// Invokes the API under test once, returning the wall-clock duration
23    /// of the call and, if determinable, the net memory-usage delta caused
24    /// by the call (in bytes). Measuring a memory delta is inherently
25    /// caller-specific (e.g. via an allocator hook or process RSS sample),
26    /// so `None` is an honest "not measured" rather than a fabricated zero.
27    pub invoke: Box<dyn Fn() -> (Duration, Option<usize>) + Send + Sync>,
28    /// Number of sequential invocations used to build the timing/memory
29    /// sample; the *maximum* observed value is compared against the
30    /// contract (a conservative choice for a safety bound).
31    pub iterations: usize,
32    /// Number of concurrent threads used for the thread-safety smoke test
33    /// when the contract claims `ThreadSafety::ThreadSafe`. `0` or `1`
34    /// disables the concurrent check.
35    pub concurrency: usize,
36}
37
38impl VerificationProbe {
39    /// Convenience constructor for a single-threaded, single-iteration
40    /// probe that does not report a memory measurement.
41    pub fn from_timing(invoke: impl Fn() + Send + Sync + 'static) -> Self {
42        Self {
43            invoke: Box::new(move || {
44                let start = Instant::now();
45                invoke();
46                (start.elapsed(), None)
47            }),
48            iterations: 1,
49            concurrency: 1,
50        }
51    }
52}
53
54/// Best-effort extraction of a human-readable message from a caught panic
55/// payload (as produced by `std::panic::catch_unwind`).
56fn panic_payload_to_string(payload: &(dyn std::any::Any + Send)) -> String {
57    if let Some(s) = payload.downcast_ref::<&str>() {
58        (*s).to_string()
59    } else if let Some(s) = payload.downcast_ref::<String>() {
60        s.clone()
61    } else {
62        "<non-string panic payload>".to_string()
63    }
64}
65
66impl Default for FormalVerificationEngine {
67    fn default() -> Self {
68        Self::new()
69    }
70}
71
72impl FormalVerificationEngine {
73    /// Create a new formal verification engine
74    pub fn new() -> Self {
75        Self {
76            verification_tasks: Arc::new(Mutex::new(HashMap::new())),
77            results_cache: Arc::new(RwLock::new(HashMap::new())),
78        }
79    }
80
81    /// Start formal verification for an API contract.
82    ///
83    /// `probe` supplies a real, runnable measurement of the API under
84    /// test. Without one, none of the contract's performance/memory/
85    /// thread-safety bounds can be honestly confirmed, so verification
86    /// completes with `VerificationStatus::Failed` and a `verified: false`
87    /// result explaining why — never a fabricated `Verified`. With a
88    /// probe, the bounds declared in `contract` are checked against real
89    /// measurements (see the private `perform_verification` method below).
90    pub fn verify_contract(
91        &self,
92        contract: &ApiContract,
93        probe: Option<VerificationProbe>,
94    ) -> CoreResult<()> {
95        let taskid = format!("{}-{}", contract.module, contract.apiname);
96
97        let properties = self.extract_verification_properties(contract);
98
99        let task = VerificationTask {
100            apiname: contract.apiname.clone(),
101            module: contract.module.clone(),
102            properties: properties.clone(),
103            status: VerificationStatus::InProgress,
104            started_at: Instant::now(),
105        };
106
107        {
108            let mut tasks = self.verification_tasks.lock().expect("Operation failed");
109            tasks.insert(taskid.clone(), task);
110        }
111
112        // Spawn a background thread so a slow probe (many iterations, or a
113        // concurrent thread-safety smoke test) never blocks the caller.
114        let tasks_clone = Arc::clone(&self.verification_tasks);
115        let results_clone = Arc::clone(&self.results_cache);
116        let performance = contract.performance.clone();
117        let memory = contract.memory.clone();
118        let thread_safety = contract.concurrency.thread_safety;
119
120        thread::spawn(move || {
121            let result = Self::perform_verification(
122                &properties,
123                &performance,
124                &memory,
125                thread_safety,
126                probe,
127            );
128            let verified = result.verified;
129
130            // Store result
131            {
132                let mut results = results_clone.write().expect("Operation failed");
133                results.insert(taskid.clone(), result);
134            }
135
136            // Update task status: honestly reflect whether verification
137            // actually confirmed the contract, rather than always marking
138            // `Verified`.
139            {
140                let mut tasks = tasks_clone.lock().expect("Operation failed");
141                if let Some(task) = tasks.get_mut(&taskid) {
142                    task.status = if verified {
143                        VerificationStatus::Verified
144                    } else {
145                        VerificationStatus::Failed
146                    };
147                }
148            }
149        });
150
151        Ok(())
152    }
153
154    /// Extract verification properties from contract
155    fn extract_verification_properties(&self, contract: &ApiContract) -> Vec<VerificationProperty> {
156        let mut properties = Vec::new();
157
158        // Performance properties
159        properties.push(VerificationProperty {
160            name: "performance_bound".to_string(),
161            specification: format!(
162                "execution_time <= {:?}",
163                contract
164                    .performance
165                    .maxexecution_time
166                    .unwrap_or(Duration::from_secs(1))
167            ),
168            property_type: PropertyType::Safety,
169        });
170
171        // Memory properties
172        if let Some(max_memory) = contract.memory.max_memory {
173            properties.push(VerificationProperty {
174                name: "memory_bound".to_string(),
175                specification: format!("memory_usage <= {max_memory}"),
176                property_type: PropertyType::Safety,
177            });
178        }
179
180        // Thread safety properties
181        if contract.concurrency.thread_safety == ThreadSafety::ThreadSafe {
182            properties.push(VerificationProperty {
183                name: "thread_safety".to_string(),
184                specification: "no_race_conditions AND no_deadlocks".to_string(),
185                property_type: PropertyType::Safety,
186            });
187        }
188
189        properties
190    }
191
192    /// Get verification status for an API
193    pub fn get_verification_status(&self, apiname: &str, module: &str) -> VerificationStatus {
194        let taskid = format!("{module}-{apiname}");
195
196        if let Ok(tasks) = self.verification_tasks.lock() {
197            if let Some(task) = tasks.get(&taskid) {
198                return task.status;
199            }
200        }
201
202        VerificationStatus::NotVerified
203    }
204
205    /// Get all verification results
206    pub fn get_all_results(&self) -> HashMap<String, VerificationResult> {
207        if let Ok(results) = self.results_cache.read() {
208            results.clone()
209        } else {
210            HashMap::new()
211        }
212    }
213
214    /// Check if verification is complete for an API
215    pub fn is_verification_complete(&self, apiname: &str, module: &str) -> bool {
216        matches!(
217            self.get_verification_status(apiname, module),
218            VerificationStatus::Verified | VerificationStatus::Failed
219        )
220    }
221
222    /// Get verification coverage percentage
223    pub fn get_verification_coverage(&self) -> f64 {
224        if let Ok(tasks) = self.verification_tasks.lock() {
225            if tasks.is_empty() {
226                return 0.0;
227            }
228
229            let verified_count = tasks
230                .values()
231                .filter(|task| task.status == VerificationStatus::Verified)
232                .count();
233
234            (verified_count as f64 / tasks.len() as f64) * 100.0
235        } else {
236            0.0
237        }
238    }
239
240    /// Actually check `properties` against real measurements taken from
241    /// `probe`.
242    ///
243    /// Without a probe, nothing was executed, so none of the declared
244    /// bounds can be confirmed: this honestly returns `verified: false`
245    /// with an explanatory counterexample rather than the previous
246    /// unconditional `verified: true`. This crate has no formal-methods
247    /// backend (no CBMC/KLEE/model-checker integration, and adding one is
248    /// out of scope for a general-purpose core utility crate); what *is*
249    /// tractable — and implemented here — is checking the contract's own
250    /// numeric bounds against a real invocation of the API.
251    fn perform_verification(
252        properties: &[VerificationProperty],
253        performance: &PerformanceContract,
254        memory: &MemoryContract,
255        thread_safety: ThreadSafety,
256        probe: Option<VerificationProbe>,
257    ) -> VerificationResult {
258        let start_time = Instant::now();
259
260        let Some(probe) = probe else {
261            return VerificationResult {
262                verified: false,
263                verification_time: start_time.elapsed(),
264                checked_properties: vec![],
265                counterexample: Some(format!(
266                    "no VerificationProbe was supplied: {} declared propert{} could not be \
267                     executed against a real workload and so cannot be confirmed",
268                    properties.len(),
269                    if properties.len() == 1 { "y" } else { "ies" }
270                )),
271                method: VerificationMethod::StaticAnalysis,
272            };
273        };
274
275        // Measure the real API under test. A probe that panics is itself a
276        // genuine finding (the API under test is not safe to call) and
277        // must be caught here: left uncaught, it would unwind straight out
278        // of the background thread `verify_contract` spawned to run this
279        // function, which would silently abandon the task in `InProgress`
280        // forever (nothing left running to ever update its status).
281        let iterations = probe.iterations.max(1);
282        let mut max_elapsed = Duration::ZERO;
283        let mut max_memory_delta: Option<usize> = None;
284        let mut probe_panic_message: Option<String> = None;
285        for _ in 0..iterations {
286            match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| (probe.invoke)())) {
287                Ok((elapsed, memory_delta)) => {
288                    max_elapsed = max_elapsed.max(elapsed);
289                    if let Some(delta) = memory_delta {
290                        max_memory_delta =
291                            Some(max_memory_delta.map_or(delta, |current| current.max(delta)));
292                    }
293                }
294                Err(payload) => {
295                    probe_panic_message = Some(panic_payload_to_string(&payload));
296                    break;
297                }
298            }
299        }
300
301        if let Some(message) = probe_panic_message {
302            return VerificationResult {
303                verified: false,
304                verification_time: start_time.elapsed(),
305                checked_properties: vec![],
306                counterexample: Some(format!(
307                    "the supplied probe panicked during measurement: {message}"
308                )),
309                method: VerificationMethod::SymbolicExecution,
310            };
311        }
312
313        let mut checked_properties = Vec::new();
314        let mut counterexamples = Vec::new();
315
316        for property in properties {
317            match property.name.as_str() {
318                "performance_bound" => {
319                    checked_properties.push(property.name.clone());
320                    if let Some(bound) = performance.maxexecution_time {
321                        if max_elapsed > bound {
322                            counterexamples.push(format!(
323                                "performance_bound violated: measured max execution time \
324                                 {max_elapsed:?} exceeds the contract bound {bound:?} (over \
325                                 {iterations} iteration(s))"
326                            ));
327                        }
328                    }
329                }
330                "memory_bound" => {
331                    checked_properties.push(property.name.clone());
332                    match (memory.max_memory, max_memory_delta) {
333                        (Some(bound), Some(delta)) if delta > bound => {
334                            counterexamples.push(format!(
335                                "memory_bound violated: measured memory delta {delta} bytes \
336                                 exceeds the contract bound {bound} bytes"
337                            ));
338                        }
339                        (Some(_), None) => {
340                            counterexamples.push(
341                                "memory_bound could not be confirmed: the supplied probe never \
342                                 reported a memory measurement"
343                                    .to_string(),
344                            );
345                        }
346                        _ => {}
347                    }
348                }
349                "thread_safety" => {
350                    checked_properties.push(property.name.clone());
351                    if thread_safety == ThreadSafety::ThreadSafe && probe.concurrency > 1 {
352                        if let Some(failure) = Self::concurrent_smoke_test(&probe) {
353                            counterexamples.push(failure);
354                        }
355                    }
356                }
357                _ => {}
358            }
359        }
360
361        let verified = counterexamples.is_empty();
362        VerificationResult {
363            verified,
364            verification_time: start_time.elapsed(),
365            checked_properties,
366            counterexample: if counterexamples.is_empty() {
367                None
368            } else {
369                Some(counterexamples.join("; "))
370            },
371            // `SymbolicExecution` is the closest available label for "the
372            // API was actually invoked and measured" (as opposed to the
373            // purely-static techniques in this enum); it is concrete
374            // rather than symbolic execution, but no better-fitting
375            // variant exists.
376            method: VerificationMethod::SymbolicExecution,
377        }
378    }
379
380    /// Runs `probe.invoke` concurrently across `probe.concurrency` threads
381    /// (each performing `probe.iterations` calls) and reports a failure
382    /// message if any worker panics — a real, if coarse, signal that a
383    /// `ThreadSafe` claim does not hold — or if the workers do not all
384    /// complete within a generous timeout (a suspected deadlock/hang).
385    fn concurrent_smoke_test(probe: &VerificationProbe) -> Option<String> {
386        const TIMEOUT: Duration = Duration::from_secs(10);
387
388        let concurrency = probe.concurrency.max(1);
389        let iterations_per_thread = probe.iterations.max(1);
390        let invoke = &probe.invoke;
391        let panic_count = AtomicUsize::new(0);
392        let (tx, rx) = mpsc::channel::<()>();
393
394        thread::scope(|scope| {
395            for _ in 0..concurrency {
396                let tx = tx.clone();
397                let panic_count = &panic_count;
398                scope.spawn(move || {
399                    for _ in 0..iterations_per_thread {
400                        let outcome =
401                            std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
402                                (invoke)();
403                            }));
404                        if outcome.is_err() {
405                            panic_count.fetch_add(1, Ordering::SeqCst);
406                        }
407                    }
408                    let _ = tx.send(());
409                });
410            }
411            drop(tx);
412
413            let deadline = Instant::now() + TIMEOUT;
414            let mut completed = 0usize;
415            while completed < concurrency {
416                let remaining = deadline.saturating_duration_since(Instant::now());
417                if remaining.is_zero() {
418                    break;
419                }
420                match rx.recv_timeout(remaining) {
421                    Ok(()) => completed += 1,
422                    Err(_) => break,
423                }
424            }
425
426            if completed < concurrency {
427                return Some(format!(
428                    "thread_safety smoke test timed out: only {completed}/{concurrency} worker \
429                     thread(s) completed within {TIMEOUT:?} (suspected deadlock/hang)"
430                ));
431            }
432
433            let panics = panic_count.load(Ordering::SeqCst);
434            if panics > 0 {
435                return Some(format!(
436                    "thread_safety smoke test failed: {panics} panic(s) observed across \
437                     {concurrency} concurrent thread(s) x {iterations_per_thread} iteration(s)"
438                ));
439            }
440
441            None
442        })
443    }
444}
445
446impl RuntimeContractValidator {
447    /// Create a new runtime contract validator
448    pub fn new() -> (Self, Receiver<MonitoringEvent>) {
449        let (sender, receiver) = mpsc::channel();
450
451        let validator = Self {
452            contracts: Arc::new(RwLock::new(HashMap::new())),
453            event_sender: sender,
454            stats: Arc::new(Mutex::new(ValidationStatistics {
455                total_validations: 0,
456                violations_detected: 0,
457                avg_validation_time: Duration::from_nanos(0),
458                success_rate: 1.0,
459            })),
460            chaos_controller: Arc::new(Mutex::new(ChaosEngineeringController {
461                enabled: false,
462                faultprobability: 0.01,
463                active_faults: Vec::new(),
464                fault_history: Vec::new(),
465            })),
466        };
467
468        (validator, receiver)
469    }
470
471    /// Register a contract for runtime validation
472    pub fn register_contract(&self, contract: ApiContract) {
473        let key = format!("{}-{}", contract.module, contract.apiname);
474
475        if let Ok(mut contracts) = self.contracts.write() {
476            contracts.insert(key, contract);
477        }
478    }
479
480    /// Validate API call against contract in real-time
481    pub fn validate_api_call(
482        &self,
483        apiname: &str,
484        module: &str,
485        context: &ApiCallContext,
486    ) -> CoreResult<()> {
487        let start_time = Instant::now();
488        let key = format!("{module}-{apiname}");
489
490        // Update statistics
491        {
492            if let Ok(mut stats) = self.stats.lock() {
493                stats.total_validations += 1;
494            }
495        }
496
497        // Inject chaos if enabled
498        self.maybe_inject_fault(apiname, module)?;
499
500        // Get contract
501        let contract = {
502            if let Ok(contracts) = self.contracts.read() {
503                contracts.get(&key).cloned()
504            } else {
505                return Err(CoreError::ValidationError(ErrorContext::new(
506                    "Cannot access contracts for validation".to_string(),
507                )));
508            }
509        };
510
511        let contract = contract.ok_or_else(|| {
512            CoreError::ValidationError(ErrorContext::new(format!(
513                "No contract found for {module}::{apiname}"
514            )))
515        })?;
516
517        // Validate performance contract
518        if let Some(max_time) = contract.performance.maxexecution_time {
519            if context.execution_time > max_time {
520                self.report_violation(
521                    apiname,
522                    module,
523                    ContractViolation {
524                        violation_type: ViolationType::Performance,
525                        expected: format!("{max_time:?}"),
526                        actual: format!("{:?}", context.execution_time),
527                        severity: ViolationSeverity::High,
528                    },
529                )?;
530            }
531        }
532
533        // Validate memory contract
534        if let Some(max_memory) = contract.memory.max_memory {
535            if context.memory_usage > max_memory {
536                self.report_violation(
537                    apiname,
538                    module,
539                    ContractViolation {
540                        violation_type: ViolationType::Memory,
541                        expected: format!("{max_memory}"),
542                        actual: context.memory_usage.to_string(),
543                        severity: ViolationSeverity::Medium,
544                    },
545                )?;
546            }
547        }
548
549        // Update statistics
550        let validation_time = start_time.elapsed();
551        {
552            if let Ok(mut stats) = self.stats.lock() {
553                let total = stats.total_validations as f64;
554                let prev_avg = stats.avg_validation_time.as_nanos() as f64;
555                let new_avg =
556                    (prev_avg * (total - 1.0) + validation_time.as_nanos() as f64) / total;
557                stats.avg_validation_time = Duration::from_nanos(new_avg as u64);
558                stats.success_rate = (total - stats.violations_detected as f64) / total;
559            }
560        }
561
562        Ok(())
563    }
564
565    /// Enable chaos engineering
566    pub fn enable_chaos_engineering(&self, faultprobability: f64) {
567        if let Ok(mut controller) = self.chaos_controller.lock() {
568            controller.enabled = true;
569            controller.faultprobability = faultprobability.clamp(0.0, 1.0);
570        }
571    }
572
573    /// Maybe inject a chaos fault
574    fn maybe_inject_fault(&self, apiname: &str, module: &str) -> CoreResult<()> {
575        if let Ok(mut controller) = self.chaos_controller.lock() {
576            if !controller.enabled {
577                return Ok(());
578            }
579
580            // Generate random number for fault probability
581            let mut hasher = DefaultHasher::new();
582            apiname.hash(&mut hasher);
583            module.hash(&mut hasher);
584            SystemTime::now()
585                .duration_since(SystemTime::UNIX_EPOCH)
586                .unwrap_or_default()
587                .as_nanos()
588                .hash(&mut hasher);
589
590            let rand_val = (hasher.finish() % 10000) as f64 / 10000.0;
591
592            if rand_val < controller.faultprobability {
593                // Inject a random fault
594                let fault = match rand_val * 4.0 {
595                    x if x < 1.0 => ChaosFault::LatencyInjection(Duration::from_millis(100)),
596                    x if x < 2.0 => ChaosFault::MemoryPressure(1024 * 1024), // 1MB
597                    x if x < 3.0 => ChaosFault::CpuThrottling(0.5),
598                    _ => ChaosFault::RandomFailure(0.1),
599                };
600
601                controller.active_faults.push(fault.clone());
602                controller
603                    .fault_history
604                    .push((Instant::now(), fault.clone()));
605
606                // Send monitoring event
607                let event = MonitoringEvent {
608                    timestamp: Instant::now(),
609                    apiname: apiname.to_string(),
610                    module: module.to_string(),
611                    event_type: MonitoringEventType::ChaosEngineeringFault(fault.clone()),
612                    performance_metrics: RuntimePerformanceMetrics {
613                        execution_time: Duration::from_nanos(0),
614                        memory_usage: 0,
615                        cpu_usage: 0.0,
616                        cache_hit_rate: 0.0,
617                        thread_count: 1,
618                    },
619                    thread_id: format!("{:?}", thread::current().id()),
620                };
621
622                let _ = self.event_sender.send(event);
623
624                // Actually inject the fault
625                match fault {
626                    ChaosFault::LatencyInjection(delay) => {
627                        thread::sleep(delay);
628                    }
629                    ChaosFault::RandomFailure(prob) if rand_val < prob => {
630                        return Err(CoreError::ValidationError(ErrorContext::new(
631                            "Chaos engineering: Random failure injected".to_string(),
632                        )));
633                    }
634                    _ => {} // Other faults would require system-level intervention
635                }
636            }
637        }
638
639        Ok(())
640    }
641
642    /// Report a contract violation
643    fn report_violation(
644        &self,
645        apiname: &str,
646        module: &str,
647        violation: ContractViolation,
648    ) -> CoreResult<()> {
649        // Update statistics
650        {
651            if let Ok(mut stats) = self.stats.lock() {
652                stats.violations_detected += 1;
653                let total = stats.total_validations as f64;
654                stats.success_rate = (total - stats.violations_detected as f64) / total;
655            }
656        }
657
658        // Send monitoring event
659        let event = MonitoringEvent {
660            timestamp: Instant::now(),
661            apiname: apiname.to_string(),
662            module: module.to_string(),
663            event_type: MonitoringEventType::ContractViolation(violation.clone()),
664            performance_metrics: RuntimePerformanceMetrics {
665                execution_time: Duration::from_nanos(0),
666                memory_usage: 0,
667                cpu_usage: 0.0,
668                cache_hit_rate: 0.0,
669                thread_count: 1,
670            },
671            thread_id: format!("{:?}", thread::current().id()),
672        };
673
674        let _ = self.event_sender.send(event);
675
676        // Return error for critical violations
677        if violation.severity >= ViolationSeverity::High {
678            return Err(CoreError::ValidationError(ErrorContext::new(format!(
679                "Critical contract violation in {}::{}: {} (expected: {}, actual: {})",
680                module,
681                apiname,
682                match violation.violation_type {
683                    ViolationType::Performance => "Performance",
684                    ViolationType::Memory => "Memory",
685                    ViolationType::Numerical => "Numerical",
686                    ViolationType::Concurrency => "Concurrency",
687                    ViolationType::Behavioral => "Behavioral",
688                },
689                violation.expected,
690                violation.actual
691            ))));
692        }
693
694        Ok(())
695    }
696
697    /// Get validation statistics
698    pub fn get_statistics(&self) -> Option<ValidationStatistics> {
699        self.stats.lock().ok().map(|stats| stats.clone())
700    }
701
702    /// Get chaos engineering status
703    pub fn get_chaos_status(&self) -> Option<(bool, f64, usize)> {
704        if let Ok(controller) = self.chaos_controller.lock() {
705            Some((
706                controller.enabled,
707                controller.faultprobability,
708                controller.fault_history.len(),
709            ))
710        } else {
711            None
712        }
713    }
714
715    /// Disable chaos engineering
716    pub fn disable_chaos_engineering(&self) {
717        if let Ok(mut controller) = self.chaos_controller.lock() {
718            controller.enabled = false;
719            controller.active_faults.clear();
720        }
721    }
722}
723
724/// API call context for runtime validation
725#[derive(Debug, Clone)]
726pub struct ApiCallContext {
727    /// Execution time of the call
728    pub execution_time: Duration,
729    /// Memory usage during the call
730    pub memory_usage: usize,
731    /// Input parameters hash
732    pub input_hash: String,
733    /// Output parameters hash
734    pub output_hash: String,
735    /// Thread ID where call occurred
736    pub thread_id: String,
737}
738
739impl Default for AdvancedPerformanceModeler {
740    fn default() -> Self {
741        Self::new()
742    }
743}
744
745impl AdvancedPerformanceModeler {
746    /// Create a new performance modeler
747    pub fn new() -> Self {
748        Self {
749            performance_history: Arc::new(RwLock::new(Vec::new())),
750            prediction_models: Arc::new(RwLock::new(HashMap::new())),
751            training_status: Arc::new(Mutex::new(HashMap::new())),
752        }
753    }
754
755    /// Record a performance measurement
756    pub fn record_measurement(
757        &self,
758        apiname: &str,
759        input_characteristics: InputCharacteristics,
760        performance: PerformanceMetrics,
761        system_state: SystemState,
762    ) {
763        // Convert PerformanceMetrics to RuntimePerformanceMetrics
764        let runtime_performance = RuntimePerformanceMetrics {
765            execution_time: Duration::from_secs_f64(
766                performance.operation_times.values().sum::<f64>()
767                    / performance.operation_times.len().max(1) as f64,
768            ),
769            memory_usage: 0, // Not available in PerformanceMetrics
770            cpu_usage: 0.0,  // Not available in PerformanceMetrics
771            cache_hit_rate: performance.cache_hit_rate,
772            thread_count: 1, // Default value
773        };
774
775        let data_point = PerformanceDataPoint {
776            timestamp: Instant::now(),
777            apiname: apiname.to_string(),
778            input_characteristics,
779            performance: runtime_performance,
780            system_state,
781        };
782
783        if let Ok(mut history) = self.performance_history.write() {
784            history.push(data_point);
785
786            // Limit history size to prevent unbounded growth
787            if history.len() > 10000 {
788                history.remove(0);
789            }
790        }
791
792        // Trigger model retraining if enough new data
793        self.maybe_retrain_model(apiname);
794    }
795
796    /// Predict performance for given input characteristics
797    pub fn predict_performance(
798        &self,
799        apiname: &str,
800        input_characteristics: InputCharacteristics,
801        system_state: &SystemState,
802    ) -> Option<RuntimePerformanceMetrics> {
803        if let Ok(models) = self.prediction_models.read() {
804            if let Some(model) = models.get(apiname) {
805                // Simplified prediction based on input size and model parameters
806                let base_time = Duration::from_nanos(1000);
807                let size_factor = match model.model_type {
808                    ModelType::LinearRegression => {
809                        // Use linear model: slope * x + intercept
810                        if model.parameters.len() >= 2 {
811                            model.parameters[0] * input_characteristics.size as f64
812                                + model.parameters[1]
813                        } else {
814                            (input_characteristics.size as f64).sqrt()
815                        }
816                    }
817                    ModelType::PolynomialRegression => (input_characteristics.size as f64).sqrt(),
818                    _ => (input_characteristics.size as f64).sqrt(),
819                };
820
821                let scaled_time = Duration::from_nanos(
822                    (base_time.as_nanos() as f64 * size_factor.max(1.0)) as u64,
823                );
824
825                return Some(RuntimePerformanceMetrics {
826                    execution_time: scaled_time,
827                    memory_usage: input_characteristics.size * 8, // Assume 8 bytes per element
828                    cpu_usage: system_state.cpu_utilization * 1.1, // Slightly higher
829                    cache_hit_rate: 0.8,                          // Assume good cache performance
830                    thread_count: 1,
831                });
832            }
833        }
834
835        None
836    }
837
838    /// Maybe retrain model if conditions are met
839    fn maybe_retrain_model(&self, apiname: &str) {
840        // Check if enough new data points exist
841        let should_retrain = {
842            if let Ok(history) = self.performance_history.read() {
843                let api_data_points = history.iter().filter(|dp| dp.apiname == apiname).count();
844                api_data_points > 100 && (api_data_points % 50 == 0)
845            } else {
846                false
847            }
848        };
849
850        if should_retrain {
851            self.train_model(apiname);
852        }
853    }
854
855    /// Train a performance prediction model
856    fn train_model(&self, apiname: &str) {
857        // Set training status
858        {
859            if let Ok(mut status) = self.training_status.lock() {
860                status.insert(apiname.to_string(), TrainingStatus::InProgress);
861            }
862        }
863
864        let apiname = apiname.to_string();
865        let history_clone = Arc::clone(&self.performance_history);
866        let models_clone = Arc::clone(&self.prediction_models);
867        let status_clone = Arc::clone(&self.training_status);
868
869        // Spawn training thread
870        thread::spawn(move || {
871            let training_data = {
872                if let Ok(history) = history_clone.read() {
873                    history
874                        .iter()
875                        .filter(|dp| dp.apiname == apiname)
876                        .cloned()
877                        .collect::<Vec<_>>()
878                } else {
879                    Vec::new()
880                }
881            };
882
883            if training_data.len() < 10 {
884                // Not enough data
885                if let Ok(mut status) = status_clone.lock() {
886                    status.insert(apiname.clone(), TrainingStatus::Failed);
887                }
888                return;
889            }
890
891            // Simple linear regression model (simplified)
892            let mut sum_x = 0.0;
893            let mut sum_y = 0.0;
894            let mut sum_xy = 0.0;
895            let mut sum_x2 = 0.0;
896            let n = training_data.len() as f64;
897
898            for dp in &training_data {
899                let x = dp.input_characteristics.size as f64;
900                let y = dp.performance.execution_time.as_nanos() as f64;
901
902                sum_x += x;
903                sum_y += y;
904                sum_xy += x * y;
905                sum_x2 += x * x;
906            }
907
908            let slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x * sum_x);
909            let intercept = (sum_y - slope * sum_x) / n;
910
911            // Calculate accuracy (R-squared)
912            let y_mean = sum_y / n;
913            let mut ss_tot = 0.0;
914            let mut ss_res = 0.0;
915
916            for dp in &training_data {
917                let x = dp.input_characteristics.size as f64;
918                let y = dp.performance.execution_time.as_nanos() as f64;
919                let y_pred = slope * x + intercept;
920
921                ss_tot += (y - y_mean).powi(2);
922                ss_res += (y - y_pred).powi(2);
923            }
924
925            let r_squared = if ss_tot > 0.0 {
926                1.0 - (ss_res / ss_tot)
927            } else {
928                0.0
929            };
930
931            let model = PerformancePredictionModel {
932                model_type: ModelType::LinearRegression,
933                parameters: vec![slope, intercept],
934                accuracy: r_squared.clamp(0.0, 1.0),
935                training_data_size: training_data.len(),
936                last_updated: Instant::now(),
937            };
938
939            // Store the trained model
940            {
941                if let Ok(mut models) = models_clone.write() {
942                    models.insert(apiname.clone(), model);
943                }
944            }
945
946            // Update training status
947            {
948                if let Ok(mut status) = status_clone.lock() {
949                    status.insert(apiname, TrainingStatus::Completed);
950                }
951            }
952        });
953    }
954
955    /// Get training status for an API
956    pub fn get_training_status(&self, apiname: &str) -> TrainingStatus {
957        if let Ok(status) = self.training_status.lock() {
958            status
959                .get(apiname)
960                .copied()
961                .unwrap_or(TrainingStatus::NotStarted)
962        } else {
963            TrainingStatus::NotStarted
964        }
965    }
966
967    /// Get model accuracy for an API
968    pub fn get_model_accuracy(&self, apiname: &str) -> Option<f64> {
969        if let Ok(models) = self.prediction_models.read() {
970            models.get(apiname).map(|model| model.accuracy)
971        } else {
972            None
973        }
974    }
975
976    /// Get number of data points for an API
977    pub fn get_data_point_count(&self, apiname: &str) -> usize {
978        if let Ok(history) = self.performance_history.read() {
979            history.iter().filter(|dp| dp.apiname == apiname).count()
980        } else {
981            0
982        }
983    }
984}
985
986impl Default for ImmutableAuditTrail {
987    fn default() -> Self {
988        Self::new()
989    }
990}
991
992impl ImmutableAuditTrail {
993    /// Create a new immutable audit trail
994    pub fn new() -> Self {
995        Self {
996            audit_chain: Arc::new(RwLock::new(Vec::new())),
997            current_hash: Arc::new(RwLock::new(0.to_string())),
998        }
999    }
1000
1001    /// Add a new audit record
1002    pub fn add_record(&self, data: AuditData) -> CoreResult<()> {
1003        let timestamp = SystemTime::now();
1004
1005        let previous_hash = {
1006            if let Ok(hash) = self.current_hash.read() {
1007                hash.clone()
1008            } else {
1009                return Err(CoreError::ValidationError(ErrorContext::new(
1010                    "Cannot access current hash".to_string(),
1011                )));
1012            }
1013        };
1014
1015        // Create record
1016        let mut record = AuditRecord {
1017            timestamp,
1018            previous_hash: previous_hash.clone(),
1019            data,
1020            signature: String::new(), // Would be populated by digital signature
1021            record_hash: String::new(),
1022        };
1023
1024        // Calculate record hash
1025        record.record_hash = self.calculate_record_hash(&record);
1026
1027        // Add digital signature (simplified)
1028        record.signature = record.record_hash.to_string();
1029
1030        // Add to chain
1031        {
1032            if let Ok(mut chain) = self.audit_chain.write() {
1033                chain.push(record.clone());
1034            } else {
1035                return Err(CoreError::ValidationError(ErrorContext::new(
1036                    "Cannot access audit chain".to_string(),
1037                )));
1038            }
1039        }
1040
1041        // Update current hash
1042        {
1043            if let Ok(mut hash) = self.current_hash.write() {
1044                *hash = record.record_hash;
1045            }
1046        }
1047
1048        Ok(())
1049    }
1050
1051    /// Calculate cryptographic hash of a record
1052    fn calculate_record_hash(&self, record: &AuditRecord) -> String {
1053        let mut hasher = DefaultHasher::new();
1054
1055        record
1056            .timestamp
1057            .duration_since(SystemTime::UNIX_EPOCH)
1058            .unwrap_or_default()
1059            .as_nanos()
1060            .hash(&mut hasher);
1061        record.previous_hash.hash(&mut hasher);
1062
1063        // Hash the data (simplified)
1064        match &record.data {
1065            AuditData::ContractRegistration(name) => name.hash(&mut hasher),
1066            AuditData::ContractValidation {
1067                apiname,
1068                module,
1069                result,
1070            } => {
1071                apiname.hash(&mut hasher);
1072                module.hash(&mut hasher);
1073                result.hash(&mut hasher);
1074            }
1075            AuditData::PerformanceMeasurement {
1076                apiname,
1077                module,
1078                metrics,
1079            } => {
1080                apiname.hash(&mut hasher);
1081                module.hash(&mut hasher);
1082                metrics.hash(&mut hasher);
1083            }
1084            AuditData::ViolationDetection {
1085                apiname,
1086                module,
1087                violation,
1088            } => {
1089                apiname.hash(&mut hasher);
1090                module.hash(&mut hasher);
1091                violation.hash(&mut hasher);
1092            }
1093        }
1094
1095        format!("{:x}", hasher.finish())
1096    }
1097
1098    /// Verify the integrity of the audit trail
1099    pub fn verify_integrity(&self) -> bool {
1100        if let Ok(chain) = self.audit_chain.read() {
1101            if chain.is_empty() {
1102                return true;
1103            }
1104
1105            for (i, record) in chain.iter().enumerate() {
1106                // Verify hash
1107                let expected_hash = self.calculate_record_hash(record);
1108                if record.record_hash != expected_hash {
1109                    return false;
1110                }
1111
1112                // Verify chain linkage
1113                if i > 0 {
1114                    let prev_record = &chain[i.saturating_sub(1)];
1115                    if record.previous_hash != prev_record.record_hash {
1116                        return false;
1117                    }
1118                }
1119            }
1120
1121            true
1122        } else {
1123            false
1124        }
1125    }
1126
1127    /// Get audit trail length
1128    pub fn len(&self) -> usize {
1129        if let Ok(chain) = self.audit_chain.read() {
1130            chain.len()
1131        } else {
1132            0
1133        }
1134    }
1135
1136    /// Check if audit trail is empty
1137    pub fn is_empty(&self) -> bool {
1138        self.len() == 0
1139    }
1140
1141    /// Get recent audit records
1142    pub fn get_recent_records(&self, count: usize) -> Vec<AuditRecord> {
1143        if let Ok(chain) = self.audit_chain.read() {
1144            let start = chain.len().saturating_sub(count);
1145            chain[start..].to_vec()
1146        } else {
1147            Vec::new()
1148        }
1149    }
1150
1151    /// Export audit trail for external verification
1152    #[cfg(feature = "serialization")]
1153    pub fn export_trail(&self) -> CoreResult<String> {
1154        if let Ok(chain) = self.audit_chain.read() {
1155            serde_json::to_string_pretty(&*chain).map_err(|e| {
1156                CoreError::ValidationError(ErrorContext::new(format!(
1157                    "Failed to serialize audit trail: {e}"
1158                )))
1159            })
1160        } else {
1161            Err(CoreError::ValidationError(ErrorContext::new(
1162                "Cannot access audit chain for export".to_string(),
1163            )))
1164        }
1165    }
1166
1167    /// Export audit trail for external verification (fallback without serialization)
1168    #[cfg(not(feature = "serialization"))]
1169    pub fn export_trail(&self) -> CoreResult<String> {
1170        Err(CoreError::ValidationError(ErrorContext::new(
1171            "Audit trail export requires serialization feature".to_string(),
1172        )))
1173    }
1174}
1175
1176// Helper implementations for public structs
1177impl InputCharacteristics {
1178    /// Create new input characteristics
1179    pub fn new(size: usize, datatype: String) -> Self {
1180        Self {
1181            size,
1182            datatype,
1183            memory_layout: "contiguous".to_string(),
1184            access_pattern: "sequential".to_string(),
1185        }
1186    }
1187
1188    /// Create characteristics for matrix operations
1189    pub fn matrix(rows: usize, cols: usize) -> Self {
1190        Self {
1191            size: rows * cols,
1192            datatype: "f64".to_string(),
1193            memory_layout: "row_major".to_string(),
1194            access_pattern: "matrix".to_string(),
1195        }
1196    }
1197
1198    /// Create characteristics for vector operations
1199    pub fn vector(length: usize) -> Self {
1200        Self {
1201            size: length,
1202            datatype: "f64".to_string(),
1203            memory_layout: "contiguous".to_string(),
1204            access_pattern: "sequential".to_string(),
1205        }
1206    }
1207}
1208
1209impl SystemState {
1210    /// Create new system state
1211    pub fn new() -> Self {
1212        Self {
1213            cpu_utilization: 0.5,    // Default 50%
1214            memory_utilization: 0.6, // Default 60%
1215            io_load: 0.1,            // Default low
1216            network_load: 0.05,      // Default very low
1217            temperature: 65.0,       // Default temperature in Celsius
1218        }
1219    }
1220
1221    /// Create system state from current system metrics (simplified)
1222    pub fn current() -> Self {
1223        // In a real implementation, this would query actual system metrics
1224        Self::new()
1225    }
1226}
1227
1228impl Default for InputCharacteristics {
1229    fn default() -> Self {
1230        Self::new(1000, "f64".to_string())
1231    }
1232}
1233
1234impl Default for SystemState {
1235    fn default() -> Self {
1236        Self::new()
1237    }
1238}
1239
1240#[cfg(test)]
1241mod tests {
1242    use super::*;
1243
1244    /// Build a minimal `ApiContract` for verification tests.
1245    fn make_contract(
1246        apiname: &str,
1247        module: &str,
1248        max_exec: Option<Duration>,
1249        max_memory: Option<usize>,
1250        thread_safe: bool,
1251    ) -> ApiContract {
1252        ApiContract {
1253            apiname: apiname.to_string(),
1254            module: module.to_string(),
1255            contract_hash: "test_hash".to_string(),
1256            created_at: SystemTime::now(),
1257            verification_status: VerificationStatus::NotVerified,
1258            stability: StabilityLevel::Stable,
1259            since_version: Version::new(1, 0, 0),
1260            performance: PerformanceContract {
1261                time_complexity: ComplexityBound::Linear,
1262                space_complexity: ComplexityBound::Constant,
1263                maxexecution_time: max_exec,
1264                min_throughput: None,
1265                memorybandwidth: None,
1266            },
1267            numerical: NumericalContract {
1268                precision: PrecisionGuarantee::MachinePrecision,
1269                stability: NumericalStability::Stable,
1270                input_domain: InputDomain {
1271                    ranges: vec![],
1272                    exclusions: vec![],
1273                    special_values: SpecialValueHandling::Propagate,
1274                },
1275                output_range: OutputRange {
1276                    bounds: None,
1277                    monotonic: None,
1278                    continuous: true,
1279                },
1280            },
1281            concurrency: ConcurrencyContract {
1282                thread_safety: if thread_safe {
1283                    ThreadSafety::ThreadSafe
1284                } else {
1285                    ThreadSafety::NotThreadSafe
1286                },
1287                atomicity: AtomicityGuarantee::OperationAtomic,
1288                lock_free: false,
1289                wait_free: false,
1290                memory_ordering: MemoryOrdering::AcquireRelease,
1291            },
1292            memory: MemoryContract {
1293                allocation_pattern: AllocationPattern::SingleAllocation,
1294                max_memory,
1295                alignment: None,
1296                locality: LocalityGuarantee::GoodSpatial,
1297                gc_behavior: GcBehavior::MinimalGc,
1298            },
1299            deprecation: None,
1300        }
1301    }
1302
1303    /// Poll until verification for `(module, apiname)` leaves the
1304    /// `InProgress` state (the background thread resolves near-instantly
1305    /// for these tests), panicking if it never does.
1306    fn wait_for_verification(
1307        engine: &FormalVerificationEngine,
1308        apiname: &str,
1309        module: &str,
1310    ) -> VerificationStatus {
1311        let deadline = Instant::now() + Duration::from_secs(5);
1312        loop {
1313            let status = engine.get_verification_status(apiname, module);
1314            if status != VerificationStatus::InProgress {
1315                return status;
1316            }
1317            assert!(
1318                Instant::now() < deadline,
1319                "verification for {module}-{apiname} did not complete within the test timeout"
1320            );
1321            thread::sleep(Duration::from_millis(5));
1322        }
1323    }
1324
1325    #[test]
1326    fn test_formal_verification_engine() {
1327        let engine = FormalVerificationEngine::new();
1328        assert_eq!(engine.get_verification_coverage(), 0.0);
1329
1330        let contract = make_contract(
1331            "test_api",
1332            "test_module",
1333            Some(Duration::from_millis(100)),
1334            Some(1024),
1335            true,
1336        );
1337
1338        // No probe supplied: nothing was actually executed, so this must
1339        // honestly resolve to Failed rather than a fabricated Verified.
1340        engine
1341            .verify_contract(&contract, None)
1342            .expect("Operation failed");
1343
1344        let status = wait_for_verification(&engine, "test_api", "test_module");
1345        assert_eq!(
1346            status,
1347            VerificationStatus::Failed,
1348            "verification with no executable probe must not fabricate Verified"
1349        );
1350
1351        let results = engine.get_all_results();
1352        let result = results
1353            .get("test_module-test_api")
1354            .expect("result recorded");
1355        assert!(!result.verified);
1356        assert!(result.counterexample.is_some());
1357    }
1358
1359    #[test]
1360    fn test_verify_contract_passes_with_probe_within_bounds() {
1361        let engine = FormalVerificationEngine::new();
1362        let contract = make_contract(
1363            "fast_api",
1364            "perf_module",
1365            Some(Duration::from_millis(50)),
1366            Some(1024),
1367            false,
1368        );
1369
1370        let probe = VerificationProbe {
1371            invoke: Box::new(|| (Duration::from_millis(1), Some(10))),
1372            iterations: 5,
1373            concurrency: 1,
1374        };
1375
1376        engine
1377            .verify_contract(&contract, Some(probe))
1378            .expect("start verification");
1379        let status = wait_for_verification(&engine, "fast_api", "perf_module");
1380        assert_eq!(status, VerificationStatus::Verified);
1381
1382        let results = engine.get_all_results();
1383        let result = results
1384            .get("perf_module-fast_api")
1385            .expect("result recorded");
1386        assert!(result.verified);
1387        assert!(result
1388            .checked_properties
1389            .contains(&"performance_bound".to_string()));
1390        assert!(result
1391            .checked_properties
1392            .contains(&"memory_bound".to_string()));
1393    }
1394
1395    #[test]
1396    fn test_verify_contract_detects_real_performance_violation() {
1397        let engine = FormalVerificationEngine::new();
1398        let contract = make_contract(
1399            "slow_api",
1400            "perf_module",
1401            Some(Duration::from_millis(10)),
1402            None,
1403            false,
1404        );
1405
1406        // A real measured duration that genuinely exceeds the contract
1407        // bound; under the old hardcoded-`true` implementation this would
1408        // have been reported Verified regardless.
1409        let probe = VerificationProbe {
1410            invoke: Box::new(|| (Duration::from_millis(200), None)),
1411            iterations: 1,
1412            concurrency: 1,
1413        };
1414
1415        engine
1416            .verify_contract(&contract, Some(probe))
1417            .expect("start verification");
1418        let status = wait_for_verification(&engine, "slow_api", "perf_module");
1419        assert_eq!(status, VerificationStatus::Failed);
1420
1421        let results = engine.get_all_results();
1422        let result = results
1423            .get("perf_module-slow_api")
1424            .expect("result recorded");
1425        assert!(!result.verified);
1426        let counterexample = result
1427            .counterexample
1428            .as_ref()
1429            .expect("counterexample present");
1430        assert!(
1431            counterexample.contains("performance_bound"),
1432            "got: {counterexample}"
1433        );
1434    }
1435
1436    #[test]
1437    fn test_verify_contract_detects_real_memory_violation() {
1438        let engine = FormalVerificationEngine::new();
1439        let contract = make_contract("greedy_api", "mem_module", None, Some(100), false);
1440
1441        let probe = VerificationProbe {
1442            invoke: Box::new(|| (Duration::from_micros(1), Some(500))),
1443            iterations: 1,
1444            concurrency: 1,
1445        };
1446
1447        engine
1448            .verify_contract(&contract, Some(probe))
1449            .expect("start verification");
1450        let status = wait_for_verification(&engine, "greedy_api", "mem_module");
1451        assert_eq!(status, VerificationStatus::Failed);
1452
1453        let results = engine.get_all_results();
1454        let result = results
1455            .get("mem_module-greedy_api")
1456            .expect("result recorded");
1457        let counterexample = result
1458            .counterexample
1459            .as_ref()
1460            .expect("counterexample present");
1461        assert!(
1462            counterexample.contains("memory_bound"),
1463            "got: {counterexample}"
1464        );
1465    }
1466
1467    #[test]
1468    fn test_verify_contract_concurrent_smoke_test_catches_real_panics() {
1469        let engine = FormalVerificationEngine::new();
1470        let contract = make_contract("racy_api", "concurrency_module", None, None, true);
1471
1472        let call_count = Arc::new(AtomicUsize::new(0));
1473        let call_count_probe = Arc::clone(&call_count);
1474        let probe = VerificationProbe {
1475            invoke: Box::new(move || {
1476                let n = call_count_probe.fetch_add(1, Ordering::SeqCst);
1477                // The sequential performance/memory warm-up consumes calls
1478                // 0..iterations (4) first; only fail calls from the
1479                // concurrent phase (n >= 4) so this test exercises the
1480                // concurrent smoke test specifically; a probe that panics
1481                // during the *sequential* pass is covered by a separate
1482                // test (`test_formal_verification_engine`-adjacent
1483                // behavior lives in `perform_verification`'s own
1484                // panic-safety, not this concurrency-focused test).
1485                assert!(n < 4 || n % 5 != 0, "simulated concurrency bug (call #{n})");
1486                (Duration::from_micros(1), None)
1487            }),
1488            iterations: 4,
1489            concurrency: 4,
1490        };
1491
1492        engine
1493            .verify_contract(&contract, Some(probe))
1494            .expect("start verification");
1495        let status = wait_for_verification(&engine, "racy_api", "concurrency_module");
1496        assert_eq!(status, VerificationStatus::Failed);
1497
1498        let results = engine.get_all_results();
1499        let result = results
1500            .get("concurrency_module-racy_api")
1501            .expect("result recorded");
1502        let counterexample = result
1503            .counterexample
1504            .as_ref()
1505            .expect("counterexample present");
1506        assert!(
1507            counterexample.contains("thread_safety"),
1508            "got: {counterexample}"
1509        );
1510    }
1511
1512    #[test]
1513    fn test_verify_contract_concurrent_smoke_test_passes_when_actually_safe() {
1514        let engine = FormalVerificationEngine::new();
1515        let contract = make_contract("safe_api", "concurrency_module2", None, None, true);
1516
1517        let probe = VerificationProbe {
1518            invoke: Box::new(|| (Duration::from_micros(1), None)),
1519            iterations: 4,
1520            concurrency: 4,
1521        };
1522
1523        engine
1524            .verify_contract(&contract, Some(probe))
1525            .expect("start verification");
1526        let status = wait_for_verification(&engine, "safe_api", "concurrency_module2");
1527        assert_eq!(status, VerificationStatus::Verified);
1528    }
1529
1530    /// Regression test: a probe that panics during the sequential
1531    /// performance/memory measurement pass (before the concurrent
1532    /// thread-safety smoke test even runs) must resolve to `Failed` with
1533    /// an explanatory counterexample — not silently hang the background
1534    /// verification thread forever (an uncaught panic there would abandon
1535    /// the task in `InProgress` with nothing left running to ever update
1536    /// it).
1537    #[test]
1538    fn test_verify_contract_probe_panic_during_sequential_pass_reports_failure_not_hang() {
1539        let engine = FormalVerificationEngine::new();
1540        let contract = make_contract(
1541            "panicky_api",
1542            "panic_module",
1543            Some(Duration::from_millis(50)),
1544            None,
1545            false,
1546        );
1547
1548        let probe = VerificationProbe {
1549            invoke: Box::new(|| panic!("probe always panics")),
1550            iterations: 1,
1551            concurrency: 1,
1552        };
1553
1554        engine
1555            .verify_contract(&contract, Some(probe))
1556            .expect("start verification");
1557        let status = wait_for_verification(&engine, "panicky_api", "panic_module");
1558        assert_eq!(
1559            status,
1560            VerificationStatus::Failed,
1561            "a probe that panics must resolve to Failed, not hang or fabricate Verified"
1562        );
1563
1564        let results = engine.get_all_results();
1565        let result = results
1566            .get("panic_module-panicky_api")
1567            .expect("result recorded");
1568        assert!(!result.verified);
1569        let counterexample = result
1570            .counterexample
1571            .as_ref()
1572            .expect("counterexample present");
1573        assert!(counterexample.contains("panicked"), "got: {counterexample}");
1574    }
1575
1576    #[test]
1577    fn test_runtime_contract_validator() {
1578        let (validator, receiver) = RuntimeContractValidator::new();
1579
1580        let stats = validator.get_statistics().expect("Operation failed");
1581        assert_eq!(stats.total_validations, 0);
1582        assert_eq!(stats.violations_detected, 0);
1583        assert_eq!(stats.success_rate, 1.0);
1584    }
1585
1586    #[test]
1587    fn test_performance_modeler() {
1588        let modeler = AdvancedPerformanceModeler::new();
1589
1590        let input_chars = InputCharacteristics::new(1000, "f64".to_string());
1591        let system_state = SystemState::new();
1592        let performance = PerformanceMetrics {
1593            operation_times: std::collections::HashMap::new(),
1594            strategy_success_rates: std::collections::HashMap::new(),
1595            memorybandwidth_utilization: 0.8,
1596            cache_hit_rate: 0.8,
1597            parallel_efficiency: 0.9,
1598        };
1599
1600        modeler.record_measurement(
1601            "test_api",
1602            input_chars.clone(),
1603            performance,
1604            system_state.clone(),
1605        );
1606
1607        assert_eq!(modeler.get_data_point_count("test_api"), 1);
1608        assert_eq!(
1609            modeler.get_training_status("test_api"),
1610            TrainingStatus::NotStarted
1611        );
1612    }
1613
1614    #[test]
1615    fn test_audit_trail() {
1616        let trail = ImmutableAuditTrail::new();
1617        assert!(trail.is_empty());
1618        assert!(trail.verify_integrity());
1619
1620        let data = AuditData::ContractRegistration("test::api".to_string());
1621        trail.add_record(data).expect("Operation failed");
1622
1623        assert_eq!(trail.len(), 1);
1624        assert!(trail.verify_integrity());
1625    }
1626
1627    #[test]
1628    fn test_input_characteristics() {
1629        let chars = InputCharacteristics::matrix(10, 10);
1630        assert_eq!(chars.size, 100);
1631        assert_eq!(chars.memory_layout, "row_major");
1632
1633        let vector_chars = InputCharacteristics::vector(50);
1634        assert_eq!(vector_chars.size, 50);
1635        assert_eq!(vector_chars.access_pattern, "sequential");
1636    }
1637
1638    #[test]
1639    fn test_system_state() {
1640        let state = SystemState::current();
1641        assert!(state.cpu_utilization >= 0.0 && state.cpu_utilization <= 1.0);
1642        assert!(state.memory_utilization >= 0.0 && state.memory_utilization <= 1.0);
1643        assert!(state.temperature > 0.0);
1644    }
1645}