use crate::context::AuditContext;
use crate::scoring::{calculate_score, compute_summary, cross_layer_risk};
use crate::types::{AuditFinding, AuditReport};
use async_trait::async_trait;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct AuditOptions {
pub deep: bool,
pub fix: bool,
pub json: bool,
}
#[async_trait]
pub trait Check: Send + Sync {
fn category(&self) -> &'static str;
async fn run(&self, ctx: &dyn AuditContext, opts: &AuditOptions) -> Vec<AuditFinding>;
}
pub async fn run_audit(
ctx: &dyn AuditContext,
checks: &[Box<dyn Check>],
opts: &AuditOptions,
timestamp: String,
secureops_version: &str,
) -> AuditReport {
let mut findings: Vec<AuditFinding> = Vec::new();
for check in checks {
findings.extend(check.run(ctx, opts).await);
}
let cross = cross_layer_risk(&findings);
findings.extend(cross);
let score = calculate_score(&findings);
let summary = compute_summary(&findings);
AuditReport {
timestamp,
openclaw_version: ctx.openclaw_version().to_string(),
secureops_version: secureops_version.to_string(),
platform: ctx.platform().to_string(),
deployment_mode: ctx.deployment_mode().to_string(),
score,
findings,
summary,
}
}