pub struct FraudConfig {
pub enabled: bool,
pub fraud_rate: f64,
pub document_fraud_rate: Option<f64>,
pub propagate_to_lines: bool,
pub propagate_to_document: bool,
pub fraud_type_distribution: FraudTypeDistribution,
pub clustering_enabled: bool,
pub clustering_factor: f64,
pub approval_thresholds: Vec<f64>,
pub per_process_rates: HashMap<String, f64>,
}Expand description
Fraud simulation configuration.
§Document-level vs. line-level fraud
fraud_rate applies to individual journal-entry lines (line-level).
document_fraud_rate (optional) applies to source documents
(purchase orders, vendor invoices, customer invoices, payments), and when
propagate_to_lines is true, every JE derived from a fraudulent document
also gets is_fraud = true. This lets users express either:
- pure line-level fraud (
document_fraud_rate = None): legacy behaviour; - pure document-level fraud (
fraud_rate ≈ 0anddocument_fraud_rateset): fraud rings expressed at document granularity — realistic for PO/invoice fraud schemes where one fraudulent document spawns multiple derived JEs; - hybrid (both set): document-level scheme fraud plus unrelated line-level slip-ups.
propagate_to_document does the inverse: when a JE is tagged as fraud by
the anomaly injector, its source document is also marked fraudulent.
Fields§
§enabled: boolEnable fraud scenario generation
fraud_rate: f64Line-level fraud rate: fraction of individual JE lines flagged as fraud (0.0 to 1.0).
§Effective line-level prevalence
If document_fraud_rate = Some(d) and propagate_to_lines = true,
the observed line-level fraud prevalence is roughly:
P(line is_fraud) ≈ fraud_rate + d × avg_lines_per_fraud_doc / total_lines
For a typical retail job (avg 3 lines per document, ~30 % of lines come from doc-flow-derived JEs) the combined rate lands near:
fraud_rate + 0.3 × d
so setting fraud_rate=0.02, document_fraud_rate=0.05, propagate_to_lines=true
produces ~3.5 % line-level fraud, not 2 %. To target a specific
line-level prevalence X, choose fraud_rate = X - 0.3 × d.
document_fraud_rate: Option<f64>Document-level fraud rate: fraction of source documents (PO, vendor
invoice, customer invoice, payment) flagged as fraud. None disables
document-level injection; Some(r) marks ~r × document-count as fraud
independently of the line-level rate.
v4.4.2+ default: Some(0.01) — the SDK team reported
is_fraud_propagated: 0/72 regressed from 12/33 in 3.1.1 because
the default had silently become None. A 1% document-fraud default
restores the propagation signal (~0.3% of JE headers carry
is_fraud_propagated = true) without meaningfully changing the
line-level fraud prevalence. Set to Some(0.0) or null in your
YAML to explicitly disable document-level injection.
propagate_to_lines: boolWhen true, flagging a document as fraudulent cascades is_fraud = true
and fraud_type to every journal entry derived from that document,
and records fraud_source_document_id on the JE header.
Default: true.
propagate_to_document: boolWhen true, tagging a JE as fraud via line-level anomaly injection also
marks the JE’s source document as fraudulent (if it can be resolved).
Default: true.
fraud_type_distribution: FraudTypeDistributionFraud type distribution
clustering_enabled: boolEnable fraud clustering
clustering_factor: f64Clustering factor
approval_thresholds: Vec<f64>Approval thresholds for threshold-adjacent fraud pattern
per_process_rates: HashMap<String, f64>v5.30 B3 (#153) — per-business-process fraud rate overrides.
Keys are business-process slugs ("P2P", "O2C", "R2R", "H2R",
"A2R"); values are line-level fraud rates that override the
global fraud_rate when a JE’s selected business process matches a
key. Unmatched processes fall back to fraud_rate.
When empty (the default), per-process rates are disabled and every
JE uses the global fraud_rate — preserving v5.29 byte-identical
output for configs that don’t opt in.
§Why
Real audit data shows process-specific fraud signatures (R2R
manual-close and period-end accruals carry higher fraud
concentration than P2P invoice-processing). The v5.29 global
fraud_rate flattens this signal, leaving the GNN fraud detector
at a uniform per-process AUC band (0.914-0.925 in the v5.29 retrain).
§Example
fraud:
fraud_rate: 0.02 # baseline for unmapped processes
per_process_rates:
R2R: 0.06 # 3× baseline — period-close hot spot
P2P: 0.04 # 2× baseline — invoice fraud
O2C: 0.025 # 1.25× baseline — revenue manipulation
H2R: 0.015 # below baseline — payroll
A2R: 0.020 # baseline — asset accountingAggregate effective line-level prevalence depends on the
business_processes weights mix; calibrate to a target X by
solving for the weighted average. For default v5.29 weights
(P2P 0.35, O2C 0.35, R2R 0.20, H2R 0.05, A2R 0.05) the
example above yields ~0.0335 line-level fraud.
Trait Implementations§
Source§impl Clone for FraudConfig
impl Clone for FraudConfig
Source§fn clone(&self) -> FraudConfig
fn clone(&self) -> FraudConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for FraudConfig
impl Debug for FraudConfig
Source§impl Default for FraudConfig
impl Default for FraudConfig
Source§impl<'de> Deserialize<'de> for FraudConfig
impl<'de> Deserialize<'de> for FraudConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for FraudConfig
impl RefUnwindSafe for FraudConfig
impl Send for FraudConfig
impl Sync for FraudConfig
impl Unpin for FraudConfig
impl UnsafeUnpin for FraudConfig
impl UnwindSafe for FraudConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.