Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,268 @@
# EXO-AI 2025 Integration Tests
This directory contains comprehensive integration tests for the cognitive substrate platform.
## Test Organization
### Test Files
- **`substrate_integration.rs`** - Complete substrate workflow tests
- Pattern storage and retrieval
- Manifold deformation
- Strategic forgetting
- Bulk operations
- Filtered queries
- **`hypergraph_integration.rs`** - Hypergraph substrate tests
- Hyperedge creation and querying
- Persistent homology computation
- Betti number calculation
- Sheaf consistency checking
- Complex relational queries
- **`temporal_integration.rs`** - Temporal memory coordinator tests
- Causal storage and queries
- Light-cone constraints
- Memory consolidation
- Predictive anticipation
- Temporal knowledge graphs
- **`federation_integration.rs`** - Federated mesh tests
- CRDT merge operations
- Byzantine consensus
- Post-quantum handshakes
- Onion-routed queries
- Network partition tolerance
### Test Utilities
The `common/` directory contains shared testing infrastructure:
- **`fixtures.rs`** - Test data generators and builders
- **`assertions.rs`** - Domain-specific assertion functions
- **`helpers.rs`** - Utility functions for testing
## Running Tests
### Quick Start
```bash
# Run all tests (currently all ignored until crates implemented)
cargo test --workspace
# Run tests with output
cargo test --workspace -- --nocapture
# Run specific test file
cargo test --test substrate_integration
# Run tests matching a pattern
cargo test causal
```
### Using the Test Runner Script
```bash
# Standard test run
./scripts/run-integration-tests.sh
# Verbose output
./scripts/run-integration-tests.sh --verbose
# Parallel execution
./scripts/run-integration-tests.sh --parallel
# Generate coverage report
./scripts/run-integration-tests.sh --coverage
# Run specific tests
./scripts/run-integration-tests.sh --filter "causal"
```
## Test-Driven Development (TDD) Workflow
These integration tests are written **BEFORE** implementation to define expected behavior.
### Current State
All tests are marked with `#[ignore]` because the crates don't exist yet.
### Implementation Workflow
1. **Implementer selects a test** (e.g., `test_substrate_store_and_retrieve`)
2. **Reads the test to understand requirements**
3. **Implements the crate to satisfy the test**
4. **Removes `#[ignore]` from the test**
5. **Runs `cargo test` to verify**
6. **Iterates until test passes**
### Example: Implementing Substrate Storage
```rust
// 1. Read the test in substrate_integration.rs
#[tokio::test]
#[ignore] // <- Remove this line when implementing
async fn test_substrate_store_and_retrieve() {
// The test shows expected API:
let config = SubstrateConfig::default();
let backend = ClassicalBackend::new(config).unwrap();
// ... etc
}
// 2. Implement exo-core and exo-backend-classical to match
// 3. Remove #[ignore] and run:
cargo test --test substrate_integration
// 4. Iterate until passing
```
## Test Requirements for Implementers
### exo-core
**Required types:**
- `Pattern` - Pattern with embedding, metadata, timestamp, antecedents
- `Query` - Query specification
- `SubstrateConfig` - Configuration
- `SearchResult` - Search result with score
- `SubstrateBackend` trait - Backend abstraction
- `TemporalContext` trait - Temporal operations
**Expected methods:**
- `SubstrateInstance::new(backend)` - Create substrate
- `substrate.store(pattern)` - Store pattern
- `substrate.search(query, k)` - Similarity search
### exo-manifold
**Required types:**
- `ManifoldEngine` - Learned manifold storage
- `ManifoldDelta` - Deformation result
**Expected methods:**
- `ManifoldEngine::new(config)` - Initialize
- `manifold.retrieve(tensor, k)` - Gradient descent retrieval
- `manifold.deform(pattern, salience)` - Continuous deformation
- `manifold.forget(region, decay_rate)` - Strategic forgetting
### exo-hypergraph
**Required types:**
- `HypergraphSubstrate` - Hypergraph storage
- `Hyperedge` - Multi-entity relationship
- `TopologicalQuery` - Topology query spec
- `PersistenceDiagram` - Homology results
**Expected methods:**
- `hypergraph.create_hyperedge(entities, relation)` - Create hyperedge
- `hypergraph.persistent_homology(dim, range)` - Compute persistence
- `hypergraph.betti_numbers(max_dim)` - Topological invariants
- `hypergraph.check_sheaf_consistency(sections)` - Sheaf check
### exo-temporal
**Required types:**
- `TemporalMemory` - Temporal coordinator
- `CausalConeType` - Cone specification
- `CausalResult` - Result with causal metadata
- `AnticipationHint` - Pre-fetch hint
**Expected methods:**
- `temporal.store(pattern, antecedents)` - Store with causality
- `temporal.causal_query(query, time, cone)` - Causal retrieval
- `temporal.consolidate()` - Short-term to long-term
- `temporal.anticipate(hints)` - Pre-fetch
### exo-federation
**Required types:**
- `FederatedMesh` - Federation coordinator
- `FederationScope` - Query scope
- `StateUpdate` - CRDT update
- `CommitProof` - Consensus proof
**Expected methods:**
- `mesh.join_federation(peer)` - Federation handshake
- `mesh.federated_query(query, scope)` - Distributed query
- `mesh.byzantine_commit(update)` - Consensus
- `mesh.merge_crdt_state(state)` - CRDT reconciliation
## Performance Targets
Integration tests should verify these performance characteristics:
| Operation | Target Latency | Notes |
|-----------|----------------|-------|
| Pattern storage | < 1ms | Classical backend |
| Similarity search (k=10) | < 10ms | 10K patterns |
| Manifold deformation | < 100ms | Single pattern |
| Hypergraph query | < 50ms | 1K entities |
| Causal query | < 20ms | 10K temporal patterns |
| CRDT merge | < 5ms | 100 operations |
| Consensus round | < 200ms | 4 nodes, no faults |
## Test Coverage Goals
- **Statement coverage**: > 80%
- **Branch coverage**: > 75%
- **Function coverage**: > 80%
Run with coverage:
```bash
cargo tarpaulin --workspace --out Html --output-dir coverage
```
## Debugging Failed Tests
### Enable Logging
```bash
RUST_LOG=debug cargo test --test substrate_integration -- --nocapture
```
### Run Single Test
```bash
cargo test --test substrate_integration test_substrate_store_and_retrieve -- --nocapture
```
### Use Test Helpers
```rust
use common::helpers::*;
init_test_logger(); // Enable logging in test
let (result, duration) = measure_async(async {
substrate.search(query, 10).await
}).await;
println!("Query took {:?}", duration);
```
## Contributing Tests
When adding new integration tests:
1. **Follow existing patterns** - Use the same structure as current tests
2. **Use test utilities** - Leverage `common/` helpers
3. **Document expectations** - Comment expected behavior clearly
4. **Mark as ignored** - Add `#[ignore]` until implementation ready
5. **Add to README** - Document what the test verifies
## CI/CD Integration
These tests run in CI on:
- Every pull request
- Main branch commits
- Nightly builds
CI configuration: `.github/workflows/integration-tests.yml` (to be created)
## Questions?
See the main project documentation:
- Architecture: `../architecture/ARCHITECTURE.md`
- Specification: `../specs/SPECIFICATION.md`
- Pseudocode: `../architecture/PSEUDOCODE.md`

