argent-risk-engine
A pure-Python credit-underwriting policy core from a production fintech scoring service — loan-amount policy, score eligibility, and decile-direction-aware risk banding, zero I/O.
PythonCredit RiskDecision Engine
High-level design
Pure functions over plain dicts/lists: SMS-income waterfall, bureau servicing history, risk segmentation, and a FOIR cap combine into a pre-approved amount.
loan policy
income estimation waterfall → proven bureau amount → risk multiplier → FOIR 0.55 cap → 5k rounding
↓
eligibility
partner-facing /score fields (eligible / amount / rejection source + reason)
↓
risk banding
decile → low/medium/high with per-model decile-direction conventions
Low-level design
26 unit tests; the decile-direction gotcha is threaded through every comparison. Apache-2.0, CI on 3.10/3.11/3.12.
- –Ascending (1 = lowest risk) and descending (1 = highest risk) scorecards coexist in production; mixing them silently inverts the loan grid, so direction is declared per model and the multiplier is injected, never guessed
- –Approval keyed off a decile cut can decline a 'medium' user — so the rejection reason follows eligibility, not the risk band, or the partner gets a rejection with no attribution