Skip to main content

FlowMonitor

Struct FlowMonitor 

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

Observes the session trace, maintains the Marking, answers tool admissibility, and projects active postures.

Implementations§

Source§

impl FlowMonitor

Source

pub fn new(flow: Flow, mode: Enforcement) -> Self

Create a monitor for a (presumed-valid) flow.

Prefer FlowMonitor::compiled or FlowMonitor::try_new, which carry proof of compilation; this convenience skips compilation for flows already known valid (e.g. built in-process by trusted code).

Source

pub fn compiled(flow: CompiledFlow, mode: Enforcement) -> Self

Create a monitor from a CompiledFlow — the validated path.

Source

pub fn try_new(flow: Flow, mode: Enforcement) -> Result<Self, FlowErrors>

Compile flow and create a monitor, surfacing structural errors instead of trusting the caller.

Source

pub fn into_shared(self) -> SharedFlowMonitor

Wrap this monitor in a SharedFlowMonitor for shared ownership between the control lane (which advances it) and runtime accessors (which snapshot it, e.g. LiveHandle::explain).

Source

pub fn into_stack(self) -> FlowStack

Wrap this monitor as the main layer of a FlowStack with no digressions — the form the Live control plane drives.

Source

pub fn restart(&mut self)

Re-enter the flow from its start: forget the marking, the fired on_enter actions and the reset edges. The flow, mode and registered actions are kept, and recorded violations stay for audit. State is not touched — the next re-latch runs against whatever facts it holds.

Source

pub fn explain(&self, state: &State) -> FlowExplanation

Explain the current control-plane state: active steps, which tools are admitted vs blocked (with reasons), and unmet requirements.

This is the deterministic answer to “why did the assistant ask that?” — model-readable, without the model driving control flow.

Source

pub fn on_enter(self, step: impl Into<String>, action: StepAction) -> Self

Attach an action fired the first time step becomes active (see on_enter). Chainable at construction time.

Source

pub fn take_newly_active(&mut self, state: &State) -> Vec<String>

Steps that became active since the last call — each reported exactly once over the session. Drives on_enter firing.

Source

pub fn enter_action(&self, step: &str) -> Option<&StepAction>

The enter-action registered for a step, if any.

Source

pub async fn fire_enter_actions(&mut self, state: &State)

Fire enter-actions for every step that just became active. Convenience over take_newly_active + enter_action; call it right after on_turn.

Source

pub fn mode(&self) -> Enforcement

The enforcement mode this monitor runs in.

Source

pub fn set_posture(&mut self, step_id: &str, posture: Option<String>) -> bool

Replace a step’s posture in place. Returns false if no such step.

Postures are re-projected at every turn boundary, so an edit takes effect on the next turn — the safe subset of live spec editing. The DAG, guards, and tool gates are structural and stay fixed.

Source

pub fn set_ground(&mut self, step_id: &str, ground: Option<String>) -> bool

Replace a step’s grounding template in place. Returns false if no such step. Same next-turn semantics as set_posture.

Source

pub fn eval(&self, guard: &Guard, state: &State) -> bool

Evaluate a Guard against this monitor’s current context (the given state plus the monitor’s marking). Used to test overlay/digression triggers without exposing the internal context.

Source

pub fn marking(&self) -> &Marking

The current marking.

Source

pub fn violations(&self) -> &[Violation]

Recorded violations.

Source

pub fn record_violation( &mut self, subject: impl Into<String>, reason: impl Into<String>, )

Record a deviation the caller detected — one this monitor cannot see for itself. A FlowStack uses it for a tool called after a Resume::Terminate digression ended the conversation: the denial is the stack’s, not this flow’s, so observe_tool would find nothing wrong.

Source

pub fn flow(&self) -> &Flow

The underlying flow.

Source

pub fn relatch(&mut self, state: &State)

Re-evaluate completion latches to a fixpoint. Call after any event that can change state or the marking (turn boundary, tool completion).

Constraint::Reset constraints are applied first, on their guard’s rising edge: the named steps un-latch, their on_enter re-arms, and the called_ok evidence their completion guards reference is forgiven — the loop primitive over an otherwise monotonic marking.

Source

pub fn on_turn(&mut self, state: &State)

Record a turn boundary, then re-latch.

Source

pub fn begin_turn(&mut self, state: &State) -> Vec<String>

The first half of on_turn: count the turn and apply Constraint::Reset edges, returning the steps that were un-latched.

