termivar_scanner/defense/
mod.rs1pub mod enforcement;
25pub mod fingerprint;
26pub mod policy;
27pub mod projection;
28pub mod shadow_planning;
29pub mod state;
30pub mod transition;
31
32pub use enforcement::{defense_aware_plan, DefensePlanningPolicy};
33pub use fingerprint::{
34 fingerprint, DefenseFingerprint, DefenseProduct, FingerprintConfidence,
35 MAX_FINGERPRINT_BODY_SCAN_BYTES,
36};
37pub use policy::{recommend, DefenseResponse};
38pub use projection::{
39 project_defense_state, project_defense_transition, project_outcome, DefenseObservationContext,
40 ObservedOutcome,
41};
42pub use shadow_planning::{
43 decide, defense_aware_shadow_plan, explanation_code, render_explanation,
44 DefenseAwareShadowPlan, DefenseInteractionClass, InteractionDecision, PlanAdjustment,
45 ResourceDefenseObservation, ResourceDefenseSignal, ShadowPlanDelta, SuppressedAction,
46};
47pub use state::{DefensePosture, DefenseState, DefenseStatusSignal};
48pub use transition::{DefenseTransition, DefenseTransitionKind, PostureShift};
49
50#[cfg(feature = "scanning")]
53pub(crate) fn assessment_interaction_decision(
54 response: DefenseResponse,
55 class: DefenseInteractionClass,
56) -> InteractionDecision {
57 shadow_planning::decide(response, class)
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn observation_layer_reexports_compose() {
66 let state = DefenseState::observe(
69 403,
70 &[("Server", "cloudflare"), ("CF-RAY", "abc")],
71 "Attention Required!",
72 );
73 assert_eq!(state.posture(), DefensePosture::Blocking);
74 let print: &DefenseFingerprint = state.fingerprint().unwrap();
75 assert_eq!(print.product(), DefenseProduct::Cloudflare);
76 assert_eq!(print.confidence(), FingerprintConfidence::Strong);
77 }
78}