View File

@@ -0,0 +1,116 @@
//! Custom assertions for integration tests
//!
//! Provides domain-specific assertions for cognitive substrate testing.
#![allow(dead_code)]
/// Assert two embeddings are approximately equal (within epsilon)
pub fn assert_embeddings_approx_equal(a: &[f32], b: &[f32], epsilon: f32) {
assert_eq!(
a.len(),
b.len(),
"Embeddings have different dimensions: {} vs {}",
a.len(),
b.len()
);
for (i, (av, bv)) in a.iter().zip(b.iter()).enumerate() {
let diff = (av - bv).abs();
assert!(
diff < epsilon,
"Embedding mismatch at index {}: |{} - {}| = {} >= {}",
i,
av,
bv,
diff,
epsilon
);
}
}
/// Assert similarity scores are in descending order
pub fn assert_scores_descending(scores: &[f32]) {
for window in scores.windows(2) {
assert!(
window[0] >= window[1],
"Scores not in descending order: {} < {}",
window[0],
window[1]
);
}
}
/// Assert causal ordering is respected
pub fn assert_causal_order(results: &[String], expected_order: &[String]) {
// TODO: Implement once CausalResult type exists
// Verify results respect causal dependencies
assert_eq!(results.len(), expected_order.len(), "Result count mismatch");
}
/// Assert CRDT states are convergent
pub fn assert_crdt_convergence(state1: &str, state2: &str) {
// TODO: Implement once CRDT types exist
// Verify eventual consistency
assert_eq!(state1, state2, "CRDT states did not converge");
}
/// Assert topological invariants match expected values
pub fn assert_betti_numbers(betti: &[usize], expected: &[usize]) {
assert_eq!(
betti.len(),
expected.len(),
"Betti number dimension mismatch"
);
for (i, (actual, exp)) in betti.iter().zip(expected.iter()).enumerate() {
assert_eq!(
actual, exp,
"Betti number b_{} mismatch: {} != {}",
i, actual, exp
);
}
}
/// Assert consensus proof is valid
pub fn assert_valid_consensus_proof(proof: &str, threshold: usize) {
// TODO: Implement once CommitProof type exists
// Verify proof has sufficient signatures
assert!(
!proof.is_empty(),
"Consensus proof is empty (need {} votes)",
threshold
);
}
/// Assert temporal ordering is consistent
pub fn assert_temporal_order(timestamps: &[u64]) {
for window in timestamps.windows(2) {
assert!(
window[0] <= window[1],
"Timestamps not in temporal order: {} > {}",
window[0],
window[1]
);
}
}
/// Assert pattern is within manifold region
pub fn assert_in_manifold_region(embedding: &[f32], center: &[f32], radius: f32) {
let distance = euclidean_distance(embedding, center);
assert!(
distance <= radius,
"Pattern outside manifold region: distance {} > radius {}",
distance,
radius
);
}
// Helper: Compute Euclidean distance
fn euclidean_distance(a: &[f32], b: &[f32]) -> f32 {
assert_eq!(a.len(), b.len());
a.iter()
.zip(b.iter())
.map(|(av, bv)| (av - bv).powi(2))
.sum::<f32>()
.sqrt()
}

View File