A caller that keeps evidence about steps outside the marking — the FlowStack and its repair signals — needs to see a reset before the re-latch runs, or a completion guard that references that evidence re-completes the step on the spot. Follow with relatch; the reset edges are consumed, so the re-latch does not apply them twice.

Source

pub fn on_tool_ok(&mut self, tool: &str, state: &State)

Record a successful tool call, then re-latch.

Source

pub fn begin_tool_ok(&mut self, tool: &str, state: &State) -> Vec<String>

The first half of on_tool_ok: count the call and apply Constraint::Reset edges, returning the steps that were un-latched.

A reset can be gated on a tool — reset(..).when(called_ok("start_over")) — in which case its edge fires here rather than at a turn boundary. A caller holding evidence outside the marking needs the same chance to shed it that begin_turn gives; follow with relatch.

Source

pub fn reads_now(&self, state: &State) -> BTreeSet<String>

The state keys the flow could act on now: those read by the active steps’ gates and done guards, by the edges leaving them, and by the constraints. A decision that writes one of these is worth asking.

Source

pub fn active_steps(&self, state: &State) -> Vec<&Step>

Steps that are eligible but not yet done.

Source

pub fn active_postures(&self, state: &State) -> Vec<String>

Postures of the active steps — to inject as turn-boundary steering.

Source

pub fn active_grounds(&self, state: &State) -> Vec<String>

Rendered grounding lines of the active steps — curated, State- interpolated facts to inject as turn-boundary steering (anti-hallucination).

Source

pub fn closing_steps(&self) -> Vec<&Step>

Terminal steps that are done — the flow’s closing.

A terminal step completes on eligibility, so it is never active and its posture is never among active_postures. Its instruction is the flow’s last word (“hand off to a human now”), which the FlowStack projects on the turn a digression completes.

Source

pub fn closing_postures(&self) -> Vec<String>

Postures of the closing_steps.

Source

pub fn closing_grounds(&self, state: &State) -> Vec<String>

Rendered grounding lines of the closing_steps.

Source

pub fn unmet_requirements(&self) -> Vec<String>

Required steps not yet done (drives repair).

Source

pub fn is_complete(&self) -> bool

Whether all required steps are done.

Source

pub fn verdict(&self, step_id: &str, state: &State) -> Verdict

The conformance verdict for a step.

Source

pub fn admits_tool(&self, tool: &str, state: &State) -> Result<(), String>

Decide whether a tool call may proceed. Ok(()) admits it; Err(reason) denies it (the caller blocks in Enforce mode, or records in Observe).

Source

pub fn offers_tool(&self, tool: &str, state: &State) -> bool

Whether tool would be admitted once every never(tool).until(..) guard on it holds: the active steps allow it and it has not used up a once, or a frontier step allows it. Under ContextUpdate steering the model is offered these tools, so that it can call one in the turn its guard comes to hold or its step opens; the call itself is still decided by admits_tool.

Source

pub fn possible(&self, guard: &Guard, state: &State) -> Option<bool>

Evaluate guard as the caller’s next words could leave it, against this flow’s marking. See Guard::possible.

Source

pub fn frontier_steps(&self, state: &State) -> Vec<&Step>

The steps one decision away: neither done nor active, but able to become active in the caller’s next turn because what stands in their way is a decided atom, in their gate, an incoming edge, or the done guard of the active step they follow.

A decision made after the caller’s turn ends cannot change the tools the model has for that turn: measured on Gemini 3.8 Live, a tool declared even 0 ms after the turn ended was not used in that turn’s reply (0 of 15), while one declared before it was (5 of 5). So under ContextUpdate steering these steps’ tools are offered ahead, and a call to one is decided at the gate: the questions in its way (frontier_questions) are asked about the turn in progress, the flow relatches, and the call is admitted only if the step opened.

Source

pub fn frontier_questions(&self, tool: &str, state: &State) -> DecisionScope

The questions that decide whether a frontier step allowing tool opens, with the state keys their guards read: the step’s gate, its incoming edges, and the done guards of the active steps it follows. Empty when no frontier step allows tool.

Source

pub fn blocking_keys(&self, tool: &str, state: &State) -> BTreeSet<String>

The state keys read by the never(tool).until(..) guards that refuse tool right now. Empty when no such guard is refusing it.

Source

pub fn observe_tool(&mut self, tool: &str, ok: bool, state: &State)

Observe a tool call for conformance. In Enforce mode the caller has already gated via admits_tool; this records the call and, in Observe mode, logs a deviation if it was inadmissible.

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self> ⓘ

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

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

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

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
§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

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

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

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

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

§

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
§

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
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

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