chio_kernel/operator_report/
budget_report.rs1use super::*;
2
3#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
4#[serde(rename_all = "camelCase")]
5pub struct BudgetUtilizationSummary {
6 pub matching_grants: u64,
7 pub returned_grants: u64,
8 pub distinct_capabilities: u64,
9 pub distinct_subjects: u64,
10 pub total_invocations: u64,
11 pub total_cost_charged: u64,
12 pub near_limit_count: u64,
13 pub exhausted_count: u64,
14 pub rows_missing_scope: u64,
15 pub rows_missing_lineage: u64,
16 pub truncated: bool,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
20#[serde(rename_all = "camelCase")]
21pub struct BudgetDimensionUsage {
22 pub used: u64,
23 pub limit: u64,
24 pub remaining: u64,
25 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub utilization_rate: Option<f64>,
27 pub near_limit: bool,
28 pub exhausted: bool,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
32#[serde(rename_all = "camelCase")]
33pub struct BudgetDimensionProfile {
34 #[serde(default, skip_serializing_if = "Option::is_none")]
35 pub invocations: Option<BudgetDimensionUsage>,
36 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub money: Option<BudgetDimensionUsage>,
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
41#[serde(rename_all = "camelCase")]
42pub struct BudgetUtilizationRow {
43 pub capability_id: String,
44 pub grant_index: u32,
45 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub subject_key: Option<String>,
47 #[serde(default, skip_serializing_if = "Option::is_none")]
48 pub tool_server: Option<String>,
49 #[serde(default, skip_serializing_if = "Option::is_none")]
50 pub tool_name: Option<String>,
51 pub invocation_count: u32,
52 #[serde(default, skip_serializing_if = "Option::is_none")]
53 pub max_invocations: Option<u32>,
54 pub total_cost_charged: u64,
55 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub currency: Option<String>,
57 #[serde(default, skip_serializing_if = "Option::is_none")]
58 pub max_total_cost_units: Option<u64>,
59 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub remaining_cost_units: Option<u64>,
61 #[serde(default, skip_serializing_if = "Option::is_none")]
62 pub invocation_utilization_rate: Option<f64>,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub cost_utilization_rate: Option<f64>,
65 pub near_limit: bool,
66 pub exhausted: bool,
67 pub updated_at: i64,
68 pub scope_resolved: bool,
69 #[serde(default, skip_serializing_if = "Option::is_none")]
70 pub scope_resolution_error: Option<String>,
71 #[serde(default, skip_serializing_if = "Option::is_none")]
72 pub dimensions: Option<BudgetDimensionProfile>,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
76#[serde(rename_all = "camelCase")]
77pub struct BudgetUtilizationReport {
78 pub summary: BudgetUtilizationSummary,
79 pub rows: Vec<BudgetUtilizationRow>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
83#[serde(rename_all = "camelCase")]
84pub struct ComplianceReport {
85 pub matching_receipts: u64,
86 pub evidence_ready_receipts: u64,
87 pub uncheckpointed_receipts: u64,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
89 pub checkpoint_coverage_rate: Option<f64>,
90 pub lineage_covered_receipts: u64,
91 pub lineage_gap_receipts: u64,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
93 pub lineage_coverage_rate: Option<f64>,
94 pub pending_settlement_receipts: u64,
95 pub failed_settlement_receipts: u64,
96 pub direct_evidence_export_supported: bool,
97 pub child_receipt_scope: EvidenceChildReceiptScope,
98 pub proofs_complete: bool,
99 pub export_query: EvidenceExportQuery,
100 #[serde(default, skip_serializing_if = "Option::is_none")]
101 pub export_scope_note: Option<String>,
102}
103
104impl ComplianceReport {
105 #[must_use]
111 pub fn compliance_score(
112 &self,
113 inputs: &crate::compliance_score::ComplianceScoreInputs,
114 config: &crate::compliance_score::ComplianceScoreConfig,
115 agent_id: &str,
116 now: u64,
117 ) -> crate::compliance_score::ComplianceScore {
118 crate::compliance_score::compliance_score(self, inputs, config, agent_id, now)
119 }
120}