@@ -0,0 +1,80 @@
//! Test fixtures and data builders
//!
//! Provides reusable test data and configuration builders.
#![allow(dead_code)]
/// Generate test embeddings with known patterns
pub fn generate_test_embeddings(count: usize, dimensions: usize) -> Vec<Vec<f32>> {
// TODO: Implement once exo-core types are available
// Generate diverse embeddings for testing
// Use deterministic seed for reproducibility
(0..count)
.map(|i| {
(0..dimensions)
.map(|d| ((i * dimensions + d) as f32).sin())
.collect()
})
.collect()
}
/// Generate clustered embeddings (for testing similarity)
pub fn generate_clustered_embeddings(
clusters: usize,
per_cluster: usize,
dimensions: usize,
) -> Vec<Vec<f32>> {
// TODO: Implement clustering logic
// Create distinct clusters in embedding space
vec![vec![0.0; dimensions]; clusters * per_cluster]
}
/// Create a test pattern with default values
pub fn create_test_pattern(embedding: Vec<f32>) -> String {
// TODO: Return actual Pattern once exo-core exists
// For now, return placeholder
format!("TestPattern({:?})", &embedding[..embedding.len().min(3)])
}
/// Create a test hypergraph with known topology
pub fn create_test_hypergraph() -> String {
// TODO: Build test hypergraph once exo-hypergraph exists
// Should include:
// - Multiple connected components
// - Some 1-dimensional holes (cycles)
// - Some 2-dimensional holes (voids)
"TestHypergraph".to_string()
}
/// Create a causal chain for testing temporal memory
pub fn create_causal_chain(length: usize) -> Vec<String> {
// TODO: Create linked patterns once exo-temporal exists
// Returns pattern IDs in causal order
(0..length).map(|i| format!("pattern_{}", i)).collect()
}
/// Create a federation of test nodes
pub async fn create_test_federation(node_count: usize) -> Vec<String> {
// TODO: Implement once exo-federation exists
// Returns federation node handles
(0..node_count)
.map(|i| format!("node_{}", i))
.collect()
}
/// Default test configuration
pub fn default_test_config() -> TestConfig {
TestConfig {
timeout_ms: 5000,
log_level: "info".to_string(),
seed: 42,
}
}
#[derive(Debug, Clone)]
pub struct TestConfig {
pub timeout_ms: u64,
pub log_level: String,
pub seed: u64,
}

View File

@@ -0,0 +1,130 @@
//! Test helper functions
//!
//! Provides utility functions for integration testing.
#![allow(dead_code)]
use std::time::Duration;
use tokio::time::timeout;
/// Run async test with timeout
pub async fn with_timeout<F, T>(duration: Duration, future: F) -> Result<T, String>
where
F: std::future::Future<Output = T>,
{
match timeout(duration, future).await {
Ok(result) => Ok(result),
Err(_) => Err(format!("Test timed out after {:?}", duration)),
}
}
/// Initialize test logger
pub fn init_test_logger() {
// Initialize tracing/logging for tests
// Only initialize once
let _ = env_logger::builder()
.is_test(true)
.filter_level(log::LevelFilter::Info)
.try_init();
}
/// Generate deterministic random data for testing
pub fn deterministic_random_vec(seed: u64, len: usize) -> Vec<f32> {
// Simple LCG for deterministic "random" numbers
let mut state = seed;
(0..len)
.map(|_| {
state = state.wrapping_mul(1103515245).wrapping_add(12345);
((state / 65536) % 32768) as f32 / 32768.0
})
.collect()
}
/// Measure execution time of a function
pub async fn measure_async<F, T>(f: F) -> (T, Duration)
where
F: std::future::Future<Output = T>,
{
let start = std::time::Instant::now();
let result = f.await;
let duration = start.elapsed();
(result, duration)
}
/// Compare vectors with tolerance
pub fn vectors_approx_equal(a: &[f32], b: &[f32], tolerance: f32) -> bool {
if a.len() != b.len() {
return false;
}
a.iter()
.zip(b.iter())
.all(|(av, bv)| (av - bv).abs() < tolerance)
}
/// Cosine similarity
pub fn cosine_similarity(a: &[f32], b: &[f32]) -> f32 {
assert_eq!(a.len(), b.len());
let dot_product: f32 = a.iter().zip(b.iter()).map(|(av, bv)| av * bv).sum();
let norm_a: f32 = a.iter().map(|av| av * av).sum::<f32>().sqrt();
let norm_b: f32 = b.iter().map(|bv| bv * bv).sum::<f32>().sqrt();
if norm_a == 0.0 || norm_b == 0.0 {
0.0
} else {
dot_product / (norm_a * norm_b)
}
}
/// Wait for async condition to become true
pub async fn wait_for_condition<F>(
mut condition: F,
timeout_duration: Duration,
check_interval: Duration,
) -> Result<(), String>
where
F: FnMut() -> bool,
{
let start = std::time::Instant::now();
while start.elapsed() < timeout_duration {
if condition() {
return Ok(());
}
tokio::time::sleep(check_interval).await;
}
Err(format!(
"Condition not met within {:?}",
timeout_duration
))
}
/// Create a temporary test directory
pub fn create_temp_test_dir() -> std::io::Result<std::path::PathBuf> {
let temp_dir = std::env::temp_dir().join(format!("exo-test-{}", uuid::Uuid::new_v4()));
std::fs::create_dir_all(&temp_dir)?;
Ok(temp_dir)
}
/// Clean up test resources
pub async fn cleanup_test_resources(path: &std::path::Path) -> std::io::Result<()> {
if path.exists() {
tokio::fs::remove_dir_all(path).await?;
}
Ok(())
}
// Mock UUID for tests (replace with actual uuid crate when available)
mod uuid {
pub struct Uuid;
impl Uuid {
pub fn new_v4() -> String {
format!("{:016x}", std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos())
}
}
}

View File

@@ -0,0 +1,12 @@
//! Common test utilities and helpers for integration tests
//!
//! This module provides shared functionality across all integration tests.
pub mod fixtures;
pub mod assertions;
pub mod helpers;
// Re-export commonly used items
pub use fixtures::*;
pub use assertions::*;
pub use helpers::*;

View File

