pub struct TrajectorySentinel { /* private fields */ }Expand description
Cross-turn risk accumulator for the advisory trajectory governance layer.
§Usage
use zeph_core::agent::trajectory::{TrajectorySentinel, RiskSignal, RiskLevel, VigilRiskLevel};
use zeph_config::TrajectorySentinelConfig;
let mut sentinel = TrajectorySentinel::new(TrajectorySentinelConfig::default());
// Call advance_turn once per turn, BEFORE gate evaluation.
let _ = sentinel.advance_turn();
sentinel.record(RiskSignal::VigilFlagged(VigilRiskLevel::High));
sentinel.record(RiskSignal::PolicyDeny);
let level = sentinel.current_risk();
assert!(level >= RiskLevel::Calm);Implementations§
Source§impl TrajectorySentinel
impl TrajectorySentinel
Sourcepub fn new(cfg: TrajectorySentinelConfig) -> Self
pub fn new(cfg: TrajectorySentinelConfig) -> Self
Create a fresh sentinel with the given configuration.
§Examples
use zeph_core::agent::trajectory::TrajectorySentinel;
use zeph_config::TrajectorySentinelConfig;
let sentinel = TrajectorySentinel::new(TrajectorySentinelConfig::default());Sourcepub fn spawn_child(&self) -> TrajectorySentinel
pub fn spawn_child(&self) -> TrajectorySentinel
Initialise a child sentinel for a spawned subagent per FR-CG-011.
When the parent is at >= Elevated, the child starts with a damped copy of the
parent’s score (parent_score * subagent_inheritance_factor). This prevents
a subagent spawn from acting as a free risk reset.
§Examples
use zeph_core::agent::trajectory::{TrajectorySentinel, RiskSignal, RiskLevel, VigilRiskLevel};
use zeph_config::TrajectorySentinelConfig;
let mut parent = TrajectorySentinel::new(TrajectorySentinelConfig::default());
let _ = parent.advance_turn();
parent.record(RiskSignal::VigilFlagged(VigilRiskLevel::High));
parent.record(RiskSignal::PolicyDeny);
let child = parent.spawn_child();
// Child starts with some inherited score when parent is >= Elevated.Sourcepub fn advance_turn(&mut self) -> bool
pub fn advance_turn(&mut self) -> bool
Advance the turn counter and apply multiplicative decay.
MUST be called once per turn, before any PolicyGateExecutor::check_policy runs.
Also handles the FR-CG-010 auto-recover cap: after auto_recover_after_turns
consecutive turns at Critical with no new high-weight signal, the score is hard-reset
to 0.0 and the buffer is cleared.
Returns true when auto-recover fired this turn — the caller MUST write an audit entry
with error_category = "trajectory_auto_recover" (F5 requirement).
Sourcepub fn record(&mut self, sig: RiskSignal)
pub fn record(&mut self, sig: RiskSignal)
Record a risk signal for the current turn.
§Examples
use zeph_core::agent::trajectory::{TrajectorySentinel, RiskSignal};
use zeph_config::TrajectorySentinelConfig;
let mut sentinel = TrajectorySentinel::new(TrajectorySentinelConfig::default());
let _ = sentinel.advance_turn();
sentinel.record(RiskSignal::PolicyDeny);
assert!(sentinel.score_now() > 0.0);Sourcepub fn current_risk(&self) -> RiskLevel
pub fn current_risk(&self) -> RiskLevel
Return the current risk level bucket for the accumulated score.
§Examples
use zeph_core::agent::trajectory::{TrajectorySentinel, RiskLevel};
use zeph_config::TrajectorySentinelConfig;
let sentinel = TrajectorySentinel::new(TrajectorySentinelConfig::default());
assert_eq!(sentinel.current_risk(), RiskLevel::Calm);Sourcepub fn poll_alert(&self) -> Option<RiskAlert>
pub fn poll_alert(&self) -> Option<RiskAlert>
Return a RiskAlert when the score crosses alert_threshold, None otherwise.
Consumed by PolicyGateExecutor. Never expose to LLM-callable surfaces.
Sourcepub fn score_now(&self) -> f32
pub fn score_now(&self) -> f32
Compute the decayed score from the signal buffer without mutating state.
Score formula: Σ_k decay_per_turn^(current_turn - signal_turn_k) * weight(signal_k)
Guaranteed to be finite and non-negative (upholds NEVER-negative invariant).
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Hard reset: clear all state. Called on /clear, /trajectory reset, or session restart.
Sourcepub fn current_turn(&self) -> u64
pub fn current_turn(&self) -> u64
The current turn counter (for diagnostics and audit logging only).
Sourcepub fn signal_count(&self) -> usize
pub fn signal_count(&self) -> usize
Number of signals in the current window (for diagnostics only).
Auto Trait Implementations§
impl Freeze for TrajectorySentinel
impl RefUnwindSafe for TrajectorySentinel
impl Send for TrajectorySentinel
impl Sync for TrajectorySentinel
impl Unpin for TrajectorySentinel
impl UnsafeUnpin for TrajectorySentinel
impl UnwindSafe for TrajectorySentinel
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
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 moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request