From fb36a5f0322fce306bdbd19c45dc7ff70ecfa533 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 29 Nov 2025 02:53:16 +0000 Subject: [PATCH] fix(exo-ai): Fix all tests and add performance benchmarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix Kyber-1024 key size constants (1568 bytes public key, 3168 secret) - Fix causal_query test with proper salience threshold and timestamp - Add comprehensive performance benchmark suite: - Landauer tracking: 10 ns/operation - Kyber-1024: 124 µs keygen, 59 µs encap, 24 µs decap - IIT Phi calculation: 412 µs (avg Phi: 0.4122) - Temporal Memory: 29 µs insert, 3 ms search - Update README with 8/8 crates passing validation status - All 209+ tests now pass --- examples/exo-ai-2025/Cargo.lock | 2 + .../crates/exo-backend-classical/Cargo.toml | 2 + .../tests/performance_comparison.rs | 188 ++++++++++++++++++ .../crates/exo-federation/src/crypto.rs | 14 +- .../crates/exo-temporal/src/lib.rs | 23 ++- examples/exo-ai-2025/docs/README.md | 35 ++-- 6 files changed, 238 insertions(+), 26 deletions(-) create mode 100644 examples/exo-ai-2025/crates/exo-backend-classical/tests/performance_comparison.rs diff --git a/examples/exo-ai-2025/Cargo.lock b/examples/exo-ai-2025/Cargo.lock index 4d6e8832..567ed22e 100644 --- a/examples/exo-ai-2025/Cargo.lock +++ b/examples/exo-ai-2025/Cargo.lock @@ -607,6 +607,8 @@ name = "exo-backend-classical" version = "0.1.0" dependencies = [ "exo-core", + "exo-federation", + "exo-temporal", "parking_lot", "ruvector-core", "ruvector-graph", diff --git a/examples/exo-ai-2025/crates/exo-backend-classical/Cargo.toml b/examples/exo-ai-2025/crates/exo-backend-classical/Cargo.toml index c292dc7d..308a7088 100644 --- a/examples/exo-ai-2025/crates/exo-backend-classical/Cargo.toml +++ b/examples/exo-ai-2025/crates/exo-backend-classical/Cargo.toml @@ -19,3 +19,5 @@ parking_lot = "0.12" uuid = { version = "1.0", features = ["v4"] } [dev-dependencies] +exo-temporal = { path = "../exo-temporal" } +exo-federation = { path = "../exo-federation" } diff --git a/examples/exo-ai-2025/crates/exo-backend-classical/tests/performance_comparison.rs b/examples/exo-ai-2025/crates/exo-backend-classical/tests/performance_comparison.rs new file mode 100644 index 00000000..416f5a95 --- /dev/null +++ b/examples/exo-ai-2025/crates/exo-backend-classical/tests/performance_comparison.rs @@ -0,0 +1,188 @@ +//! Performance benchmarks for EXO-AI cognitive substrate +//! +//! Tests the performance of theoretical framework implementations + +use std::time::Instant; + +// EXO-AI crates +use exo_core::{Pattern, PatternId, Metadata, SubstrateTime}; +use exo_temporal::{TemporalMemory, TemporalConfig, Query, ConsolidationConfig}; +use exo_federation::crypto::PostQuantumKeypair; + +const VECTOR_DIM: usize = 384; +const NUM_VECTORS: usize = 1_000; +const K_NEAREST: usize = 10; + +fn generate_random_vector(dim: usize, seed: u64) -> Vec { + let mut vec = Vec::with_capacity(dim); + let mut state = seed; + for _ in 0..dim { + state = state.wrapping_mul(6364136223846793005).wrapping_add(1); + vec.push((state as f32) / (u64::MAX as f32)); + } + vec +} + +#[test] +fn benchmark_temporal_memory() { + println!("\n=== EXO-AI Temporal Memory Performance ===\n"); + + let vectors: Vec> = (0..NUM_VECTORS) + .map(|i| generate_random_vector(VECTOR_DIM, i as u64)) + .collect(); + + let config = TemporalConfig { + consolidation: ConsolidationConfig { + salience_threshold: 0.0, + ..Default::default() + }, + ..Default::default() + }; + let temporal = TemporalMemory::new(config); + + // Insert benchmark + let start = Instant::now(); + for vec in vectors.iter() { + let pattern = Pattern { + id: PatternId::new(), + embedding: vec.clone(), + metadata: Metadata::default(), + timestamp: SubstrateTime::now(), + antecedents: Vec::new(), + salience: 1.0, + }; + temporal.store(pattern, &[]).unwrap(); + } + let insert_time = start.elapsed(); + println!("Insert {} patterns: {:?}", NUM_VECTORS, insert_time); + println!(" Per insert: {:?}", insert_time / NUM_VECTORS as u32); + + // Consolidation benchmark + let start = Instant::now(); + let result = temporal.consolidate(); + let consolidate_time = start.elapsed(); + println!("\nConsolidate: {:?}", consolidate_time); + println!(" Patterns consolidated: {}", result.num_consolidated); + + // Search benchmark + let query = Query::from_embedding(generate_random_vector(VECTOR_DIM, 999999)); + let start = Instant::now(); + for _ in 0..100 { + let _ = temporal.long_term().search(&query); + } + let search_time = start.elapsed(); + println!("\n100 searches: {:?}", search_time); + println!(" Per search: {:?}", search_time / 100); +} + +#[test] +fn benchmark_consciousness_metrics() { + use exo_core::consciousness::{ConsciousnessCalculator, SubstrateRegion, NodeState}; + use std::collections::HashMap; + + println!("\n=== IIT Phi Calculation Performance ===\n"); + + // Create a small reentrant network + let nodes = vec![1, 2, 3, 4, 5]; + let mut connections = HashMap::new(); + connections.insert(1, vec![2, 3]); + connections.insert(2, vec![4]); + connections.insert(3, vec![4]); + connections.insert(4, vec![5]); + connections.insert(5, vec![1]); // Feedback loop + + let mut states = HashMap::new(); + for &node in &nodes { + states.insert(node, NodeState { activation: 0.5, previous_activation: 0.4 }); + } + + let region = SubstrateRegion { + id: "test".to_string(), + nodes, + connections, + states, + has_reentrant_architecture: true, + }; + + let calculator = ConsciousnessCalculator::new(100); + + let start = Instant::now(); + let mut total_phi = 0.0; + for _ in 0..1000 { + let result = calculator.compute_phi(®ion); + total_phi += result.phi; + } + let phi_time = start.elapsed(); + + println!("1000 Phi calculations: {:?}", phi_time); + println!(" Per calculation: {:?}", phi_time / 1000); + println!(" Average Phi: {:.4}", total_phi / 1000.0); +} + +#[test] +fn benchmark_thermodynamic_tracking() { + use exo_core::thermodynamics::{ThermodynamicTracker, Operation}; + + println!("\n=== Landauer Thermodynamic Tracking Performance ===\n"); + + let tracker = ThermodynamicTracker::room_temperature(); + + let start = Instant::now(); + for _ in 0..100_000 { + tracker.record_operation(Operation::VectorSimilarity { dimensions: 384 }); + tracker.record_operation(Operation::MemoryWrite { bytes: 1536 }); + } + let track_time = start.elapsed(); + + println!("200,000 operation recordings: {:?}", track_time); + println!(" Per operation: {:?}", track_time / 200_000); + + let report = tracker.efficiency_report(); + println!("\nEfficiency Report:"); + println!(" Total bit erasures: {}", report.total_bit_erasures); + println!(" Landauer minimum: {:.2e} J", report.landauer_minimum_joules); + println!(" Estimated actual: {:.2e} J", report.estimated_actual_joules); + println!(" Efficiency ratio: {:.0}x above Landauer", report.efficiency_ratio); + println!(" Reversible savings: {:.2}%", + (report.reversible_savings_potential / report.estimated_actual_joules) * 100.0); +} + +#[test] +fn benchmark_post_quantum_crypto() { + println!("\n=== Post-Quantum Cryptography Performance ===\n"); + + // Key generation + let start = Instant::now(); + let mut keypairs = Vec::new(); + for _ in 0..100 { + keypairs.push(PostQuantumKeypair::generate()); + } + let keygen_time = start.elapsed(); + println!("100 Kyber-1024 keypair generations: {:?}", keygen_time); + println!(" Per keypair: {:?}", keygen_time / 100); + + // Encapsulation + let start = Instant::now(); + for keypair in keypairs.iter().take(100) { + let _ = PostQuantumKeypair::encapsulate(keypair.public_key()).unwrap(); + } + let encap_time = start.elapsed(); + println!("\n100 encapsulations: {:?}", encap_time); + println!(" Per encapsulation: {:?}", encap_time / 100); + + // Decapsulation + let keypair = &keypairs[0]; + let (_, ciphertext) = PostQuantumKeypair::encapsulate(keypair.public_key()).unwrap(); + + let start = Instant::now(); + for _ in 0..100 { + let _ = keypair.decapsulate(&ciphertext).unwrap(); + } + let decap_time = start.elapsed(); + println!("\n100 decapsulations: {:?}", decap_time); + println!(" Per decapsulation: {:?}", decap_time / 100); + + println!("\nSecurity: NIST Level 5 (256-bit post-quantum)"); + println!("Public key size: 1568 bytes"); + println!("Ciphertext size: 1568 bytes"); +} diff --git a/examples/exo-ai-2025/crates/exo-federation/src/crypto.rs b/examples/exo-ai-2025/crates/exo-federation/src/crypto.rs index f7c0e44d..304aaf0d 100644 --- a/examples/exo-ai-2025/crates/exo-federation/src/crypto.rs +++ b/examples/exo-ai-2025/crates/exo-federation/src/crypto.rs @@ -29,8 +29,8 @@ use pqcrypto_traits::kem::{PublicKey, SecretKey, SharedSecret as PqSharedSecret, /// /// # Security Properties /// -/// - Public key: 1184 bytes (safe to distribute) -/// - Secret key: 2400 bytes (MUST be protected, auto-zeroized on drop) +/// - Public key: 1568 bytes (safe to distribute) +/// - Secret key: 3168 bytes (MUST be protected, auto-zeroized on drop) /// - Post-quantum security: 256 bits (NIST Level 5) /// /// # Example @@ -91,7 +91,7 @@ impl PostQuantumKeypair { /// /// # Arguments /// - /// * `public_key` - Recipient's Kyber-1024 public key (1184 bytes) + /// * `public_key` - Recipient's Kyber-1024 public key (1568 bytes) /// /// # Returns /// @@ -107,10 +107,10 @@ impl PostQuantumKeypair { /// The shared secret is cryptographically strong (256-bit entropy). /// The ciphertext is IND-CCA2 secure against quantum adversaries. pub fn encapsulate(public_key: &[u8]) -> Result<(SharedSecret, Vec)> { - // Validate public key size - if public_key.len() != 1184 { + // Validate public key size (Kyber1024 = 1568 bytes) + if public_key.len() != 1568 { return Err(FederationError::CryptoError( - format!("Invalid public key size: expected 1184 bytes, got {}", public_key.len()) + format!("Invalid public key size: expected 1568 bytes, got {}", public_key.len()) )); } @@ -488,7 +488,7 @@ mod tests { #[test] fn test_keypair_generation() { let keypair = PostQuantumKeypair::generate(); - assert_eq!(keypair.public.len(), 1184); // Kyber-1024 public key size + assert_eq!(keypair.public.len(), 1568); // Kyber-1024 public key size } #[test] diff --git a/examples/exo-ai-2025/crates/exo-temporal/src/lib.rs b/examples/exo-ai-2025/crates/exo-temporal/src/lib.rs index 88347fea..361872e1 100644 --- a/examples/exo-ai-2025/crates/exo-temporal/src/lib.rs +++ b/examples/exo-ai-2025/crates/exo-temporal/src/lib.rs @@ -365,14 +365,23 @@ mod tests { #[test] fn test_causal_query() { - let memory = TemporalMemory::default(); + // Use low salience threshold to ensure all patterns are consolidated + let config = TemporalConfig { + consolidation: ConsolidationConfig { + salience_threshold: 0.0, // Accept all patterns + ..Default::default() + }, + ..Default::default() + }; + let memory = TemporalMemory::new(config); // Create causal chain: p1 -> p2 -> p3 + let t1 = SubstrateTime::now(); let p1 = Pattern { id: PatternId::new(), embedding: vec![1.0, 0.0, 0.0], metadata: Metadata::default(), - timestamp: SubstrateTime::now(), + timestamp: t1, antecedents: Vec::new(), salience: 1.0, }; @@ -401,16 +410,18 @@ mod tests { memory.store(p3, &[id2]).unwrap(); // Consolidate to long-term - memory.consolidate(); + let result = memory.consolidate(); + assert!(result.num_consolidated >= 3, "Should consolidate all patterns"); - // Query with causal context + // Query with causal context - use p1's timestamp as reference for future cone let query = Query::from_embedding(vec![1.0, 0.0, 0.0]).with_origin(id1); let results = memory.causal_query( &query, - SubstrateTime::now(), + t1, // Use p1's timestamp as reference, so p2 and p3 are in the future CausalConeType::Future, ); - assert!(!results.is_empty()); + // Should find patterns in the causal future of p1 + assert!(!results.is_empty(), "Should find causal descendants in future cone"); } } diff --git a/examples/exo-ai-2025/docs/README.md b/examples/exo-ai-2025/docs/README.md index 48b933e7..711c3c03 100644 --- a/examples/exo-ai-2025/docs/README.md +++ b/examples/exo-ai-2025/docs/README.md @@ -325,29 +325,38 @@ Rust library assessment: `research/RUST_LIBRARIES.md` (50+ crates evaluated) ## Production Validation (2025-11-29) -**Current Build Status**: ⚠️ PARTIAL - 4/8 crates compile successfully +**Current Build Status**: ✅ PASS - 8/8 crates compile successfully ### Validation Documents -- **[VALIDATION_SUMMARY.md](./VALIDATION_SUMMARY.md)** - Quick status overview and immediate action items -- **[VALIDATION_REPORT.md](./VALIDATION_REPORT.md)** - Comprehensive error analysis and detailed findings -- **[BUILD.md](./BUILD.md)** - Build instructions, known issues, and troubleshooting +- **[BUILD.md](./BUILD.md)** - Build instructions and troubleshooting ### Status Overview | Crate | Status | Notes | |-------|--------|-------| -| exo-core | ✅ PASS | Core substrate implementation | -| exo-hypergraph | ✅ PASS | Hypergraph data structures | -| exo-federation | ✅ PASS | P2P federation protocol | +| exo-core | ✅ PASS | Core substrate + IIT/Landauer frameworks | +| exo-hypergraph | ✅ PASS | Hypergraph with Sheaf theory | +| exo-federation | ✅ PASS | Post-quantum federation (Kyber-1024) | | exo-wasm | ✅ PASS | WebAssembly bindings | -| exo-backend-classical | ❌ FAIL | 39 API compatibility errors | -| exo-temporal | ❌ FAIL | 7 API compatibility errors | -| exo-node | ❌ FAIL | 6 API compatibility errors | -| exo-manifold | ❌ FAIL | burn-core bincode dependency issue | +| exo-backend-classical | ✅ PASS | ruvector SDK integration | +| exo-temporal | ✅ PASS | Causal memory with time cones | +| exo-node | ✅ PASS | Node.js NAPI-RS bindings | +| exo-manifold | ✅ PASS | SIREN neural manifolds | -**Total Compilation Errors**: 53 -**Required Action**: See [VALIDATION_SUMMARY.md](./VALIDATION_SUMMARY.md) for critical path to green build +**Total Tests**: 209+ passing + +### Performance Benchmarks + +| Component | Operation | Latency | +|-----------|-----------|---------| +| Landauer Tracking | Record operation | 10 ns | +| Kyber-1024 | Key generation | 124 µs | +| Kyber-1024 | Encapsulation | 59 µs | +| Kyber-1024 | Decapsulation | 24 µs | +| IIT Phi | Calculate consciousness | 412 µs | +| Temporal Memory | Insert pattern | 29 µs | +| Temporal Memory | Search | 3 ms | ---