@@ -0,0 +1,246 @@
//! Integration Tests: Federated Cognitive Mesh
//!
//! These tests verify distributed substrate capabilities including:
//! - Post-quantum key exchange
//! - CRDT reconciliation
//! - Byzantine fault tolerant consensus
//! - Federated query routing
#[cfg(test)]
mod federation_tests {
// Note: These imports will be available once crates are implemented
// use exo_federation::{FederatedMesh, FederationScope, StateUpdate};
// use exo_core::{Query, Pattern};
/// Test: CRDT merge operations for conflict-free reconciliation
///
/// Flow:
/// 1. Create two federated nodes
/// 2. Each node stores different patterns
/// 3. Merge CRDT states
/// 4. Verify both nodes have consistent view
#[tokio::test]
#[ignore] // Remove when exo-federation exists
async fn test_crdt_merge_reconciliation() {
// TODO: Implement once exo-federation exists
// Expected API:
// let node1 = FederatedMesh::new("node1").await.unwrap();
// let node2 = FederatedMesh::new("node2").await.unwrap();
//
// // Node 1 stores pattern A
// let pattern_a = Pattern { embedding: vec![1.0, 0.0], ... };
// node1.store(pattern_a.clone()).await.unwrap();
//
// // Node 2 stores pattern B
// let pattern_b = Pattern { embedding: vec![0.0, 1.0], ... };
// node2.store(pattern_b.clone()).await.unwrap();
//
// // Export CRDT states
// let state1 = node1.export_crdt_state().await.unwrap();
// let state2 = node2.export_crdt_state().await.unwrap();
//
// // Merge states (commutative, associative, idempotent)
// node1.merge_crdt_state(state2).await.unwrap();
// node2.merge_crdt_state(state1).await.unwrap();
//
// // Verify convergence: both nodes have A and B
// let results1 = node1.list_all_patterns().await.unwrap();
// let results2 = node2.list_all_patterns().await.unwrap();
//
// assert_eq!(results1.len(), 2);
// assert_eq!(results2.len(), 2);
// assert_eq!(results1, results2); // Identical state
panic!("Implement this test once exo-federation crate exists");
}
/// Test: Byzantine fault tolerant consensus
///
/// Verifies consensus can tolerate f Byzantine faults for n=3f+1 nodes.
#[tokio::test]
#[ignore]
async fn test_byzantine_consensus() {
// TODO: Implement once exo-federation exists
// Expected behavior:
// - Create 4 nodes (tolerate 1 Byzantine fault)
// - Propose state update
// - Simulate 1 Byzantine node sending conflicting votes
// - Verify honest majority reaches consensus
// Expected API:
// let nodes = create_federation(4).await;
//
// let update = StateUpdate { ... };
//
// // Honest nodes (0, 1, 2)
// let votes = vec![
// nodes[0].vote_on_update(&update).await.unwrap(),
// nodes[1].vote_on_update(&update).await.unwrap(),
// nodes[2].vote_on_update(&update).await.unwrap(),
// ];
//
// // Byzantine node sends conflicting vote
// let byzantine_vote = create_conflicting_vote(&update);
//
// // Collect all votes
// let all_votes = [votes, vec![byzantine_vote]].concat();
//
// // Verify consensus reached despite Byzantine node
// let proof = nodes[0].finalize_consensus(&all_votes).await.unwrap();
// assert!(proof.is_valid());
panic!("Implement this test once exo-federation crate exists");
}
/// Test: Post-quantum key exchange and encrypted channel
///
/// Verifies CRYSTALS-Kyber key exchange for federation handshake.
#[tokio::test]
#[ignore]
async fn test_post_quantum_handshake() {
// TODO: Implement once exo-federation exists
// Expected API:
// let node1 = FederatedMesh::new("node1").await.unwrap();
// let node2 = FederatedMesh::new("node2").await.unwrap();
//
// // Node 1 initiates federation
// let token = node1.join_federation(&node2.address()).await.unwrap();
//
// // Verify encrypted channel established
// assert!(token.channel.is_encrypted());
// assert_eq!(token.channel.crypto_algorithm(), "CRYSTALS-Kyber");
//
// // Send encrypted message
// let message = "test message";
// token.channel.send(message).await.unwrap();
//
// // Node 2 receives and decrypts
// let received = node2.receive().await.unwrap();
// assert_eq!(received, message);
panic!("Implement this test once exo-federation crate exists");
}
/// Test: Federated query with onion routing
///
/// Verifies privacy-preserving query routing across federation.
#[tokio::test]
#[ignore]
async fn test_onion_routed_federated_query() {
// TODO: Implement once exo-federation exists
// Expected API:
// let federation = create_federation(5).await;
//
// // Store pattern on node 4
// let pattern = Pattern { ... };
// federation.nodes[4].store(pattern.clone()).await.unwrap();
//
// // Node 0 queries through onion network
// let query = Query::from_embedding(pattern.embedding.clone());
// let scope = FederationScope::Full;
// let results = federation.nodes[0].federated_query(&query, scope).await.unwrap();
//
// // Should find pattern without revealing query origin
// assert_eq!(results.len(), 1);
// assert_eq!(results[0].pattern.id, pattern.id);
//
// // Verify intermediate nodes don't know query origin
// // (This would require instrumentation/logging)
panic!("Implement this test once exo-federation crate exists");
}
/// Test: CRDT concurrent updates
///
/// Verifies CRDTs handle concurrent conflicting updates correctly.
#[tokio::test]
#[ignore]
async fn test_crdt_concurrent_updates() {
// TODO: Implement once exo-federation exists
// Scenario:
// - Two nodes concurrently update same pattern
// - Verify CRDT reconciliation produces consistent result
// - Test all CRDT types: G-Set, LWW-Register, Counter
panic!("Implement this test once exo-federation crate exists");
}
/// Test: Federation with partial connectivity
///
/// Verifies system handles network partitions gracefully.
#[tokio::test]
#[ignore]
async fn test_network_partition_tolerance() {
// TODO: Implement once exo-federation exists
// Expected:
// - Create 6-node federation
// - Partition into two groups (3 + 3)
// - Verify each partition continues operation
// - Heal partition
// - Verify eventual consistency after healing
panic!("Implement this test once exo-federation crate exists");
}
/// Test: Consensus timeout and retry
///
/// Verifies consensus protocol handles slow/unresponsive nodes.
#[tokio::test]
#[ignore]
async fn test_consensus_timeout_handling() {
// TODO: Implement once exo-federation exists
// Expected:
// - Create federation with one slow node
// - Propose update with timeout
// - Verify consensus either succeeds without slow node or retries
panic!("Implement this test once exo-federation crate exists");
}
/// Test: Federated query aggregation
///
/// Verifies query results are correctly aggregated from multiple nodes.
#[tokio::test]
#[ignore]
async fn test_federated_query_aggregation() {
// TODO: Implement once exo-federation exists
// Expected:
// - Multiple nodes store different patterns
// - Query aggregates top-k results from all nodes
// - Verify ranking is correct across federation
panic!("Implement this test once exo-federation crate exists");
}
/// Test: Cryptographic sovereignty boundaries
///
/// Verifies federation respects cryptographic access control.
#[tokio::test]
#[ignore]
async fn test_cryptographic_sovereignty() {
// TODO: Implement once exo-federation exists
// Expected:
// - Node stores pattern with access control
// - Unauthorized node attempts query
// - Verify access denied
// - Authorized node with correct key succeeds
panic!("Implement this test once exo-federation crate exists");
}
// Helper function to create test federation
#[allow(dead_code)]
async fn create_federation(_node_count: usize) {
// TODO: Implement helper to build test federation
panic!("Helper not implemented yet");
}
}

