pub struct RuleEngine { /* private fields */ }Expand description
Refactor Wave-2 Tier-A2 (issue #850) — unified rule engine consumed by every governance entry point.
Before this refactor each of the three callsites that consult
governance_rules (the substrate GOVERNANCE_PRE_WRITE hook, the
wire_check agent-external hook, and the audited check_agent_action
MCP / CLI surface) duplicated the rule-load + first-refusal-wins
loop in its own function (check_agent_action,
check_agent_action_no_audit, check_agent_action_deferred).
Adding a new severity variant or matcher field meant touching three
near-identical loops. The RuleEngine collapses the load + routing
logic into one place; the three legacy free functions remain as
thin wrappers so the public API is wire-stable.
rules holds the snapshot of enabled rules of the target kind
(the engine is constructed per-action, not per-table — kind-scoped
loading matches the existing list_enabled_by_kind shape and
preserves the signature-verification side effects in
crate::governance::rules_store::list_enabled_by_kind).
The combinator is first-refusal-wins with warn falling
through and log being silent — identical semantics to the
pre-refactor inline loops.
Implementations§
Source§impl RuleEngine
impl RuleEngine
Sourcepub fn load_for_action(conn: &Connection, action: &AgentAction) -> Result<Self>
pub fn load_for_action(conn: &Connection, action: &AgentAction) -> Result<Self>
Construct an engine scoped to a single AgentAction’s kind
without consulting any cache. Equivalent to
load_for_action_cached(conn, None, action).
Reads the enabled rule rows of matching kind from
governance_rules via
crate::governance::rules_store::list_enabled_by_kind; the
signature-verification gate (L1-6 bypass-impossibility
invariant) runs inside that helper and is preserved verbatim.
§Errors
Propagates any SQLite error from list_enabled_by_kind.
Sourcepub fn load_for_action_cached(
conn: &Connection,
cache: Option<&RuleCache>,
action: &AgentAction,
) -> Result<Self>
pub fn load_for_action_cached( conn: &Connection, cache: Option<&RuleCache>, action: &AgentAction, ) -> Result<Self>
Cached variant of Self::load_for_action (#991).
When cache is Some, consults the per-instance RuleCache
— cache hit returns the cached Arc<Vec<Rule>> without
re-running the SQL + Ed25519-verify path; cache miss loads via
crate::governance::rules_store::list_enabled_by_kind and
inserts. When cache is None, behaves exactly like
Self::load_for_action (no cache consultation, fresh load).
§Errors
Propagates any SQLite error from list_enabled_by_kind.
Sourcepub fn from_rules(rules: Vec<Rule>) -> Self
pub fn from_rules(rules: Vec<Rule>) -> Self
Construct an engine directly from a pre-loaded rules slice. Useful for tests that want to skip the SQLite round-trip or for future callsites that already hold a cached rule list.
Sourcepub fn evaluate(&self, _agent_id: &str, action: &AgentAction) -> Decision
pub fn evaluate(&self, _agent_id: &str, action: &AgentAction) -> Decision
Evaluate action against the loaded rules. Returns the
first-refusal-wins Decision.
agent_id is unused by the matcher today but threaded through
so future agent-scoped matchers (operator allow-lists, agent
quotas) can consult it without an API break.
Sourcepub fn rules(&self) -> &[Rule]
pub fn rules(&self) -> &[Rule]
Borrow the loaded rule slice. Used by count_matching_rules
and by tests that want to assert load-side behaviour without
running the matcher.
Auto Trait Implementations§
impl Freeze for RuleEngine
impl RefUnwindSafe for RuleEngine
impl Send for RuleEngine
impl Sync for RuleEngine
impl Unpin for RuleEngine
impl UnsafeUnpin for RuleEngine
impl UnwindSafe for RuleEngine
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more