Skip to main content

RuleCache

Struct RuleCache 

Source
pub struct RuleCache { /* private fields */ }
Expand description

Per-instance cache of Vec<Rule> keyed by AgentAction::kind().

The cache is owned by a Connection-bearing context (HTTP AppState, MCP main loop, or the substrate GOVERNANCE_PRE_WRITE / GOVERNANCE_PRE_ACTION hook installer that captures a long-lived Connection). Pass &RuleCache (or wrap in Arc for shared ownership) to the cached entry points (check_agent_action_cached, etc.). Cache hits return an Arc<Vec<Rule>> clone — no row data is cloned on the fast path.

Implementations§

Source§

impl RuleCache

Source

pub fn new() -> Self

Construct an empty cache. Cheap; safe to call per-test.

Source

pub fn get_or_load( &self, conn: &Connection, kind: &str, ) -> Result<Arc<Vec<Rule>>, RuleCacheError>

Return the cached rule list for kind, loading via crate::governance::rules_store::list_enabled_by_kind on cache miss. The Ed25519 signature verify side-effect on the loader path runs on miss; cache hits skip it.

v0.7.0 #1020 (Agent-1 #6) — returns the typed RuleCacheError enum at the substrate-public boundary (was bare anyhow::Result pre-#1020). RuleCacheError: Into<anyhow::Error> is implemented so existing anyhow-chained callers can keep their ? operator with no signature changes.

§Errors
  • RuleCacheError::Load wraps any error from list_enabled_by_kind (rusqlite errors, signature-verify panics).
  • RuleCacheError::Poisoned indicates the inner RwLock is poisoned by a prior thread panic. The legacy fallback returned a fresh snapshot anyway; callers wanting that posture can branch via RuleCacheError::is_poisoned and re-call list_enabled_by_kind directly.
Source

pub fn invalidate(&self, kind: &str)

Drop the cached entry for kind. Currently no caller takes this path because the rules_store writers don’t know the affected kind without inspecting the row; Self::invalidate_all is simpler.

Source

pub fn invalidate_all(&self)

Drop every cached entry. Used by the rules_store write paths (insert / remove / set_enabled / update_signature) so the next reader rebuilds against the post-write state.

Source

pub fn len(&self) -> usize

Number of currently-cached entries — for test inspection.

#1018 (2026-05-21): poison semantics changed from “lie as empty” to “return None via Self::len_checked”. The legacy len() returns 0 on poison (matches the pre-#1018 contract some tests still depend on); call sites that need to distinguish “empty” from “poisoned” use len_checked.

Source

pub fn len_checked(&self) -> Option<usize>

#1018 (2026-05-21): poison-aware variant of Self::len. Returns Some(len) on a healthy lock, None if the RwLock is poisoned. Pre-#1018 a poisoned cache reported len() == 0 and is_empty() == true — invisible to callers and test assertions. Operator inspection paths + future health-probe surfaces should consume this variant; legacy paths keep len().

Source

pub fn is_empty(&self) -> bool

Whether the cache is empty — for test inspection.

#1018: the legacy contract treats poison as “empty” (returns true). Use Self::is_empty_checked when the distinction matters.

Source

pub fn is_empty_checked(&self) -> Option<bool>

#1018 (2026-05-21): poison-aware variant of Self::is_empty. Returns Some(true) when the cache is healthy AND empty, Some(false) when healthy AND populated, None when the RwLock is poisoned. Operator inspection paths use this.

Trait Implementations§

Source§

impl Debug for RuleCache

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for RuleCache

Source§

fn default() -> RuleCache

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more