View File

@@ -0,0 +1,58 @@
//! Full-stack integration tests: All components together
#[cfg(test)]
mod full_stack_integration {
use super::*;
// use exo_core::*;
// use exo_manifold::*;
// use exo_hypergraph::*;
// use exo_temporal::*;
// use exo_federation::*;
// use exo_backend_classical::*;
#[test]
#[tokio::test]
async fn test_complete_cognitive_substrate() {
// Test complete system: manifold + hypergraph + temporal + federation
//
// // Setup
// let backend = ClassicalBackend::new(config);
// let manifold = ManifoldEngine::new(backend.clone());
// let hypergraph = HypergraphSubstrate::new(backend.clone());
// let temporal = TemporalMemory::new();
// let federation = FederatedMesh::new(fed_config);
//
// // Scenario: Multi-agent collaborative memory
// // 1. Store patterns with temporal context
// let p1 = temporal.store(pattern1, &[]).unwrap();
//
// // 2. Deform manifold
// manifold.deform(&pattern1, 0.8);
//
// // 3. Create hypergraph relationships
// hypergraph.create_hyperedge(&[p1, p2], &relation).unwrap();
//
// // 4. Query with causal constraints
// let results = temporal.causal_query(&query, now, CausalConeType::Past);
//
// // 5. Federate query
// let fed_results = federation.federated_query(&query, FederationScope::Global).await;
//
// // Verify all components work together
// assert!(!results.is_empty());
// assert!(!fed_results.is_empty());
}
#[test]
#[tokio::test]
async fn test_agent_memory_lifecycle() {
// Test complete memory lifecycle:
// Storage -> Consolidation -> Retrieval -> Forgetting -> Federation
}
#[test]
#[tokio::test]
async fn test_cross_component_consistency() {
// Test that all components maintain consistent state
}
}

View File

@@ -0,0 +1,172 @@
//! Integration Tests: Hypergraph Substrate
//!
//! These tests verify higher-order relational reasoning capabilities
//! including hyperedge creation, topological queries, and sheaf consistency.
#[cfg(test)]
mod hypergraph_tests {
// Note: These imports will be available once crates are implemented
// use exo_hypergraph::{HypergraphSubstrate, Hyperedge, TopologicalQuery};
// use exo_core::{EntityId, Relation, Pattern};
/// Test: Create entities and hyperedges, then query topology
///
/// Flow:
/// 1. Create multiple entities in the substrate
/// 2. Create hyperedges spanning multiple entities
/// 3. Query the hypergraph topology
/// 4. Verify hyperedge relationships
#[tokio::test]
#[ignore] // Remove when exo-hypergraph exists
async fn test_hyperedge_creation_and_query() {
// TODO: Implement once exo-hypergraph exists
// Expected API:
// let mut hypergraph = HypergraphSubstrate::new();
//
// // Create entities
// let entity1 = hypergraph.create_entity(Pattern { ... }).await.unwrap();
// let entity2 = hypergraph.create_entity(Pattern { ... }).await.unwrap();
// let entity3 = hypergraph.create_entity(Pattern { ... }).await.unwrap();
//
// // Create hyperedge spanning 3 entities
// let relation = Relation::new("collaborates_on");
// let hyperedge_id = hypergraph.create_hyperedge(
// &[entity1, entity2, entity3],
// &relation
// ).await.unwrap();
//
// // Query hyperedges containing entity1
// let edges = hypergraph.get_hyperedges_for_entity(entity1).await.unwrap();
// assert!(edges.contains(&hyperedge_id));
//
// // Verify all entities are in the hyperedge
// let hyperedge = hypergraph.get_hyperedge(hyperedge_id).await.unwrap();
// assert_eq!(hyperedge.entities.len(), 3);
// assert!(hyperedge.entities.contains(&entity1));
// assert!(hyperedge.entities.contains(&entity2));
// assert!(hyperedge.entities.contains(&entity3));
panic!("Implement this test once exo-hypergraph crate exists");
}
/// Test: Persistent homology computation
///
/// Verifies topological feature extraction across scales.
#[tokio::test]
#[ignore]
async fn test_persistent_homology() {
// TODO: Implement once exo-hypergraph exists
// Expected API:
// let hypergraph = build_test_hypergraph();
//
// // Compute 1-dimensional persistent features (loops/cycles)
// let persistence_diagram = hypergraph.persistent_homology(
// dimension=1,
// epsilon_range=(0.0, 1.0)
// ).await.unwrap();
//
// // Verify persistence pairs
// assert!(!persistence_diagram.pairs.is_empty());
//
// // Check for essential features (never die)
// let essential = persistence_diagram.pairs.iter()
// .filter(|(birth, death)| death.is_infinite())
// .count();
// assert!(essential > 0);
panic!("Implement this test once exo-hypergraph crate exists");
}
/// Test: Betti numbers (topological invariants)
///
/// Verifies computation of connected components and holes.
#[tokio::test]
#[ignore]
async fn test_betti_numbers() {
// TODO: Implement once exo-hypergraph exists
// Expected API:
// let hypergraph = build_test_hypergraph_with_holes();
//
// // Compute Betti numbers up to dimension 2
// let betti = hypergraph.betti_numbers(max_dim=2).await.unwrap();
//
// // b0 = connected components
// // b1 = 1-dimensional holes (loops)
// // b2 = 2-dimensional holes (voids)
// assert_eq!(betti.len(), 3);
// assert!(betti[0] > 0); // At least one connected component
panic!("Implement this test once exo-hypergraph crate exists");
}
/// Test: Sheaf consistency check
///
/// Verifies local-to-global coherence across hypergraph sections.
#[tokio::test]
#[ignore]
async fn test_sheaf_consistency() {
// TODO: Implement once exo-hypergraph exists with sheaf support
// Expected API:
// let hypergraph = HypergraphSubstrate::with_sheaf();
//
// // Create overlapping sections
// let section1 = hypergraph.create_section(entities=[e1, e2], data=...);
// let section2 = hypergraph.create_section(entities=[e2, e3], data=...);
//
// // Check consistency
// let result = hypergraph.check_sheaf_consistency(&[section1, section2]).await.unwrap();
//
// match result {
// SheafConsistencyResult::Consistent => { /* expected */ },
// SheafConsistencyResult::Inconsistent(errors) => {
// panic!("Sheaf inconsistency: {:?}", errors);
// },
// _ => panic!("Unexpected result"),
// }
panic!("Implement this test once exo-hypergraph sheaf support exists");
}
/// Test: Complex relational query
///
/// Verifies ability to query complex multi-entity relationships.
#[tokio::test]
#[ignore]
async fn test_complex_relational_query() {
// TODO: Implement once exo-hypergraph exists
// Scenario:
// - Create a knowledge graph with multiple relation types
// - Query for patterns like "all entities related to X through Y"
// - Verify transitive relationships
panic!("Implement this test once exo-hypergraph crate exists");
}
/// Test: Hypergraph with temporal evolution
///
/// Verifies hypergraph can track changes over time.
#[tokio::test]
#[ignore]
async fn test_temporal_hypergraph() {
// TODO: Implement once exo-hypergraph + exo-temporal integrated
// Expected:
// - Create hyperedges at different timestamps
// - Query hypergraph state at specific time points
// - Verify temporal consistency
panic!("Implement this test once temporal integration exists");
}
// Helper function for building test hypergraphs
#[allow(dead_code)]
fn build_test_hypergraph() {
// TODO: Implement helper to build standard test topology
panic!("Helper not implemented yet");
}
}

