Skip to main content

datasynth_eval/
config.rs

1//! Configuration for the evaluation framework.
2
3use rust_decimal::Decimal;
4use serde::{Deserialize, Serialize};
5
6/// Main configuration for running an evaluation.
7#[derive(Debug, Clone, Serialize, Deserialize, Default)]
8pub struct EvaluationConfig {
9    /// Statistical evaluation settings.
10    pub statistical: StatisticalConfig,
11    /// Coherence evaluation settings.
12    pub coherence: CoherenceConfig,
13    /// Data quality evaluation settings.
14    pub quality: QualityConfig,
15    /// ML-readiness evaluation settings.
16    pub ml: MlConfig,
17    /// Privacy evaluation settings.
18    #[serde(default)]
19    pub privacy: PrivacyEvaluationConfig,
20    /// Report generation settings.
21    pub report: ReportConfig,
22    /// Pass/fail thresholds.
23    pub thresholds: EvaluationThresholds,
24    /// Quality gate configuration.
25    #[serde(default)]
26    pub quality_gates: QualityGateConfig,
27}
28
29/// Configuration for quality gates.
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct QualityGateConfig {
32    /// Whether quality gate evaluation is enabled.
33    #[serde(default)]
34    pub enabled: bool,
35    /// Profile name: "strict", "default", "lenient", or "custom".
36    #[serde(default = "default_gate_profile")]
37    pub profile: String,
38    /// Custom gate definitions (used when profile = "custom").
39    #[serde(default)]
40    pub custom_gates: Vec<CustomGateConfig>,
41    /// Whether to fail the generation run on gate violations.
42    #[serde(default)]
43    pub fail_on_violation: bool,
44}
45
46fn default_gate_profile() -> String {
47    "default".to_string()
48}
49
50impl Default for QualityGateConfig {
51    fn default() -> Self {
52        Self {
53            enabled: false,
54            profile: default_gate_profile(),
55            custom_gates: Vec::new(),
56            fail_on_violation: false,
57        }
58    }
59}
60
61/// Configuration for a custom quality gate.
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct CustomGateConfig {
64    /// Gate name.
65    pub name: String,
66    /// Metric to check (e.g., "benford_mad", "completion_rate", "duplicate_rate").
67    pub metric: String,
68    /// Threshold value.
69    pub threshold: f64,
70    /// Upper threshold for "between" comparison.
71    #[serde(default)]
72    pub upper_threshold: Option<f64>,
73    /// Comparison: "gte", "lte", "eq", "between".
74    #[serde(default = "default_comparison")]
75    pub comparison: String,
76}
77
78fn default_comparison() -> String {
79    "gte".to_string()
80}
81
82/// Privacy evaluation configuration.
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct PrivacyEvaluationConfig {
85    /// Enable membership inference attack testing.
86    pub mia_enabled: bool,
87    /// Enable linkage attack assessment.
88    pub linkage_enabled: bool,
89    /// Enable NIST SP 800-226 alignment report.
90    pub nist_alignment_enabled: bool,
91    /// Enable SynQP quality-privacy matrix.
92    pub synqp_enabled: bool,
93    /// Maximum AUC-ROC threshold for MIA (default: 0.6).
94    pub mia_auc_threshold: f64,
95    /// Maximum re-identification rate for linkage (default: 0.05).
96    pub max_reidentification_rate: f64,
97    /// Minimum k-anonymity for linkage (default: 5).
98    pub min_k_anonymity: usize,
99}
100
101impl Default for PrivacyEvaluationConfig {
102    fn default() -> Self {
103        Self {
104            mia_enabled: false,
105            linkage_enabled: false,
106            nist_alignment_enabled: false,
107            synqp_enabled: false,
108            mia_auc_threshold: 0.6,
109            max_reidentification_rate: 0.05,
110            min_k_anonymity: 5,
111        }
112    }
113}
114
115/// Statistical evaluation configuration.
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct StatisticalConfig {
118    /// Enable Benford's Law analysis.
119    pub benford_enabled: bool,
120    /// Enable amount distribution analysis.
121    pub amount_distribution_enabled: bool,
122    /// Enable line item distribution analysis.
123    pub line_item_enabled: bool,
124    /// Enable temporal pattern analysis.
125    pub temporal_enabled: bool,
126    /// Enable drift detection analysis.
127    pub drift_detection_enabled: bool,
128    /// Significance level for statistical tests (default: 0.05).
129    pub significance_level: f64,
130    /// Minimum sample size for statistical tests.
131    pub min_sample_size: usize,
132    /// Window size for drift detection rolling statistics.
133    pub drift_window_size: usize,
134    /// Enable anomaly realism evaluation.
135    #[serde(default)]
136    pub anomaly_realism_enabled: bool,
137}
138
139impl Default for StatisticalConfig {
140    fn default() -> Self {
141        Self {
142            benford_enabled: true,
143            amount_distribution_enabled: true,
144            line_item_enabled: true,
145            temporal_enabled: true,
146            drift_detection_enabled: true,
147            significance_level: 0.05,
148            min_sample_size: 100,
149            drift_window_size: 10,
150            anomaly_realism_enabled: false,
151        }
152    }
153}
154
155/// Coherence evaluation configuration.
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct CoherenceConfig {
158    /// Enable balance sheet validation.
159    pub balance_enabled: bool,
160    /// Enable subledger reconciliation.
161    pub subledger_enabled: bool,
162    /// Enable document chain validation.
163    pub document_chain_enabled: bool,
164    /// Enable intercompany matching validation.
165    pub intercompany_enabled: bool,
166    /// Enable referential integrity validation.
167    pub referential_enabled: bool,
168    /// Tolerance for balance differences.
169    pub balance_tolerance: Decimal,
170    /// Enable financial reporting evaluation.
171    #[serde(default)]
172    pub financial_reporting_enabled: bool,
173    /// Enable HR/payroll evaluation.
174    #[serde(default)]
175    pub hr_payroll_enabled: bool,
176    /// Enable manufacturing evaluation.
177    #[serde(default)]
178    pub manufacturing_enabled: bool,
179    /// Enable bank reconciliation evaluation.
180    #[serde(default)]
181    pub bank_reconciliation_enabled: bool,
182    /// Enable sourcing (S2C) evaluation.
183    #[serde(default)]
184    pub sourcing_enabled: bool,
185    /// Enable cross-process link evaluation.
186    #[serde(default)]
187    pub cross_process_enabled: bool,
188    /// Enable audit evaluation.
189    #[serde(default)]
190    pub audit_enabled: bool,
191    /// Enable tax evaluation.
192    #[serde(default)]
193    pub tax_enabled: bool,
194    /// Enable treasury evaluation.
195    #[serde(default)]
196    pub treasury_enabled: bool,
197    /// Enable project accounting evaluation.
198    #[serde(default)]
199    pub project_accounting_enabled: bool,
200    /// Enable ESG evaluation.
201    #[serde(default)]
202    pub esg_enabled: bool,
203    /// Enable sales quote evaluation.
204    #[serde(default)]
205    pub sales_quotes_enabled: bool,
206    /// Enable country pack evaluation.
207    #[serde(default)]
208    pub country_packs_enabled: bool,
209}
210
211impl Default for CoherenceConfig {
212    fn default() -> Self {
213        Self {
214            balance_enabled: true,
215            subledger_enabled: true,
216            document_chain_enabled: true,
217            intercompany_enabled: true,
218            referential_enabled: true,
219            balance_tolerance: Decimal::new(1, 2), // 0.01
220            financial_reporting_enabled: false,
221            hr_payroll_enabled: false,
222            manufacturing_enabled: false,
223            bank_reconciliation_enabled: false,
224            sourcing_enabled: false,
225            cross_process_enabled: false,
226            audit_enabled: false,
227            tax_enabled: false,
228            treasury_enabled: false,
229            project_accounting_enabled: false,
230            esg_enabled: false,
231            sales_quotes_enabled: false,
232            country_packs_enabled: false,
233        }
234    }
235}
236
237/// Data quality evaluation configuration.
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct QualityConfig {
240    /// Enable uniqueness validation.
241    pub uniqueness_enabled: bool,
242    /// Enable completeness validation.
243    pub completeness_enabled: bool,
244    /// Enable format consistency validation.
245    pub format_enabled: bool,
246    /// Enable cross-field consistency validation.
247    pub consistency_enabled: bool,
248    /// Similarity threshold for near-duplicate detection (0.0-1.0).
249    pub near_duplicate_threshold: f64,
250}
251
252impl Default for QualityConfig {
253    fn default() -> Self {
254        Self {
255            uniqueness_enabled: true,
256            completeness_enabled: true,
257            format_enabled: true,
258            consistency_enabled: true,
259            near_duplicate_threshold: 0.95,
260        }
261    }
262}
263
264/// ML-readiness evaluation configuration.
265#[derive(Debug, Clone, Serialize, Deserialize)]
266pub struct MlConfig {
267    /// Enable feature distribution analysis.
268    pub features_enabled: bool,
269    /// Enable label quality analysis.
270    pub labels_enabled: bool,
271    /// Enable train/test split validation.
272    pub splits_enabled: bool,
273    /// Enable graph structure analysis.
274    pub graph_enabled: bool,
275    /// Enable anomaly scoring analysis.
276    #[serde(default)]
277    pub anomaly_scoring_enabled: bool,
278    /// Enable feature quality analysis.
279    #[serde(default)]
280    pub feature_quality_enabled: bool,
281    /// Enable GNN readiness analysis.
282    #[serde(default)]
283    pub gnn_readiness_enabled: bool,
284    /// Enable domain gap analysis.
285    #[serde(default)]
286    pub domain_gap_enabled: bool,
287    /// Enable temporal fidelity analysis.
288    #[serde(default)]
289    pub temporal_fidelity_enabled: bool,
290    /// Enable scheme detectability analysis.
291    #[serde(default)]
292    pub scheme_detectability_enabled: bool,
293    /// Enable cross-modal consistency analysis.
294    #[serde(default)]
295    pub cross_modal_enabled: bool,
296    /// Enable embedding readiness analysis.
297    #[serde(default)]
298    pub embedding_readiness_enabled: bool,
299}
300
301impl Default for MlConfig {
302    fn default() -> Self {
303        Self {
304            features_enabled: true,
305            labels_enabled: true,
306            splits_enabled: true,
307            graph_enabled: true,
308            anomaly_scoring_enabled: false,
309            feature_quality_enabled: false,
310            gnn_readiness_enabled: false,
311            domain_gap_enabled: false,
312            temporal_fidelity_enabled: false,
313            scheme_detectability_enabled: false,
314            cross_modal_enabled: false,
315            embedding_readiness_enabled: false,
316        }
317    }
318}
319
320/// Report generation configuration.
321#[derive(Debug, Clone, Serialize, Deserialize)]
322pub struct ReportConfig {
323    /// Generate HTML report.
324    pub html_enabled: bool,
325    /// Generate JSON report.
326    pub json_enabled: bool,
327    /// Include charts in HTML report.
328    pub charts_enabled: bool,
329    /// Path to baseline report for comparison.
330    pub baseline_path: Option<String>,
331}
332
333impl Default for ReportConfig {
334    fn default() -> Self {
335        Self {
336            html_enabled: true,
337            json_enabled: true,
338            charts_enabled: true,
339            baseline_path: None,
340        }
341    }
342}
343
344/// Banking/KYC/AML evaluation configuration.
345#[derive(Debug, Clone, Default, Serialize, Deserialize)]
346pub struct BankingEvalConfig {
347    /// Enable KYC completeness evaluation.
348    #[serde(default)]
349    pub kyc_enabled: bool,
350    /// Enable AML detectability evaluation.
351    #[serde(default)]
352    pub aml_enabled: bool,
353}
354
355/// Process mining evaluation configuration.
356#[derive(Debug, Clone, Default, Serialize, Deserialize)]
357pub struct ProcessMiningEvalConfig {
358    /// Enable event sequence validation.
359    #[serde(default)]
360    pub event_sequence_enabled: bool,
361    /// Enable variant analysis.
362    #[serde(default)]
363    pub variant_analysis_enabled: bool,
364}
365
366/// Causal model evaluation configuration.
367#[derive(Debug, Clone, Default, Serialize, Deserialize)]
368pub struct CausalEvalConfig {
369    /// Enable causal model evaluation.
370    #[serde(default)]
371    pub enabled: bool,
372}
373
374/// LLM enrichment quality evaluation configuration.
375#[derive(Debug, Clone, Default, Serialize, Deserialize)]
376pub struct EnrichmentEvalConfig {
377    /// Enable enrichment quality evaluation.
378    #[serde(default)]
379    pub enabled: bool,
380}
381
382/// Pass/fail thresholds for evaluation metrics.
383#[derive(Debug, Clone, Serialize, Deserialize)]
384pub struct EvaluationThresholds {
385    // Statistical thresholds
386    /// Minimum p-value for Benford's Law chi-squared test.
387    pub benford_p_value_min: f64,
388    /// Maximum Mean Absolute Deviation for Benford's Law.
389    pub benford_mad_max: f64,
390    /// Minimum p-value for amount distribution KS test.
391    pub amount_ks_p_value_min: f64,
392    /// Minimum correlation for temporal patterns.
393    pub temporal_correlation_min: f64,
394
395    // Drift detection thresholds
396    /// Minimum drift magnitude to consider significant.
397    pub drift_magnitude_min: f64,
398    /// Maximum Hellinger distance threshold.
399    pub drift_hellinger_max: f64,
400    /// Maximum Population Stability Index (PSI) threshold.
401    pub drift_psi_max: f64,
402    /// Minimum F1 score for drift detection quality.
403    pub drift_f1_score_min: f64,
404
405    // Coherence thresholds
406    /// Maximum balance sheet imbalance.
407    pub balance_tolerance: Decimal,
408    /// Minimum subledger reconciliation rate.
409    pub subledger_reconciliation_rate_min: f64,
410    /// Minimum document chain completion rate.
411    pub document_chain_completion_min: f64,
412    /// Minimum intercompany match rate.
413    pub ic_match_rate_min: f64,
414    /// Minimum referential integrity rate.
415    pub referential_integrity_min: f64,
416
417    // Quality thresholds
418    /// Maximum duplicate rate.
419    pub duplicate_rate_max: f64,
420    /// Minimum completeness rate.
421    pub completeness_rate_min: f64,
422    /// Minimum format consistency rate.
423    pub format_consistency_min: f64,
424
425    // New evaluator thresholds
426    /// Minimum anomaly separability (AUC-ROC).
427    #[serde(default = "default_anomaly_separability")]
428    pub min_anomaly_separability: f64,
429    /// Minimum feature quality score.
430    #[serde(default = "default_feature_quality")]
431    pub min_feature_quality: f64,
432    /// Minimum GNN readiness score.
433    #[serde(default = "default_gnn_readiness")]
434    pub min_gnn_readiness: f64,
435    /// Maximum domain gap score.
436    #[serde(default = "default_domain_gap")]
437    pub max_domain_gap: f64,
438    /// Minimum temporal fidelity score.
439    #[serde(default = "default_temporal_fidelity")]
440    pub min_temporal_fidelity: f64,
441    /// Minimum scheme detectability score.
442    #[serde(default = "default_scheme_detectability")]
443    pub min_scheme_detectability: f64,
444    /// Minimum cross-modal consistency.
445    #[serde(default = "default_cross_modal")]
446    pub min_cross_modal_consistency: f64,
447    /// Minimum embedding readiness score.
448    #[serde(default = "default_embedding_readiness")]
449    pub min_embedding_readiness: f64,
450
451    // ML thresholds
452    /// Minimum anomaly rate.
453    pub anomaly_rate_min: f64,
454    /// Maximum anomaly rate.
455    pub anomaly_rate_max: f64,
456    /// Minimum label coverage.
457    pub label_coverage_min: f64,
458    /// Minimum train ratio.
459    pub train_ratio_min: f64,
460    /// Minimum graph connectivity.
461    pub graph_connectivity_min: f64,
462}
463
464fn default_anomaly_separability() -> f64 {
465    0.70
466}
467fn default_feature_quality() -> f64 {
468    0.60
469}
470fn default_gnn_readiness() -> f64 {
471    0.65
472}
473fn default_domain_gap() -> f64 {
474    0.25
475}
476fn default_temporal_fidelity() -> f64 {
477    0.70
478}
479fn default_scheme_detectability() -> f64 {
480    0.60
481}
482fn default_cross_modal() -> f64 {
483    0.60
484}
485fn default_embedding_readiness() -> f64 {
486    0.50
487}
488
489impl Default for EvaluationThresholds {
490    fn default() -> Self {
491        Self {
492            // Statistical
493            benford_p_value_min: 0.05,
494            benford_mad_max: 0.015,
495            amount_ks_p_value_min: 0.05,
496            temporal_correlation_min: 0.80,
497
498            // New evaluator thresholds
499            min_anomaly_separability: 0.70,
500            min_feature_quality: 0.60,
501            min_gnn_readiness: 0.65,
502            max_domain_gap: 0.25,
503            min_temporal_fidelity: 0.70,
504            min_scheme_detectability: 0.60,
505            min_cross_modal_consistency: 0.60,
506            min_embedding_readiness: 0.50,
507
508            // Drift detection
509            drift_magnitude_min: 0.05,
510            drift_hellinger_max: 0.30,
511            drift_psi_max: 0.25,
512            drift_f1_score_min: 0.50,
513
514            // Coherence
515            balance_tolerance: Decimal::new(1, 2), // 0.01
516            subledger_reconciliation_rate_min: 0.99,
517            document_chain_completion_min: 0.90,
518            ic_match_rate_min: 0.95,
519            referential_integrity_min: 0.99,
520
521            // Quality
522            duplicate_rate_max: 0.01,
523            completeness_rate_min: 0.95,
524            format_consistency_min: 0.99,
525
526            // ML
527            anomaly_rate_min: 0.01,
528            anomaly_rate_max: 0.20,
529            label_coverage_min: 0.99,
530            train_ratio_min: 0.60,
531            graph_connectivity_min: 0.95,
532        }
533    }
534}
535
536impl EvaluationThresholds {
537    /// Create strict thresholds for rigorous validation.
538    pub fn strict() -> Self {
539        Self {
540            min_anomaly_separability: 0.80,
541            min_feature_quality: 0.70,
542            min_gnn_readiness: 0.75,
543            max_domain_gap: 0.15,
544            min_temporal_fidelity: 0.80,
545            min_scheme_detectability: 0.70,
546            min_cross_modal_consistency: 0.70,
547            min_embedding_readiness: 0.60,
548            benford_p_value_min: 0.10,
549            benford_mad_max: 0.010,
550            amount_ks_p_value_min: 0.10,
551            temporal_correlation_min: 0.90,
552            drift_magnitude_min: 0.03,
553            drift_hellinger_max: 0.20,
554            drift_psi_max: 0.15,
555            drift_f1_score_min: 0.70,
556            balance_tolerance: Decimal::new(1, 4), // 0.0001
557            subledger_reconciliation_rate_min: 0.999,
558            document_chain_completion_min: 0.95,
559            ic_match_rate_min: 0.99,
560            referential_integrity_min: 0.999,
561            duplicate_rate_max: 0.001,
562            completeness_rate_min: 0.99,
563            format_consistency_min: 0.999,
564            anomaly_rate_min: 0.01,
565            anomaly_rate_max: 0.10,
566            label_coverage_min: 0.999,
567            train_ratio_min: 0.70,
568            graph_connectivity_min: 0.99,
569        }
570    }
571
572    /// Create lenient thresholds for exploratory validation.
573    pub fn lenient() -> Self {
574        Self {
575            min_anomaly_separability: 0.55,
576            min_feature_quality: 0.45,
577            min_gnn_readiness: 0.50,
578            max_domain_gap: 0.40,
579            min_temporal_fidelity: 0.55,
580            min_scheme_detectability: 0.45,
581            min_cross_modal_consistency: 0.45,
582            min_embedding_readiness: 0.35,
583            benford_p_value_min: 0.01,
584            benford_mad_max: 0.025,
585            amount_ks_p_value_min: 0.01,
586            temporal_correlation_min: 0.60,
587            drift_magnitude_min: 0.10,
588            drift_hellinger_max: 0.50,
589            drift_psi_max: 0.40,
590            drift_f1_score_min: 0.30,
591            balance_tolerance: Decimal::new(1, 1), // 0.1
592            subledger_reconciliation_rate_min: 0.90,
593            document_chain_completion_min: 0.80,
594            ic_match_rate_min: 0.85,
595            referential_integrity_min: 0.95,
596            duplicate_rate_max: 0.05,
597            completeness_rate_min: 0.90,
598            format_consistency_min: 0.95,
599            anomaly_rate_min: 0.005,
600            anomaly_rate_max: 0.30,
601            label_coverage_min: 0.95,
602            train_ratio_min: 0.50,
603            graph_connectivity_min: 0.90,
604        }
605    }
606}