Skip to main content

chio_autonomy/
model.rs

1use serde::{Deserialize, Serialize};
2
3use crate::capability::{runtime_attestation::RuntimeAssuranceTier, scope::MonetaryAmount};
4use crate::market::LiabilityCoverageClass;
5use crate::receipt::lineage::SignedExportEnvelope;
6use crate::web3::settlement::Web3SettlementLifecycleState;
7
8pub const CHIO_AUTONOMOUS_PRICING_INPUT_SCHEMA: &str = "chio.autonomous-pricing-input.v1";
9pub const CHIO_AUTONOMOUS_PRICING_AUTHORITY_ENVELOPE_SCHEMA: &str =
10    "chio.autonomous-pricing-authority-envelope.v1";
11pub const CHIO_AUTONOMOUS_PRICING_DECISION_SCHEMA: &str = "chio.autonomous-pricing-decision.v1";
12pub const CHIO_CAPITAL_POOL_OPTIMIZATION_SCHEMA: &str = "chio.capital-pool-optimization.v1";
13pub const CHIO_CAPITAL_POOL_SIMULATION_REPORT_SCHEMA: &str =
14    "chio.capital-pool-simulation-report.v1";
15pub const CHIO_AUTONOMOUS_EXECUTION_DECISION_SCHEMA: &str = "chio.autonomous-execution-decision.v1";
16pub const CHIO_AUTONOMOUS_ROLLBACK_PLAN_SCHEMA: &str = "chio.autonomous-rollback-plan.v1";
17pub const CHIO_AUTONOMOUS_COMPARISON_REPORT_SCHEMA: &str = "chio.autonomous-comparison-report.v1";
18pub const CHIO_AUTONOMOUS_DRIFT_REPORT_SCHEMA: &str = "chio.autonomous-drift-report.v1";
19pub const CHIO_AUTONOMOUS_QUALIFICATION_MATRIX_SCHEMA: &str =
20    "chio.autonomous-qualification-matrix.v1";
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
23#[serde(rename_all = "snake_case")]
24pub enum AutonomousEvidenceKind {
25    UnderwritingDecision,
26    ExposureLedger,
27    CreditScorecard,
28    CapitalBook,
29    CreditFacility,
30    CreditLossLifecycle,
31    Web3SettlementReceipt,
32    LiabilityQuoteResponse,
33    LiabilityAutoBindDecision,
34    ClaimWorkflow,
35    RuntimeAssuranceAppraisal,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
39#[serde(rename_all = "snake_case")]
40pub enum AutonomousPricingAction {
41    Reprice,
42    Renew,
43    Decline,
44    Bind,
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
48#[serde(rename_all = "snake_case")]
49pub enum AutonomousPricingDisposition {
50    Reprice,
51    Renew,
52    Decline,
53    BindWithinEnvelope,
54    ManualReview,
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
58#[serde(rename_all = "snake_case")]
59pub enum AutonomousDecisionReviewState {
60    AutoApproved,
61    HumanReviewRequired,
62    ShadowOnly,
63    Blocked,
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
67#[serde(rename_all = "snake_case")]
68pub enum AutonomousAutomationMode {
69    Shadow,
70    Advisory,
71    Active,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
75#[serde(rename_all = "snake_case")]
76pub enum AutonomousAuthorityEnvelopeKind {
77    OperatorPolicy,
78    RegulatedRole,
79    DelegatedMarketAuthority,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
83#[serde(rename_all = "snake_case")]
84pub enum AutonomousPricingExplanationDirection {
85    Increase,
86    Decrease,
87    Hold,
88    Escalate,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
92#[serde(rename_all = "snake_case")]
93pub enum CapitalOptimizationAction {
94    IncreaseReserve,
95    DecreaseReserve,
96    ShiftCapacity,
97    HoldCapacity,
98    DeferClaim,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
102#[serde(rename_all = "snake_case")]
103pub enum CapitalPoolSimulationMode {
104    WhatIf,
105    Shadow,
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
109#[serde(rename_all = "snake_case")]
110pub enum AutonomousExecutionAction {
111    Reprice,
112    Renew,
113    Decline,
114    Bind,
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
118#[serde(rename_all = "snake_case")]
119pub enum AutonomousExecutionLifecycleState {
120    Prepared,
121    Executed,
122    Interrupted,
123    RolledBack,
124    Blocked,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
128#[serde(rename_all = "snake_case")]
129pub enum AutonomousDriftKind {
130    LossRatioSpike,
131    PremiumVariance,
132    CapitalUtilization,
133    SettlementFailureRate,
134    OverrideRate,
135    ModelVersionMismatch,
136    EvidenceStaleness,
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
140#[serde(rename_all = "snake_case")]
141pub enum AutonomousDriftSeverity {
142    Warning,
143    Critical,
144}
145
146#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
147#[serde(rename_all = "snake_case")]
148pub enum AutonomousSafeState {
149    ShadowModeOnly,
150    DelegatedOnly,
151    BindDisabled,
152    FullPause,
153}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
156#[serde(rename_all = "snake_case")]
157pub enum AutonomousRollbackAction {
158    SwitchToSafeState,
159    CancelPendingExecution,
160    RequireHumanApproval,
161    RevertToDelegatedAuthority,
162    FreezeModelVersion,
163}
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
166#[serde(rename_all = "snake_case")]
167pub enum AutonomousComparisonDisposition {
168    Match,
169    NarrowerThanManual,
170    WiderThanManual,
171    ManualOverride,
172}
173
174#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
175#[serde(rename_all = "snake_case")]
176pub enum AutonomousQualificationOutcome {
177    Pass,
178    FailClosed,
179}
180
181#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
182#[serde(deny_unknown_fields)]
183pub struct AutonomousEvidenceReference {
184    pub kind: AutonomousEvidenceKind,
185    pub reference_id: String,
186    #[serde(default, skip_serializing_if = "Option::is_none")]
187    pub observed_at: Option<u64>,
188    #[serde(default, skip_serializing_if = "Option::is_none")]
189    pub locator: Option<String>,
190}
191
192#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(deny_unknown_fields)]
194pub struct AutonomousPricingSupportBoundary {
195    pub delegated_authority_required: bool,
196    pub live_bind_supported: bool,
197    pub reserve_optimization_required: bool,
198    pub operator_override_supported: bool,
199}
200
201impl Default for AutonomousPricingSupportBoundary {
202    fn default() -> Self {
203        Self {
204            delegated_authority_required: true,
205            live_bind_supported: true,
206            reserve_optimization_required: true,
207            operator_override_supported: true,
208        }
209    }
210}
211
212#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
213#[serde(deny_unknown_fields)]
214pub struct AutonomousModelProvenance {
215    pub model_id: String,
216    pub model_version: String,
217    pub engine_family: String,
218    pub published_at: u64,
219    pub training_cutoff: u64,
220    pub input_hash: String,
221    pub explanation_version: String,
222    pub supports_counterfactuals: bool,
223    pub supports_shadow_evaluation: bool,
224}
225
226#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
227#[serde(deny_unknown_fields)]
228pub struct AutonomousPricingInputArtifact {
229    pub schema: String,
230    pub input_id: String,
231    pub generated_at: u64,
232    pub subject_key: String,
233    pub provider_id: String,
234    pub coverage_class: LiabilityCoverageClass,
235    pub currency: String,
236    pub requested_coverage_amount: MonetaryAmount,
237    pub receipt_history_window_secs: u64,
238    pub reputation_score_bps: u32,
239    pub runtime_assurance_tier: RuntimeAssuranceTier,
240    pub pending_loss_units: u64,
241    pub settled_loss_units: u64,
242    pub available_capital_units: u64,
243    #[serde(default, skip_serializing_if = "Option::is_none")]
244    pub latest_web3_settlement_state: Option<Web3SettlementLifecycleState>,
245    pub evidence_refs: Vec<AutonomousEvidenceReference>,
246    pub support_boundary: AutonomousPricingSupportBoundary,
247    #[serde(default, skip_serializing_if = "Option::is_none")]
248    pub note: Option<String>,
249}
250
251pub type SignedAutonomousPricingInput = SignedExportEnvelope<AutonomousPricingInputArtifact>;
252
253#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
254#[serde(deny_unknown_fields)]
255pub struct AutonomousPricingAuthorityEnvelopeArtifact {
256    pub schema: String,
257    pub envelope_id: String,
258    pub issued_at: u64,
259    pub subject_key: String,
260    pub provider_id: String,
261    pub currency: String,
262    pub kind: AutonomousAuthorityEnvelopeKind,
263    pub automation_mode: AutonomousAutomationMode,
264    pub permitted_actions: Vec<AutonomousPricingAction>,
265    pub authority_chain_refs: Vec<String>,
266    pub max_coverage_amount: MonetaryAmount,
267    pub max_premium_amount: MonetaryAmount,
268    pub max_rate_change_bps: u32,
269    pub max_daily_decisions: u32,
270    pub requires_human_review_for_bind: bool,
271    #[serde(default, skip_serializing_if = "Option::is_none")]
272    pub requires_human_review_above_premium: Option<MonetaryAmount>,
273    #[serde(default, skip_serializing_if = "Option::is_none")]
274    pub regulated_role: Option<String>,
275    #[serde(default, skip_serializing_if = "Option::is_none")]
276    pub delegated_authority_reference: Option<String>,
277    pub not_before: u64,
278    pub not_after: u64,
279    pub support_boundary: AutonomousPricingSupportBoundary,
280    #[serde(default, skip_serializing_if = "Option::is_none")]
281    pub note: Option<String>,
282}
283
284pub type SignedAutonomousPricingAuthorityEnvelope =
285    SignedExportEnvelope<AutonomousPricingAuthorityEnvelopeArtifact>;
286
287#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
288#[serde(deny_unknown_fields)]
289pub struct AutonomousPricingExplanationFactor {
290    pub code: String,
291    pub description: String,
292    pub direction: AutonomousPricingExplanationDirection,
293    pub weight_bps: u32,
294    #[serde(default, skip_serializing_if = "Vec::is_empty")]
295    pub evidence_refs: Vec<AutonomousEvidenceReference>,
296}
297
298#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
299#[serde(deny_unknown_fields)]
300pub struct AutonomousPricingDecisionArtifact {
301    pub schema: String,
302    pub decision_id: String,
303    pub issued_at: u64,
304    pub pricing_input: AutonomousPricingInputArtifact,
305    pub model: AutonomousModelProvenance,
306    pub authority_envelope: AutonomousPricingAuthorityEnvelopeArtifact,
307    pub disposition: AutonomousPricingDisposition,
308    pub review_state: AutonomousDecisionReviewState,
309    pub suggested_coverage_amount: MonetaryAmount,
310    pub suggested_premium_amount: MonetaryAmount,
311    #[serde(default, skip_serializing_if = "Option::is_none")]
312    pub suggested_ceiling_factor_bps: Option<u32>,
313    pub confidence_bps: u32,
314    pub explanation_factors: Vec<AutonomousPricingExplanationFactor>,
315    #[serde(default, skip_serializing_if = "Option::is_none")]
316    pub comparison_baseline_ref: Option<String>,
317    #[serde(default, skip_serializing_if = "Option::is_none")]
318    pub note: Option<String>,
319}
320
321pub type SignedAutonomousPricingDecision = SignedExportEnvelope<AutonomousPricingDecisionArtifact>;
322
323#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
324#[serde(deny_unknown_fields)]
325pub struct CapitalPoolOptimizationSupportBoundary {
326    pub live_mutation_supported: bool,
327    pub scenario_comparison_supported: bool,
328    pub cross_currency_optimization_supported: bool,
329    pub web3_reconciliation_required: bool,
330    pub operator_override_required: bool,
331}
332
333impl Default for CapitalPoolOptimizationSupportBoundary {
334    fn default() -> Self {
335        Self {
336            live_mutation_supported: false,
337            scenario_comparison_supported: true,
338            cross_currency_optimization_supported: false,
339            web3_reconciliation_required: true,
340            operator_override_required: true,
341        }
342    }
343}
344
345#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
346#[serde(deny_unknown_fields)]
347pub struct CapitalPoolRecommendation {
348    pub action: CapitalOptimizationAction,
349    pub source_ref: String,
350    #[serde(default, skip_serializing_if = "Option::is_none")]
351    pub destination_ref: Option<String>,
352    pub amount: MonetaryAmount,
353    pub rationale: String,
354}
355
356#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
357#[serde(deny_unknown_fields)]
358pub struct CapitalPoolOptimizationArtifact {
359    pub schema: String,
360    pub optimization_id: String,
361    pub issued_at: u64,
362    pub subject_key: String,
363    pub currency: String,
364    pub pricing_decision_ref: String,
365    pub capital_book_ref: String,
366    pub facility_refs: Vec<String>,
367    #[serde(default, skip_serializing_if = "Vec::is_empty")]
368    pub pending_claim_refs: Vec<String>,
369    pub target_reserve_ratio_bps: u32,
370    pub max_facility_utilization_bps: u32,
371    pub max_bind_capacity_units: u64,
372    pub recommendations: Vec<CapitalPoolRecommendation>,
373    pub support_boundary: CapitalPoolOptimizationSupportBoundary,
374    #[serde(default, skip_serializing_if = "Option::is_none")]
375    pub note: Option<String>,
376}
377
378pub type SignedCapitalPoolOptimization = SignedExportEnvelope<CapitalPoolOptimizationArtifact>;
379
380#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
381#[serde(deny_unknown_fields)]
382pub struct CapitalPoolSimulationDelta {
383    pub metric_name: String,
384    pub baseline_units: u64,
385    pub candidate_units: u64,
386    pub description: String,
387}
388
389#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
390#[serde(deny_unknown_fields)]
391pub struct CapitalPoolSimulationReport {
392    pub schema: String,
393    pub simulation_id: String,
394    pub generated_at: u64,
395    pub subject_key: String,
396    pub currency: String,
397    pub baseline_optimization: CapitalPoolOptimizationArtifact,
398    pub candidate_optimization: CapitalPoolOptimizationArtifact,
399    pub simulation_mode: CapitalPoolSimulationMode,
400    pub deltas: Vec<CapitalPoolSimulationDelta>,
401    pub recommended_operator_action: String,
402    #[serde(default, skip_serializing_if = "Option::is_none")]
403    pub note: Option<String>,
404}
405
406pub type SignedCapitalPoolSimulationReport = SignedExportEnvelope<CapitalPoolSimulationReport>;
407
408#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
409#[serde(deny_unknown_fields)]
410pub struct AutonomousExecutionSafetyGate {
411    pub name: String,
412    pub passed: bool,
413    pub description: String,
414}
415
416#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
417#[serde(deny_unknown_fields)]
418pub struct AutonomousExecutionRollbackControl {
419    pub rollback_plan_ref: String,
420    pub interruptible: bool,
421    pub human_interrupt_contact: String,
422}
423
424#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
425#[serde(deny_unknown_fields)]
426pub struct AutonomousExecutionDecisionArtifact {
427    pub schema: String,
428    pub execution_id: String,
429    pub issued_at: u64,
430    pub pricing_decision_ref: String,
431    pub optimization_ref: String,
432    pub authority_envelope_ref: String,
433    pub subject_key: String,
434    pub provider_id: String,
435    pub currency: String,
436    pub action: AutonomousExecutionAction,
437    pub lifecycle_state: AutonomousExecutionLifecycleState,
438    #[serde(default, skip_serializing_if = "Option::is_none")]
439    pub quote_response_ref: Option<String>,
440    #[serde(default, skip_serializing_if = "Option::is_none")]
441    pub auto_bind_decision_ref: Option<String>,
442    #[serde(default, skip_serializing_if = "Option::is_none")]
443    pub bound_coverage_ref: Option<String>,
444    #[serde(default, skip_serializing_if = "Option::is_none")]
445    pub settlement_dispatch_ref: Option<String>,
446    pub safety_gates: Vec<AutonomousExecutionSafetyGate>,
447    pub rollback_control: AutonomousExecutionRollbackControl,
448    #[serde(default, skip_serializing_if = "Option::is_none")]
449    pub note: Option<String>,
450}
451
452pub type SignedAutonomousExecutionDecision =
453    SignedExportEnvelope<AutonomousExecutionDecisionArtifact>;
454
455#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
456#[serde(deny_unknown_fields)]
457pub struct AutonomousRollbackPlanArtifact {
458    pub schema: String,
459    pub plan_id: String,
460    pub issued_at: u64,
461    pub subject_key: String,
462    pub safe_state: AutonomousSafeState,
463    pub triggers: Vec<AutonomousDriftKind>,
464    pub actions: Vec<AutonomousRollbackAction>,
465    pub requires_operator_ack: bool,
466    #[serde(default, skip_serializing_if = "Option::is_none")]
467    pub note: Option<String>,
468}
469
470pub type SignedAutonomousRollbackPlan = SignedExportEnvelope<AutonomousRollbackPlanArtifact>;
471
472#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
473#[serde(deny_unknown_fields)]
474pub struct AutonomousComparisonDelta {
475    pub field: String,
476    pub automated_value: String,
477    pub manual_value: String,
478    pub description: String,
479}
480
481#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
482#[serde(deny_unknown_fields)]
483pub struct AutonomousComparisonReport {
484    pub schema: String,
485    pub comparison_id: String,
486    pub generated_at: u64,
487    pub pricing_decision_ref: String,
488    pub manual_decision_ref: String,
489    pub disposition: AutonomousComparisonDisposition,
490    #[serde(default, skip_serializing_if = "Vec::is_empty")]
491    pub deltas: Vec<AutonomousComparisonDelta>,
492    #[serde(default, skip_serializing_if = "Option::is_none")]
493    pub override_reference: Option<String>,
494    #[serde(default, skip_serializing_if = "Option::is_none")]
495    pub note: Option<String>,
496}
497
498pub type SignedAutonomousComparisonReport = SignedExportEnvelope<AutonomousComparisonReport>;
499
500#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
501#[serde(deny_unknown_fields)]
502pub struct AutonomousDriftSignal {
503    pub kind: AutonomousDriftKind,
504    pub severity: AutonomousDriftSeverity,
505    pub metric_name: String,
506    pub observed_value: u64,
507    pub threshold_value: u64,
508    pub description: String,
509    #[serde(default, skip_serializing_if = "Vec::is_empty")]
510    pub evidence_refs: Vec<AutonomousEvidenceReference>,
511}
512
513#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
514#[serde(deny_unknown_fields)]
515pub struct AutonomousDriftReport {
516    pub schema: String,
517    pub drift_report_id: String,
518    pub generated_at: u64,
519    pub subject_key: String,
520    pub pricing_decision_ref: String,
521    pub optimization_ref: String,
522    pub drift_signals: Vec<AutonomousDriftSignal>,
523    pub rollback_plan: AutonomousRollbackPlanArtifact,
524    pub comparison_report: AutonomousComparisonReport,
525    pub fail_safe_engaged: bool,
526    #[serde(default, skip_serializing_if = "Option::is_none")]
527    pub note: Option<String>,
528}
529
530pub type SignedAutonomousDriftReport = SignedExportEnvelope<AutonomousDriftReport>;
531
532#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
533#[serde(deny_unknown_fields)]
534pub struct AutonomousQualificationCase {
535    pub id: String,
536    pub name: String,
537    pub requirement_ids: Vec<String>,
538    #[serde(default, skip_serializing_if = "Option::is_none")]
539    pub drift_kind: Option<AutonomousDriftKind>,
540    pub expected_outcome: AutonomousQualificationOutcome,
541    pub observed_outcome: AutonomousQualificationOutcome,
542    pub notes: String,
543}
544
545#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
546#[serde(deny_unknown_fields)]
547pub struct AutonomousQualificationMatrix {
548    pub schema: String,
549    pub profile_id: String,
550    pub cases: Vec<AutonomousQualificationCase>,
551}