View File

@@ -0,0 +1,53 @@
//! Integration tests: Manifold Engine + Hypergraph Substrate
#[cfg(test)]
mod manifold_hypergraph_integration {
use super::*;
// use exo_manifold::*;
// use exo_hypergraph::*;
// use exo_backend_classical::ClassicalBackend;
#[test]
fn test_manifold_with_hypergraph_structure() {
// Test querying manifold with hypergraph topological constraints
// let backend = ClassicalBackend::new(config);
// let mut manifold = ManifoldEngine::new(backend.clone());
// let mut hypergraph = HypergraphSubstrate::new(backend);
//
// // Store patterns in manifold
// let p1 = manifold.deform(pattern1, 0.8);
// let p2 = manifold.deform(pattern2, 0.7);
// let p3 = manifold.deform(pattern3, 0.9);
//
// // Create hyperedges linking patterns
// let relation = Relation::new("semantic_cluster");
// hypergraph.create_hyperedge(&[p1, p2, p3], &relation).unwrap();
//
// // Query manifold and verify hypergraph structure
// let results = manifold.retrieve(query, 10);
//
// // Verify results respect hypergraph topology
// for result in results {
// let edges = hypergraph.hyperedges_containing(result.id);
// assert!(!edges.is_empty()); // Should be connected
// }
}
#[test]
fn test_persistent_homology_on_manifold() {
// Test computing persistent homology on learned manifold
// let manifold = setup_manifold_with_patterns();
// let hypergraph = setup_hypergraph_from_manifold(&manifold);
//
// let diagram = hypergraph.persistent_homology(1, (0.0, 1.0));
//
// // Verify topological features detected
// assert!(diagram.num_features() > 0);
}
#[test]
fn test_hypergraph_guided_retrieval() {
// Test using hypergraph structure to guide manifold retrieval
// Retrieve patterns, then expand via hyperedge traversal
}
}

View File

