Skip to main content

tracevault_core/
policy.rs

1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct PolicyRule {
6    pub id: Uuid,
7    pub org_id: Option<String>,
8    pub name: String,
9    pub description: String,
10    pub condition: PolicyCondition,
11    pub action: PolicyAction,
12    pub severity: PolicySeverity,
13    pub enabled: bool,
14    #[serde(default)]
15    pub scope: PolicyScope,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(tag = "type")]
20pub enum PolicyCondition {
21    TraceCompleteness,
22    AiPercentageThreshold {
23        threshold: f32,
24    },
25    ModelAllowlist {
26        allowed_models: Vec<String>,
27    },
28    SensitivePathPattern {
29        patterns: Vec<String>,
30    },
31    RequiredToolCall {
32        tool_names: Vec<String>,
33        #[serde(default)]
34        must_succeed: bool,
35    },
36    TokenBudget {
37        max_tokens: Option<u64>,
38        max_cost_usd: Option<f64>,
39    },
40    ConditionalToolCall {
41        tool_name: String,
42        min_count: Option<u32>,
43        when_files_match: Option<Vec<String>>,
44        #[serde(default)]
45        must_succeed: bool,
46    },
47}
48
49/// Which evaluation window this policy applies to.
50#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
51#[serde(rename_all = "snake_case")]
52pub enum PolicyScope {
53    /// Evaluated over the entire push window (default).
54    #[default]
55    Session,
56    /// Evaluated only against events inside the last validation window.
57    ValidationWindow,
58    /// Evaluated in both contexts.
59    Both,
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
63#[serde(rename_all = "snake_case")]
64pub enum PolicyAction {
65    BlockPush,
66    Warn,
67    /// Tool is explicitly permitted inside a validation window without a count
68    /// requirement. Prevents it from triggering the unknown-tool gate.
69    Allow,
70}
71
72/// Org/repo-level setting controlling what happens when an unknown tool
73/// (not covered by any validation_window-scoped policy) is called inside
74/// the validation window.
75#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
76#[serde(rename_all = "snake_case")]
77pub enum ValidationWindowMode {
78    /// No window enforcement (default).
79    #[default]
80    Disabled,
81    /// Unknown tool call is flagged but push succeeds.
82    Warn,
83    /// Unknown tool call blocks the push.
84    Block,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88#[serde(rename_all = "lowercase")]
89pub enum PolicySeverity {
90    Critical,
91    High,
92    Medium,
93    Low,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub struct PolicyEvaluation {
98    pub policy: PolicyRule,
99    pub result: EvalResult,
100    pub details: String,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
104#[serde(rename_all = "lowercase")]
105pub enum EvalResult {
106    Pass,
107    Fail,
108    Warn,
109}