use urge_core::{
ast::{node, Expr, Literal},
engine::{ContextValue, EvalContext},
symbol::SemanticClass,
};
use urge_meta::{GovernancePipeline, PipelineConfig};
pub mod hard_rules {
use urge_core::decision::Verdict;
pub fn camera_deny() -> Verdict {
Verdict::deny_immediate("camera: no user permission granted")
}
pub fn microphone_consent_required() -> Verdict {
Verdict::deny_immediate("microphone: consent required before activation")
}
pub fn network_airplane_mode_deny() -> Verdict {
Verdict::deny_immediate("network: airplane mode active")
}
}
pub struct BiosGovernor {
pipeline: GovernancePipeline,
}
impl BiosGovernor {
pub fn new() -> Self {
BiosGovernor {
pipeline: GovernancePipeline::new(PipelineConfig::embedded()),
}
}
pub fn check_access(&self, capability: &str, _app_id: &str, battery_percent: u8) -> bool {
let battery_critical = battery_percent < 5;
if battery_critical && matches!(capability, "camera" | "gps" | "bluetooth") {
return false;
}
let slots: &[(&'static str, ContextValue)] = &[
(
"battery_sufficient",
ContextValue::Bool(battery_percent >= 20),
),
("permission_granted", ContextValue::Bool(true)), ("not_restricted", ContextValue::Bool(true)), ];
let ctx = EvalContext {
slots,
logical_time: 0,
depth_limit: 4, };
use urge_core::symbol::ParadigmSet;
let mut ps = ParadigmSet::empty();
ps.insert(urge_core::engine::Paradigm::Boolean);
let ast = node(Expr::Binary {
op: SemanticClass::Conjunction,
left: node(Expr::Binary {
op: SemanticClass::Conjunction,
left: node(Expr::Var {
name: {
let mut s = heapless::String::new();
let _ = s.push_str("battery_sufficient");
s
},
paradigms: ps,
}),
right: node(Expr::Var {
name: {
let mut s = heapless::String::new();
let _ = s.push_str("permission_granted");
s
},
paradigms: ps,
}),
paradigms: ps,
}),
right: node(Expr::Var {
name: {
let mut s = heapless::String::new();
let _ = s.push_str("not_restricted");
s
},
paradigms: ps,
}),
paradigms: ps,
});
let verdict =
self.pipeline
.evaluate_ast(&ast, ps, &ctx, urge_core::decision::LogicTrace::new());
verdict.valid
}
pub fn evaluate_simple(&self, _capability: SemanticClass, subject: bool) -> bool {
let mut ps = urge_core::symbol::ParadigmSet::empty();
ps.insert(urge_core::engine::Paradigm::Boolean);
let ast = node(Expr::Lit(Literal::Bool(subject)));
let ctx = EvalContext {
slots: &[],
logical_time: 0,
depth_limit: 4,
};
let v = self
.pipeline
.evaluate_ast(&ast, ps, &ctx, urge_core::decision::LogicTrace::new());
v.valid
}
}
impl Default for BiosGovernor {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bios_denies_on_critical_battery() {
let gov = BiosGovernor::new();
assert!(!gov.check_access("camera", "app.health", 3));
}
#[test]
fn bios_permits_with_sufficient_battery() {
let gov = BiosGovernor::new();
assert!(gov.check_access("camera", "app.health", 80));
}
}