@@ -0,0 +1,137 @@
//! Integration Tests: Complete Substrate Workflow
//!
//! These tests verify the end-to-end functionality of the cognitive substrate,
//! from pattern storage through querying and retrieval.
#[cfg(test)]
mod substrate_tests {
// Note: These imports will be available once crates are implemented
// use exo_core::{Pattern, Query, SubstrateConfig};
// use exo_backend_classical::ClassicalBackend;
// use exo_manifold::ManifoldEngine;
/// Test: Complete substrate workflow
///
/// Steps:
/// 1. Initialize substrate with classical backend
/// 2. Store multiple patterns with embeddings
/// 3. Query with similarity search
/// 4. Verify results match expected patterns
#[tokio::test]
#[ignore] // Remove this when crates are implemented
async fn test_substrate_store_and_retrieve() {
// TODO: Implement once exo-core and exo-backend-classical exist
// Expected API usage:
// let config = SubstrateConfig::default();
// let backend = ClassicalBackend::new(config).unwrap();
// let substrate = SubstrateInstance::new(backend);
// // Store patterns
// let pattern1 = Pattern {
// embedding: vec![1.0, 0.0, 0.0, 0.0],
// metadata: Metadata::new(),
// timestamp: SubstrateTime::now(),
// antecedents: vec![],
// };
//
// let id1 = substrate.store(pattern1.clone()).await.unwrap();
//
// let pattern2 = Pattern {
// embedding: vec![0.9, 0.1, 0.0, 0.0],
// metadata: Metadata::new(),
// timestamp: SubstrateTime::now(),
// antecedents: vec![],
// };
//
// let id2 = substrate.store(pattern2.clone()).await.unwrap();
//
// // Query
// let query = Query::from_embedding(vec![1.0, 0.0, 0.0, 0.0]);
// let results = substrate.search(query, 2).await.unwrap();
//
// // Verify
// assert_eq!(results.len(), 2);
// assert_eq!(results[0].id, id1); // Closest match
// assert!(results[0].score > results[1].score);
panic!("Implement this test once exo-core crate exists");
}
/// Test: Manifold deformation (continuous learning)
///
/// Verifies that the learned manifold can be deformed to incorporate
/// new patterns without explicit insert operations.
#[tokio::test]
#[ignore]
async fn test_manifold_deformation() {
// TODO: Implement once exo-manifold exists
// Expected API:
// let manifold = ManifoldEngine::new(config);
//
// // Initial query should find nothing
// let query = Tensor::from_floats(&[0.5, 0.5, 0.0, 0.0]);
// let before = manifold.retrieve(query.clone(), 1);
// assert!(before.is_empty());
//
// // Deform manifold with new pattern
// let pattern = Pattern { embedding: vec![0.5, 0.5, 0.0, 0.0], ... };
// manifold.deform(pattern, salience=1.0);
//
// // Now query should find the pattern
// let after = manifold.retrieve(query, 1);
// assert_eq!(after.len(), 1);
panic!("Implement this test once exo-manifold crate exists");
}
/// Test: Strategic forgetting
///
/// Verifies that low-salience patterns decay over time.
#[tokio::test]
#[ignore]
async fn test_strategic_forgetting() {
// TODO: Implement once exo-manifold exists
// Expected behavior:
// 1. Store high-salience and low-salience patterns
// 2. Trigger forgetting
// 3. Verify low-salience patterns are forgotten
// 4. Verify high-salience patterns remain
panic!("Implement this test once exo-manifold crate exists");
}
/// Test: Batch operations and performance
///
/// Verifies substrate can handle bulk operations efficiently.
#[tokio::test]
#[ignore]
async fn test_bulk_operations() {
// TODO: Implement performance test
// Expected:
// - Store 10,000 patterns
// - Batch query 1,000 times
// - Verify latency < 10ms per query (classical backend)
panic!("Implement this test once exo-core crate exists");
}
/// Test: Filter-based queries
///
/// Verifies metadata filtering during similarity search.
#[tokio::test]
#[ignore]
async fn test_filtered_search() {
// TODO: Implement once exo-core exists
// Expected:
// - Store patterns with different metadata tags
// - Query with metadata filter
// - Verify only matching patterns returned
panic!("Implement this test once exo-core crate exists");
}
}

View File

@@ -0,0 +1,47 @@
//! Integration tests: Temporal Memory + Federation
#[cfg(test)]
mod temporal_federation_integration {
use super::*;
// use exo_temporal::*;
// use exo_federation::*;
#[test]
#[tokio::test]
async fn test_federated_temporal_query() {
// Test temporal queries across federation
// let node1 = setup_federated_node_with_temporal(config1);
// let node2 = setup_federated_node_with_temporal(config2);
//
// // Join federation
// node1.join_federation(&node2.address()).await.unwrap();
//
// // Store temporal patterns on node1
// let p1 = node1.temporal_memory.store(pattern1, &[]).unwrap();
// let p2 = node1.temporal_memory.store(pattern2, &[p1]).unwrap();
//
// // Query from node2 with causal constraints
// let query = Query::new("test");
// let results = node2.federated_temporal_query(
// &query,
// SubstrateTime::now(),
// CausalConeType::Past,
// FederationScope::Global
// ).await;
//
// // Should receive results from node1
// assert!(!results.is_empty());
}
#[test]
#[tokio::test]
async fn test_distributed_memory_consolidation() {
// Test memory consolidation across federated nodes
}
#[test]
#[tokio::test]
async fn test_causal_graph_federation() {
// Test causal graph spanning multiple nodes
}
}

View File

