stemedb/crates/stemedb-sim/src/agent.rs
jordan d3a88585fe feat: Phase 6 UAT - Admission control, HLC recency, cluster coordination
This commit includes comprehensive work on Phase 6 features:

## Admission Control (Phase 6 admission middleware)
- AdmissionStore implementation backed by TrustRankStore
- PoW verification with tier-based difficulty computation
- Trust tier progression (Newcomer → Established → Trusted → Authority)
- API integration with admission status endpoints

## HLC Recency Lens (Phase 6C)
- HlcRecencyLens for distributed system ordering
- Hybrid logical clock integration with causality preservation

## Cluster Coordination (Phase 6C)
- Multi-node cluster tests (availability, partition tolerance)
- CRDT convergence tests for anti-entropy sync
- Gateway handler improvements

## Aphoria Code Linter (Phase 2A)
- RFC/OWASP corpus builders with network fetching and caching
- Concept hierarchy with auto-alias creation on conflict detection
- Multiple security extractors (TLS, JWT, CORS, secrets, rate limiting)

## Code Organization
- Split large files into modules to comply with 500-line limit
- Improved test organization with separate test modules
- Fixed rkyv serialization for EigenTrustState (AgentScore struct)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 00:43:37 -07:00

97 lines
3.1 KiB
Rust

//! Agent types for simulation testing.
use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey};
use rand::rngs::OsRng;
use stemedb_core::types::{
Assertion, Hash, HlcTimestamp, LifecycleStage, ObjectValue, SignatureEntry, SourceClass, Vote,
};
/// A simulated agent with a cryptographic identity.
pub(crate) struct Agent {
pub id: String,
signing_key: SigningKey,
verifying_key: VerifyingKey,
}
impl Agent {
pub fn new(id: &str) -> Self {
let mut csprng = OsRng;
let signing_key = SigningKey::generate(&mut csprng);
let verifying_key = VerifyingKey::from(&signing_key);
Self { id: id.to_string(), signing_key, verifying_key }
}
/// Get the agent's public key as a 32-byte array.
pub fn public_key(&self) -> [u8; 32] {
self.verifying_key.to_bytes()
}
/// Create and sign an assertion with custom lifecycle and timestamp.
pub fn sign_assertion_with_options(
&self,
subject: &str,
predicate: &str,
object: ObjectValue,
lifecycle: LifecycleStage,
custom_timestamp: Option<u64>,
) -> Assertion {
let timestamp = custom_timestamp.unwrap_or_else(|| {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0)
});
// For simulation, we sign the concatenation of subject and predicate.
// In a real system, we'd sign the hash of the fact data.
let message = format!("{}:{}", subject, predicate);
let signature: Signature = self.signing_key.sign(message.as_bytes());
Assertion {
subject: subject.to_string(),
predicate: predicate.to_string(),
object,
parent_hash: None,
source_hash: [0u8; 32],
source_class: SourceClass::Expert,
visual_hash: None,
epoch: None,
source_metadata: None,
lifecycle,
signatures: vec![SignatureEntry {
agent_id: self.verifying_key.to_bytes(),
signature: signature.to_bytes(),
timestamp,
version: 1,
}],
confidence: 1.0,
timestamp,
hlc_timestamp: HlcTimestamp::default(),
vector: None,
}
}
/// Create and sign a vote for an assertion.
///
/// The agent signs the assertion_hash to prove authenticity.
pub fn vote(&self, assertion_hash: Hash, weight: f32) -> Vote {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
// Sign the assertion hash to prove we're voting on this specific assertion
let signature: Signature = self.signing_key.sign(&assertion_hash);
Vote {
assertion_hash,
agent_id: self.verifying_key.to_bytes(),
weight,
signature: signature.to_bytes(),
timestamp,
source_url: None,
observed_context: None,
}
}
}