#Cascade Screening Cookbook
Version: 0.43.0 | Updated: 2026-03-28 | Applies to: ranvier-runtime 0.36+ | Category: Cookbook
#Overview
Cascade screening is a sequential filter pattern where a subject passes through multiple independent screens. Each screen can reject (short-circuit) or pass through. This pattern is ideal when:
- Each check is independently valid
- Early rejection saves downstream computation
- The order of checks matters (cheapest/fastest first)
- Each screen is independently testable and replaceable
#1. Pattern Anatomy
Input โ Screen A โ Screen B โ Screen C โ Screen D โ Approved
โ โ โ โ
Reject A Reject B Reject C Reject DKey characteristics:
- Fail-fast: First rejection short-circuits the entire pipeline
- Independence: Each screen knows nothing about other screens
- Ordering: Place cheapest/fastest checks first for efficiency
- Auditability: Each screen logs its decision
#2. Applied Domain: AML/KYC Compliance
Four-stage compliance screening for new customers.
let screening = Axon::typed::<CustomerApplication, String>("kyc-screening")
.then(sanctions_check) // Screen 1: O(1) list lookup
.then(pep_check) // Screen 2: O(1) flag check
.then(risk_scoring) // Screen 3: O(n) algorithm
.then(document_verification); // Screen 4: expensive external API
// Screen order matters: sanctions check is instant, document
// verification calls an external API. Ordering cheapest-first
// avoids unnecessary API calls for sanctioned applicants.#Each screen as a Transition
#[transition]
async fn sanctions_check(
applicant: CustomerApplication,
) -> Outcome<CustomerApplication, String> {
let sanctioned_countries = ["NK", "SY", "IR"];
if sanctioned_countries.contains(&applicant.country.as_str()) {
return Outcome::Fault(format!(
"Screen 1 REJECTED: {} from sanctioned country {}",
applicant.name, applicant.country
));
}
Outcome::Next(applicant)
}#3. Applied Domain: Content Moderation
Three-stage content moderation pipeline.
let moderation = Axon::typed::<ContentSubmission, String>("content-moderation")
.then(spam_filter) // Fast regex/heuristic check
.then(toxicity_classifier) // ML model inference
.then(policy_enforcer); // Business rule evaluation#Pattern insight
Spam filter (microseconds) runs before toxicity classifier (milliseconds). If content is obvious spam, the expensive ML model is never invoked.
#4. Applied Domain: Customs Declaration Screening
Multi-layer customs screening for import declarations.
let customs = Axon::typed::<ImportDeclaration, String>("customs-screening")
.then(tariff_classification) // Classify goods by HS code
.then(restricted_goods_check) // Check against restricted list
.then(valuation_check) // Verify declared value
.then(origin_verification); // Country of origin rules#5. Combining with Outcome::Emit for Audit Trail
Each screen can emit an audit event while continuing the pipeline:
#[transition]
async fn pep_check(
mut applicant: CustomerApplication,
bus: &mut Bus,
) -> Outcome<CustomerApplication, String> {
let is_pep = check_pep_database(&applicant.name).await;
// Log the screen result to Bus for audit trail
bus.insert(ScreenResult {
screen: "pep",
passed: !is_pep,
timestamp: chrono::Utc::now(),
});
if is_pep {
Outcome::Fault("PEP check: flagged as politically exposed".into())
} else {
Outcome::Next(applicant)
}
}#6. Difference from Rule Chain
| Aspect | Cascade Screening | Rule Chain |
|---|---|---|
| Focus | Filter/reject | Evaluate/score |
| Rejection | Domain-specific logic | Generic threshold |
| Output | Pass/reject decision | Eligibility result |
| Ordering | Performance-driven | Logic-driven |
Both use the same Axon mechanism (Outcome::Next / Outcome::Fault), but
the intent is different. Screening emphasizes fail-fast filtering;
rule chains emphasize comprehensive evaluation.
#Quick Reference
Start Template: ranvier new my-app --template screening
Example: cargo run -p cascade-screening
Pattern Tag: screening#See Also
cascade-screeningexample โ Pure Axon screening democompliance-demoexample โ HTTP screening with Guardscookbook_saga_compensation.mdโ When screens trigger compensable actions