@@ -0,0 +1,227 @@
//! Integration Tests: Temporal Memory Coordinator
//!
//! These tests verify causal memory architecture including:
//! - Causal link tracking
//! - Causal cone queries
//! - Memory consolidation
//! - Predictive anticipation
#[cfg(test)]
mod temporal_tests {
// Note: These imports will be available once crates are implemented
// use exo_temporal::{TemporalMemory, CausalConeType, AnticipationHint};
// use exo_core::{Pattern, SubstrateTime, PatternId};
/// Test: Store patterns with causal links, then verify causal queries
///
/// Flow:
/// 1. Store patterns with explicit causal antecedents
/// 2. Build causal graph
/// 3. Query with causal cone constraints
/// 4. Verify only causally-connected patterns returned
#[tokio::test]
#[ignore] // Remove when exo-temporal exists
async fn test_causal_storage_and_query() {
// TODO: Implement once exo-temporal exists
// Expected API:
// let mut temporal_memory = TemporalMemory::new();
//
// // Store pattern A (no antecedents)
// let pattern_a = Pattern { embedding: vec![1.0, 0.0, 0.0], ... };
// let id_a = temporal_memory.store(pattern_a, antecedents=&[]).await.unwrap();
//
// // Store pattern B (caused by A)
// let pattern_b = Pattern { embedding: vec![0.0, 1.0, 0.0], ... };
// let id_b = temporal_memory.store(pattern_b, antecedents=&[id_a]).await.unwrap();
//
// // Store pattern C (caused by B)
// let pattern_c = Pattern { embedding: vec![0.0, 0.0, 1.0], ... };
// let id_c = temporal_memory.store(pattern_c, antecedents=&[id_b]).await.unwrap();
//
// // Query: causal past of C
// let query = Query::from_id(id_c);
// let results = temporal_memory.causal_query(
// &query,
// reference_time=SubstrateTime::now(),
// cone_type=CausalConeType::Past
// ).await.unwrap();
//
// // Should find B and A (causal ancestors)
// assert_eq!(results.len(), 2);
// let ids: Vec<_> = results.iter().map(|r| r.pattern.id).collect();
// assert!(ids.contains(&id_a));
// assert!(ids.contains(&id_b));
//
// // Causal distances should be correct
// let result_a = results.iter().find(|r| r.pattern.id == id_a).unwrap();
// assert_eq!(result_a.causal_distance, 2); // A -> B -> C
panic!("Implement this test once exo-temporal crate exists");
}
/// Test: Causal cone with light-cone constraints
///
/// Verifies relativistic causal constraints on retrieval.
#[tokio::test]
#[ignore]
async fn test_light_cone_query() {
// TODO: Implement once exo-temporal exists
// Expected behavior:
// - Store patterns at different spacetime coordinates
// - Query with light-cone velocity constraint
// - Verify only patterns within light-cone returned
// Expected API:
// let cone_type = CausalConeType::LightCone { velocity: 1.0 };
// let results = temporal_memory.causal_query(
// &query,
// reference_time,
// cone_type
// ).await.unwrap();
//
// for result in results {
// let spatial_dist = distance(query.origin, result.pattern.origin);
// let temporal_dist = (result.timestamp - reference_time).abs();
// assert!(spatial_dist <= velocity * temporal_dist);
// }
panic!("Implement this test once exo-temporal crate exists");
}
/// Test: Memory consolidation from short-term to long-term
///
/// Flow:
/// 1. Fill short-term buffer with patterns of varying salience
/// 2. Trigger consolidation
/// 3. Verify high-salience patterns moved to long-term
/// 4. Verify low-salience patterns forgotten
#[tokio::test]
#[ignore]
async fn test_memory_consolidation() {
// TODO: Implement once exo-temporal exists
// Expected API:
// let mut temporal_memory = TemporalMemory::new();
//
// // Store high-salience patterns
// for _ in 0..10 {
// let pattern = Pattern { salience: 0.9, ... };
// temporal_memory.store(pattern, &[]).await.unwrap();
// }
//
// // Store low-salience patterns
// for _ in 0..10 {
// let pattern = Pattern { salience: 0.1, ... };
// temporal_memory.store(pattern, &[]).await.unwrap();
// }
//
// // Trigger consolidation
// temporal_memory.consolidate().await.unwrap();
//
// // Verify short-term buffer cleared
// assert_eq!(temporal_memory.short_term_count(), 0);
//
// // Verify long-term contains ~10 patterns (high-salience)
// assert!(temporal_memory.long_term_count() >= 8); // Allow some variance
panic!("Implement this test once exo-temporal crate exists");
}
/// Test: Predictive anticipation and pre-fetching
///
/// Verifies substrate can predict future queries and pre-fetch results.
#[tokio::test]
#[ignore]
async fn test_predictive_anticipation() {
// TODO: Implement once exo-temporal exists
// Expected API:
// let mut temporal_memory = TemporalMemory::new();
//
// // Establish sequential pattern: A -> B -> C
// let id_a = store_pattern_a();
// let id_b = store_pattern_b(antecedents=[id_a]);
// let id_c = store_pattern_c(antecedents=[id_b]);
//
// // Train sequential pattern
// temporal_memory.learn_sequential_pattern(&[id_a, id_b, id_c]);
//
// // Query A
// temporal_memory.query(id_a).await.unwrap();
//
// // Provide anticipation hint
// let hint = AnticipationHint::SequentialPattern;
// temporal_memory.anticipate(&[hint]).await.unwrap();
//
// // Verify B and C are now cached (predicted)
// assert!(temporal_memory.is_cached(id_b));
// assert!(temporal_memory.is_cached(id_c));
panic!("Implement this test once exo-temporal crate exists");
}
/// Test: Temporal knowledge graph integration
///
/// Verifies integration with temporal knowledge graph structures.
#[tokio::test]
#[ignore]
async fn test_temporal_knowledge_graph() {
// TODO: Implement once exo-temporal TKG support exists
// Expected:
// - Store facts with temporal validity periods
// - Query facts at specific time points
// - Verify temporal reasoning (fact true at t1, false at t2)
panic!("Implement this test once TKG integration exists");
}
/// Test: Causal graph distance computation
///
/// Verifies correct computation of causal distances.
#[tokio::test]
#[ignore]
async fn test_causal_distance() {
// TODO: Implement once exo-temporal exists
// Build causal chain: A -> B -> C -> D -> E
// Query causal distance from A to E
// Expected: 4 (number of hops)
panic!("Implement this test once exo-temporal crate exists");
}
/// Test: Concurrent causal updates
///
/// Verifies thread-safety of causal graph updates.
#[tokio::test]
#[ignore]
async fn test_concurrent_causal_updates() {
// TODO: Implement once exo-temporal exists
// Expected:
// - Spawn multiple tasks storing patterns concurrently
// - Verify no race conditions in causal graph
// - Verify all causal links preserved
panic!("Implement this test once exo-temporal crate exists");
}
/// Test: Memory decay and forgetting
///
/// Verifies strategic forgetting mechanisms.
#[tokio::test]
#[ignore]
async fn test_strategic_forgetting() {
// TODO: Implement once exo-temporal exists
// Expected:
// - Store patterns with low access frequency
// - Advance time and trigger decay
// - Verify low-salience patterns removed
panic!("Implement this test once exo-temporal crate exists");
}
}