use urge_core::engine::{ContextValue, EvalContext};
use urge_meta::{GovernancePipeline, PipelineConfig};
use urge_monitor::{
obligation::{Obligation, ObligationType, ObligationViolationEvent},
GovernanceMonitor,
};
use crate::audit::AuditLog;
pub mod hipaa {
pub const MIN_NECESSARY: &str = "must minimum_necessary_access";
pub const ACCESS_CONTROL: &str = "must authorized_user and must authenticated";
pub const AUDIT_CONTROLS: &str = "always audit_active";
pub const DATA_INTEGRITY: &str = "always phi_integrity_maintained";
pub const TRANSMISSION_SECURITY: &str = "must encrypted_transmission";
}
pub mod clinical {
pub const INFORMED_CONSENT: &str = "must consent_obtained before procedure";
pub const PHQ9_SEVERE_ESCALATION: &str = "must escalate_to_provider";
pub const MED_ADMIN_ORDER: &str = "must verified_order and must authenticated";
}
pub struct HealthcareGovernor {
monitor: GovernanceMonitor,
audit: AuditLog,
current_time_ns: u64,
}
impl HealthcareGovernor {
pub fn new() -> Self {
let pipeline = GovernancePipeline::new(PipelineConfig::healthcare());
let monitor = GovernanceMonitor::new(pipeline);
HealthcareGovernor {
monitor,
audit: AuditLog::new(),
current_time_ns: 0,
}
}
pub fn require_consent(&mut self, patient_id: &str, responsible_agent: &str, deadline_ns: u64) {
let id = {
#[cfg(feature = "alloc")]
{
alloc::format!("consent:{}:{}", patient_id, responsible_agent)
}
#[cfg(not(feature = "alloc"))]
{
"consent:obligation"
}
};
let ob = Obligation::new(
&id,
ObligationType::Obligatory,
responsible_agent,
"obtain_consent",
Some(self.current_time_ns + deadline_ns),
self.current_time_ns,
);
self.monitor.track_obligation(ob);
}
pub fn evaluate(
&mut self,
expression: &str,
context_slots: &[(&'static str, ContextValue)],
) -> urge_core::decision::Verdict {
let ctx = EvalContext {
slots: context_slots,
logical_time: self.current_time_ns,
depth_limit: 16,
};
let verdict = self.monitor.pipeline.evaluate_str(expression, &ctx);
self.audit
.record(expression, &verdict, self.current_time_ns, None);
verdict
}
pub fn check_phi_access(
&mut self,
_agent_id: &str,
_patient_id: &str,
is_authorized: bool,
is_authenticated: bool,
audit_active: bool,
) -> Result<(), &'static str> {
let slots: &[(&'static str, ContextValue)] = &[
("authorized_user", ContextValue::Bool(is_authorized)),
("authenticated", ContextValue::Bool(is_authenticated)),
("audit_active", ContextValue::Bool(audit_active)),
("minimum_necessary_access", ContextValue::Bool(true)), ];
let verdict = self.evaluate(hipaa::ACCESS_CONTROL, slots);
if verdict.valid {
Ok(())
} else {
Err("HIPAA access control denied: insufficient authorization or authentication")
}
}
pub fn tick(&mut self, now_ns: u64) -> alloc::vec::Vec<ObligationViolationEvent> {
self.current_time_ns = now_ns;
self.monitor.tick(now_ns)
}
pub fn action_completed(
&mut self,
agent: &str,
action: &str,
) -> alloc::vec::Vec<ObligationViolationEvent> {
self.monitor.action_completed(agent, action)
}
pub fn audit_log(&self) -> &AuditLog {
&self.audit
}
pub fn stats(&self) -> urge_monitor::engine::MonitorStats {
self.monitor.stats()
}
}
impl Default for HealthcareGovernor {
fn default() -> Self {
Self::new()
}
}