pub mod audit;
pub mod control_support;
#[allow(dead_code)]
pub mod governance_support;
pub mod identity;
pub mod identity_support;
pub mod integration_support;
pub mod lifecycle;
pub mod mcp;
pub mod policy;
pub mod reward_support;
pub mod rings;
pub mod sandbox;
pub mod trust;
pub mod trust_support;
pub mod types;
pub use audit::AuditLogger;
pub use control_support::{
CircuitBreaker, CircuitState, ErrorBudget, HealthStatus, IncidentRecord, KillSwitch,
KillSwitchDecision, KillSwitchEvent, KillSwitchReason, KillSwitchRegistry, KillSwitchScope,
ObjectiveEvaluation, ServiceHealthReport, ServiceLevelObjective, SloEngine,
};
pub use governance_support::{
annex_iv_to_json, annex_iv_to_markdown, load_cedar_into_engine, load_rego_into_engine,
ActionRequest, AgentRiskProfile, AnnexIVDocument, AnnexIVSection, AuditChain, AuditSink,
AuthorityDecision, AuthorityRequest, CedarDecision, CedarEvaluation, CedarEvaluator,
ClassificationResult, ComplianceEngine, ComplianceFramework, ComplianceReport,
ComplianceViolation, ConditionOperator, DataClassification, DefaultAuthorityResolver,
DelegationInfo, EUAIActRiskClassifier, FederationDecision, FederationEngine, FederationStore,
FileAuditSink, FileFederationStore, HashChainVerifier, InMemoryFederationStore, OPADecision,
OPAEvaluation, OPAEvaluator, OrgPolicy, OrgPolicyDecision, OrgPolicyRule, OrgTrustAgreement,
PolicyBackendDiagnostic, PolicyBackendTrace, PolicyCategory, PolicyDelegation,
PolicyDiagnosticSeverity, PolicyEvaluator, PolicyRuleTrace, RiskLevel as GovernanceRiskLevel,
ShadowMode, ShadowResult, SignedAuditEntry, TechnicalDocumentationExporter, TrustCondition,
TrustDefaults, TrustInfo, TrustPolicy, TrustPolicyDecision, TrustRule,
};
pub use identity::{AgentIdentity, PublicIdentity};
pub use identity_support::{
from_jwk, from_jwks, to_jwk, to_jwks, AgentDID, AgentNamespace, Credential, CredentialManager,
CredentialStatus, DelegationLink, HumanSponsor, KeyRotationManager, KeyStore, MTLSConfig,
MTLSIdentityVerifier, NamespaceManager, NamespaceRule, PKCS11KeyStore, RevocationEntry,
RevocationList, RiskLevel, RiskScore as IdentityRiskScore, RiskScorer, RiskSeverity,
RiskSignal, SPIFFEIdentity, SPIFFERegistry, ScopeChain, SoftwareKeyStore, SvidType,
UserContext, SVID,
};
pub use integration_support::{
DetectionBasis, DiscoveredAgent, DiscoveryEvidence, DiscoveryInventory,
DiscoveryInventorySummary, DiscoveryReconciler, DiscoveryRecord, DiscoveryRiskAssessment,
DiscoveryRiskLevel, DiscoveryRiskScorer, DiscoveryScanResult, DiscoveryScanner,
DiscoveryStatus, DriftResult, ExecutionRequest, ExecutionResponse, FrameworkAdapter,
FrameworkExecutionResult, FrameworkGovernanceAdapter, FrameworkKind, FrameworkResponse,
GovernanceEvent, GovernanceEventType, GovernanceHook, GovernanceMiddleware, GovernancePattern,
GovernancePolicy, PatternType, ProcessSnapshot, PromptDefenseEvaluator, PromptDefenseFinding,
PromptDefenseReport, PromptRiskLevel, RegisteredAgent, ResponseGovernanceAssessment,
ShadowAgent,
};
pub use lifecycle::{LifecycleEvent, LifecycleManager, LifecycleState};
pub use mcp::*;
pub use policy::{PolicyEngine, PolicyError};
pub use reward_support::{
AgentRewardState, ContributionWeightedStrategy, DimensionType, DistributionResult,
EqualSplitStrategy, HierarchicalStrategy, InteractionEdge, NetworkTrustEngine, ParticipantInfo,
RewardAllocation, RewardConfig, RewardDimension, RewardDistributor, RewardEngine, RewardPool,
RewardSignal, RewardStrategy, RewardTrustScore, TrustEvent, TrustWeightedStrategy,
};
pub use rings::{Ring, RingEnforcer};
pub use trust::{TrustConfig, TrustManager};
pub use trust_support::{
CapabilityGrant, CapabilityRegistry, CapabilityScope, CardRegistry, HandshakeChallenge,
HandshakeResponse, HandshakeResult, HandshakeTrustLevel, PeerInfo, ProtocolBridge, TrustBridge,
TrustHandshake, TrustedAgentCard,
};
pub use types::{
AuditEntry, AuditFilter, CandidateDecision, ConflictResolutionStrategy, GovernanceResult,
PolicyDecision, PolicyScope, ResolutionResult, TrustScore, TrustTier,
};
use std::collections::HashMap;
pub struct AgentMeshClient {
pub identity: AgentIdentity,
pub trust: TrustManager,
pub policy: PolicyEngine,
pub audit: AuditLogger,
}
#[derive(Default)]
pub struct ClientOptions {
pub capabilities: Vec<String>,
pub trust_config: Option<TrustConfig>,
pub policy_yaml: Option<String>,
}
impl AgentMeshClient {
pub fn new(agent_id: &str) -> Result<Self, ClientError> {
Self::with_options(agent_id, ClientOptions::default())
}
pub fn with_options(agent_id: &str, opts: ClientOptions) -> Result<Self, ClientError> {
let identity =
AgentIdentity::generate(agent_id, opts.capabilities).map_err(ClientError::Identity)?;
let trust_config = opts.trust_config.unwrap_or_default();
let trust = TrustManager::new(trust_config);
let policy = PolicyEngine::new();
if let Some(yaml) = &opts.policy_yaml {
policy.load_from_yaml(yaml).map_err(ClientError::Policy)?;
}
Ok(Self {
identity,
trust,
policy,
audit: AuditLogger::new(),
})
}
pub fn execute_with_governance(
&self,
action: &str,
context: Option<&HashMap<String, serde_yaml::Value>>,
) -> GovernanceResult {
let decision = self.policy.evaluate(action, context);
let audit_entry = self.audit.log(&self.identity.did, action, decision.label());
let trust_score = self.trust.get_trust_score(&self.identity.did);
match &decision {
PolicyDecision::Allow => self.trust.record_success(&self.identity.did),
PolicyDecision::Deny(_) => self.trust.record_failure(&self.identity.did),
_ => {}
}
GovernanceResult {
allowed: decision.is_allowed(),
decision,
trust_score,
audit_entry,
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum ClientError {
#[error("identity error: {0}")]
Identity(identity::IdentityError),
#[error("policy error: {0}")]
Policy(policy::PolicyError),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_default_allows_everything() {
let client = AgentMeshClient::new("test-agent").unwrap();
let result = client.execute_with_governance("anything", None);
assert!(result.allowed);
assert_eq!(result.decision, PolicyDecision::Allow);
}
#[test]
fn test_client_with_policy() {
let yaml = r#"
version: "1.0"
agent: test
policies:
- name: gate
type: capability
allowed_actions:
- "data.read"
denied_actions:
- "shell:*"
"#;
let opts = ClientOptions {
policy_yaml: Some(yaml.to_string()),
..Default::default()
};
let client = AgentMeshClient::with_options("test", opts).unwrap();
let r1 = client.execute_with_governance("data.read", None);
assert!(r1.allowed);
let r2 = client.execute_with_governance("shell:rm", None);
assert!(!r2.allowed);
assert!(matches!(r2.decision, PolicyDecision::Deny(_)));
}
#[test]
fn test_governance_updates_trust() {
let client = AgentMeshClient::new("trust-test").unwrap();
let did = client.identity.did.clone();
client.execute_with_governance("action1", None); client.execute_with_governance("action2", None); let score = client.trust.get_trust_score(&did);
assert!(score.score > 500);
}
#[test]
fn test_governance_creates_audit_chain() {
let client = AgentMeshClient::new("audit-test").unwrap();
client.execute_with_governance("a", None);
client.execute_with_governance("b", None);
client.execute_with_governance("c", None);
assert!(client.audit.verify());
assert_eq!(client.audit.entries().len(), 3);
}
#[test]
fn test_client_with_custom_trust_config() {
let opts = ClientOptions {
trust_config: Some(TrustConfig {
initial_score: 800,
threshold: 700,
reward: 20,
penalty: 100,
persist_path: None,
decay_rate: 0.95,
}),
..Default::default()
};
let client = AgentMeshClient::with_options("custom-trust", opts).unwrap();
let score = client.trust.get_trust_score(&client.identity.did);
assert_eq!(score.score, 800);
assert_eq!(score.tier, TrustTier::Trusted);
}
#[test]
fn test_client_with_capabilities() {
let opts = ClientOptions {
capabilities: vec!["data.read".to_string(), "data.write".to_string()],
..Default::default()
};
let client = AgentMeshClient::with_options("cap-agent", opts).unwrap();
assert_eq!(
client.identity.capabilities,
vec!["data.read", "data.write"]
);
}
#[test]
fn test_client_with_invalid_yaml_returns_error() {
let opts = ClientOptions {
policy_yaml: Some("not: valid: yaml: {{{{".to_string()),
..Default::default()
};
let result = AgentMeshClient::with_options("bad-yaml", opts);
assert!(result.is_err());
match result {
Err(ClientError::Policy(_)) => {}
other => panic!("expected ClientError::Policy, got {:?}", other.err()),
}
}
#[test]
fn test_multiple_governance_executions_build_audit_chain() {
let client = AgentMeshClient::new("chain-agent").unwrap();
for i in 0..5 {
client.execute_with_governance(&format!("action.{}", i), None);
}
let entries = client.audit.entries();
assert_eq!(entries.len(), 5);
for i in 0..5 {
assert_eq!(entries[i].seq, i as u64);
}
for i in 1..5 {
assert_eq!(entries[i].previous_hash, entries[i - 1].hash);
}
assert!(client.audit.verify());
}
#[test]
fn test_governance_with_denied_action_decreases_trust() {
let yaml = r#"
version: "1.0"
agent: test
policies:
- name: gate
type: capability
denied_actions:
- "dangerous.*"
"#;
let opts = ClientOptions {
policy_yaml: Some(yaml.to_string()),
..Default::default()
};
let client = AgentMeshClient::with_options("deny-trust", opts).unwrap();
let did = client.identity.did.clone();
let initial = client.trust.get_trust_score(&did).score;
client.execute_with_governance("dangerous.action", None);
let after = client.trust.get_trust_score(&did).score;
assert!(after < initial);
}
#[test]
fn test_governance_with_approval_required_action() {
let yaml = r#"
version: "1.0"
agent: test
policies:
- name: deploy-gate
type: approval
actions:
- "deploy.*"
min_approvals: 3
"#;
let opts = ClientOptions {
policy_yaml: Some(yaml.to_string()),
..Default::default()
};
let client = AgentMeshClient::with_options("approval-test", opts).unwrap();
let result = client.execute_with_governance("deploy.prod", None);
assert!(!result.allowed);
assert!(matches!(
result.decision,
PolicyDecision::RequiresApproval(_)
));
}
#[test]
fn test_approval_required_action_preserves_trust_and_audits_label() {
let yaml = r#"
version: "1.0"
agent: test
policies:
- name: deploy-gate
type: approval
actions:
- "deploy.*"
min_approvals: 2
"#;
let opts = ClientOptions {
policy_yaml: Some(yaml.to_string()),
..Default::default()
};
let client = AgentMeshClient::with_options("approval-audit", opts).unwrap();
let did = client.identity.did.clone();
let before = client.trust.get_trust_score(&did).score;
let result = client.execute_with_governance("deploy.production", None);
let after = client.trust.get_trust_score(&did).score;
assert!(!result.allowed);
assert!(matches!(
result.decision,
PolicyDecision::RequiresApproval(_)
));
assert_eq!(result.audit_entry.decision, "requires_approval");
assert_eq!(after, before);
}
#[test]
fn test_governance_with_rate_limited_action() {
let yaml = r#"
version: "1.0"
agent: test
policies:
- name: rate-gate
type: rate_limit
actions:
- "api.*"
max_calls: 2
window: "60s"
"#;
let opts = ClientOptions {
policy_yaml: Some(yaml.to_string()),
..Default::default()
};
let client = AgentMeshClient::with_options("rate-test", opts).unwrap();
let r1 = client.execute_with_governance("api.call", None);
assert!(r1.allowed);
let r2 = client.execute_with_governance("api.call", None);
assert!(r2.allowed);
let r3 = client.execute_with_governance("api.call", None);
assert!(!r3.allowed);
assert!(matches!(r3.decision, PolicyDecision::RateLimited { .. }));
}
#[test]
fn test_client_identity_did_is_correct() {
let client = AgentMeshClient::new("my-agent-42").unwrap();
assert_eq!(client.identity.did, "did:agentmesh:my-agent-42");
}
#[test]
fn test_audit_chain_integrity_after_mixed_allow_deny() {
let yaml = r#"
version: "1.0"
agent: test
policies:
- name: gate
type: capability
allowed_actions:
- "safe.*"
denied_actions:
- "bad.*"
"#;
let opts = ClientOptions {
policy_yaml: Some(yaml.to_string()),
..Default::default()
};
let client = AgentMeshClient::with_options("mixed-test", opts).unwrap();
let r1 = client.execute_with_governance("safe.read", None);
assert!(r1.allowed);
let r2 = client.execute_with_governance("bad.delete", None);
assert!(!r2.allowed);
let r3 = client.execute_with_governance("safe.write", None);
assert!(r3.allowed);
assert!(client.audit.verify());
assert_eq!(client.audit.entries().len(), 3);
let entries = client.audit.entries();
assert_eq!(entries[0].decision, "allow");
assert_eq!(entries[1].decision, "deny");
assert_eq!(entries[2].decision, "allow");
}
}