pub struct PolicyEngine { /* private fields */ }Expand description
Applies constraints, mode and policy to one command, and builds the card that would unblock it.
Implementations§
Source§impl PolicyEngine
impl PolicyEngine
Sourcepub fn new(config: &OrchestratorConfig) -> Self
pub fn new(config: &OrchestratorConfig) -> Self
Builds an engine from a configuration, with the built-in copy and no review diff.
Sourcepub fn with_copy(self, copy: ConfirmationCopy) -> Self
pub fn with_copy(self, copy: ConfirmationCopy) -> Self
Replaces the copy on the cards the policy engine raises.
§The shipped default is English, and only English
Not a placeholder: it is real copy, it renders, and a deployment that never calls this ships it to every user in every locale. That is the failure worth naming here, because nothing goes wrong until a user in another language reads a sentence the rest of the product would never have written — which is how it was found.
A LocalizedText carries a default plus one string per locale, so
supplying your own is additive rather than a rewrite: start from
english() and use
LocalizedText::with to
add the languages you answer in.
Sourcepub fn with_review_diff(self, diff: Arc<dyn ReviewDiffBuilder>) -> Self
pub fn with_review_diff(self, diff: Arc<dyn ReviewDiffBuilder>) -> Self
Replaces the review diff builder.
use turnframe_core::interaction::ReviewDiffEntry;
use turnframe_runtime::config::OrchestratorConfig;
use turnframe_runtime::policy::PolicyEngine;
use std::sync::Arc;
let engine = PolicyEngine::new(&OrchestratorConfig::conservative())
.with_review_diff(Arc::new(|_: &turnframe_runtime::policy::PolicyRequest<'_>| {
vec![ReviewDiffEntry::new("name", "Name")]
}));
assert!(format!("{engine:?}").starts_with("PolicyEngine"));Sourcepub fn mode(&self) -> &OrchestrationMode
pub fn mode(&self) -> &OrchestrationMode
The orchestration mode the engine gates on.
Sourcepub fn review_diff(&self, request: &PolicyRequest<'_>) -> Vec<ReviewDiffEntry>
pub fn review_diff(&self, request: &PolicyRequest<'_>) -> Vec<ReviewDiffEntry>
The diff a review card would show for request.
Sourcepub fn decide(
&self,
snapshot: &PolicySnapshot,
request: &PolicyRequest<'_>,
constraints: &[ConstraintKind],
) -> PolicyOutcome
pub fn decide( &self, snapshot: &PolicySnapshot, request: &PolicyRequest<'_>, constraints: &[ConstraintKind], ) -> PolicyOutcome
Decides one command against snapshot and the turn’s constraints.
See the module documentation for the order of the gates.
Sourcepub fn confirmation_card(
&self,
key: impl Into<String>,
case_ref: &CaseRef,
policy: &CommandPolicy,
command_refs: Vec<CommandRef>,
diff: Vec<ReviewDiffEntry>,
subject: Option<ConfirmationSubject>,
) -> Option<InteractionSpec>
pub fn confirmation_card( &self, key: impl Into<String>, case_ref: &CaseRef, policy: &CommandPolicy, command_refs: Vec<CommandRef>, diff: Vec<ReviewDiffEntry>, subject: Option<ConfirmationSubject>, ) -> Option<InteractionSpec>
The card whose answer satisfies policy, or None when the end user
cannot supply the confirmation at all.
None comes back for ConfirmationPolicy::None (nothing to confirm)
and for ConfirmationPolicy::HumanProfessionalReview (offering the
user a card would let them approve themselves).
The card always carries a confirming CTA that authorizes exactly
command_refs and a declining CTA, so refusing is always possible (I6).
A InteractionKind::ReviewChanges card with an empty diff degrades
to InteractionKind::ConfirmCommand, which
ConfirmationPolicy::ReviewCard accepts just as well.
Sourcepub fn selection_card(
&self,
key: impl Into<String>,
case_ref: &CaseRef,
title: LocalizedText,
cancel_label: LocalizedText,
candidates: &[TargetCandidate],
) -> Option<InteractionSpec>
pub fn selection_card( &self, key: impl Into<String>, case_ref: &CaseRef, title: LocalizedText, cancel_label: LocalizedText, candidates: &[TargetCandidate], ) -> Option<InteractionSpec>
The card that lets the user pick between ambiguous targets (§12.3).
Returns None when there are fewer than two candidates — a selection
with one answer is not a selection — or more than
InteractionConfig::max_selection_candidates, because truncating the
list would let list order decide which cases the user may reach (I8).