Skip to content

Repository files navigation

SaakhScore

Explainable MSME Financial Health Card for IDBI Innovate 2026 PS3. Saakh (साख) is a trader's earned creditworthiness — SaakhScore proves it for businesses the bureau can't see.

Live demo | Submission deck | Demo video | Animated walkthrough | Model card | Pilot runbook

tests Python FastAPI Model Status License

Built for IDBI Innovate 2026 - Problem Statement 3: Financial Health Score - Team Looper


Contents

Overview

SaakhScore turns consented alternate-data signals into a bank-reviewable credit decision for thin-file MSMEs. The public prototype uses a synthetic cohort and sandbox-ready API contracts; it does not claim private IDBI data access.

The core demo moment is a New-to-Credit case traditional underwriting rejects because there is no bureau file. SaakhScore approves the same business with a defensible Grade A health score, reason codes, Shapley attribution, policy guardrails, and an underwriter memo.

Case Traditional bureau-only SaakhScore alternate data
Shree Ganesh Textiles, no bureau file Rejected Approved - Grade A, Score 86/100
Indicative credit limit Rs 0 Rs 27,00,000
Explanation No credit bureau history Ranked reason codes, Shapley attribution, policy guardrails

Demo

What to verify in under three minutes:

  1. Open the live app and keep the default Shree Ganesh Textiles case selected.
  2. Compare Traditional bureau-only: Rejected with SaakhScore alternate data: Approved.
  3. In the review packet alongside, inspect the pillars, English/Hindi reason codes, the EMI limit-sizing ledger, model attribution, decision path, and policy guardrails.
  4. Still in Decision, run the sensitivity lab (up to three signals, one joint re-score), the three-scenario stress battery, and a side-by-side borrower comparison -- then click around the portfolio risk map under the impact strip.
  5. Switch to Model, Governance, and Proof to confirm the real-outcome benchmark, audit, validation, pilot gates, fairness, rubric, and competitor-gap proof -- then try the live underwriter console under Sources.

Backend Proof

The backend is not a mock response behind a polished screen. The judge can verify the product through live API surfaces:

Proof surface What it proves
GET /health/ready Release version, serving provider, runtime permission and verified artifact integrity used by container/Render readiness checks.
GET /submission/proof One payload summarizing the NTC reversal, truth boundary, backend capability map, judge runbook, rubric scorecard, competitor gap map, API catalog, validation metrics, controls, and Stage 2 swap points.
GET /msmes/ntc_hero/score Full decision packet: score, grade, limit, reason codes, exact Shapley attribution, memo, guardrails, source map, and decision path.
GET /model/evaluation Untouched proxy holdout AUC/Gini/KS/PR-AUC/Brier/ECE, bootstrap intervals, fairness slices, PSI, candidate comparison, and artifact hashes.
GET /model/sme-benchmark Real SBA small-business charge-off outcomes at natural base rates: v2 champion validated on a true later-in-time OOT window (114,770 loans) and a recession stress cohort (257,465 loans), plus the v1 case-sample baseline with its out-of-distribution test -- selective monotonicity, native exact TreeSHAP, per-artifact hashes, and committed honesty caveats.
POST /sandbox/score Underwriter-authenticated, purpose/scoped/expiry-checked AA/GST/UPI/EPFO/Bureau payloads normalize into the cockpit contract.
POST /sandbox/recalibration/report Underwriter-authenticated sandbox distribution, coverage, labels, and retraining readiness evidence.
GET /sandbox/outcome-contract Machine-readable dated 12-month outcome schema, maturity rule, chronological split policy, and privacy boundary.
POST /sandbox/pilot-readiness Underwriter-authenticated maturity, volume, temporal/OOT, source-coverage, NTC/NTB, and fairness-slice gates without record persistence.
GET /deployment/readiness Fail-closed model and infrastructure promotion gates for pilot/production mode.
POST /validation/report Underwriter-authenticated AUC, Gini, KS, PSI, and reason-code stability for caller-supplied dated cohorts.
GET /governance Audit count, model status, live controls, fairness slices, pilot KPIs, and deployment caveats are inspectable.

Quick backend checks:

curl https://id-ysm9.onrender.com/submission/proof
curl https://id-ysm9.onrender.com/health/ready
curl https://id-ysm9.onrender.com/msmes/ntc_hero/score
curl https://id-ysm9.onrender.com/governance
curl https://id-ysm9.onrender.com/deployment/readiness

Rubric coverage is implemented as backend data, not only README copy:

Judge lens Verifiable proof
Innovation NTC bureau rejection becomes an explainable alternate-data approval with memo, reasons, guardrails, and audit.
Feasibility One FastAPI service, zero-build static cockpit, non-root container, readiness probe, Render Blueprint, GitHub Actions, and no mandatory paid API dependency.
Scalability Separate ingestion, scoring, attribution, O(n log n) validation, audit, temporal readiness, bounded payloads, and fail-closed promotion gates.
Business impact Portfolio impact, NTC rescues, credit unlocked, pilot KPIs, early-risk guardrail, and diversification measures.
Technical implementation Calibrated monotonic XGBoost, native exact TreeSHAP, logistic fallback, score/PD/policy separation, scoped APIs, and artifact-backed evidence.
Governance readiness Honest random-holdout boundary, dated outcome contract, true-OOT readiness gates, model-disagreement review, pseudonymised audit, and fail-closed pilot promotion.

Features

  • Deep-linkable, keyboard-accessible two-rail underwriter workspace: decision stage beside a permanent review packet (Decision, Evidence, Model, Governance, Proof, Sources) with borrower queue, score, grade, risk band, credit-line recommendation, and decision comparison. Fonts are self-hosted; the app makes zero external requests.
  • In-product model evidence: the Model tab renders GET /model/sme-benchmark (v2 real-outcome splits with bootstrap intervals, DeLong-tested baselines, artifact integrity) plus the consumer-proxy evaluation with candidate comparison and outcome-linked fairness slices.
  • Live underwriter console under Sources: send a real editable payload to POST /sandbox/score with the documented demo key -- loading, 401, and validation errors render honestly; nothing is mocked.
  • Sensitivity, stress, and compare labs in the decision packet: move up to three whitelisted signals in one joint re-score (GET /msmes/{id}/whatif/multi -- interactions are real, not summed single-lever deltas); run a fixed three-scenario adverse stress battery with shocks clamped to the input schema (GET /msmes/{id}/stress); and put any two borrower files side by side, pillar by pillar. All are views over the identical live pipeline -- no audit events, no mocks.
  • Portfolio risk map: a clickable score-vs-PD scatter of the live cohort (bubble area = indicative limit) rendered from GET /portfolio, so concentration of risk is visible at a glance.
  • Five-pillar financial health card: Liquidity, Discipline, Momentum, Leverage, and Digital Footprint.
  • Calibrated monotonic XGBoost champion with native exact TreeSHAP, a calibrated logistic fallback, and an untouched 4,500-row public-proxy holdout -- not a regressor fit against a synthetic score. See MODEL_CARD.md.
  • Deterministic underwriter memo and borrower improvement plan; optional AWS Bedrock memo generation is a Stage 2 configuration path.
  • EWS-style monitoring signals (bank-recognisable categories for the same five pillars) and a deterministic, rule-based underwriter next-best-action recommendation, both derived from the already-computed score -- not generative output.
  • Underwriter/auditor role gates, source-scoped consent, strict app CSP, request IDs, body/array bounds, quota headers, and fsync-backed genesis-anchored pseudonymised audit events.
  • Sandbox-ready ingestion via POST /sandbox/score for AA/GST/UPI/EPFO/Bureau-style payloads, with enforced purpose/scope/expiry consent. A source the caller never connects always routes to mandatory review instead of being silently scored as worst-case, and a counterparty-concentration guardrail flags heavy single-buyer dependency.
  • GST-vs-bank turnover reconciliation: when both feeds are present, declared turnover is compared against bank-observed inflow; a divergence beyond +/-25% routes to review and becomes the underwriter's top next action -- the "looks-fine-on-paper" red flag, detected in both directions.
  • EMI-capacity indicative limit: the limit is sized from spare debt-service capacity (existing-debt service estimated, policy rate/tenor annuity) and only capped by the grade multiple, with the full limit_basis breakdown in every response -- not a bare score-times-constant number.
  • Favorable-only conduct prior: strong GST momentum and UPI footprint reduce the routed PD through a capped, disclosed expert prior (never inflating PD for thin digital visibility -- absence of signal is not evidence of risk); the coefficients become trainable the moment dated sandbox outcomes arrive.
  • Bilingual reason codes: borrower-facing reasons, improvement actions, and the underwriter next-best-action ship in English and Hindi -- and render in-product behind an English/हिन्दी toggle, in a committed Devanagari face.
  • Recalibration and monitoring APIs for holdout AUC/Gini/KS/PR-AUC/Brier/ECE, bootstrap intervals, PSI, reason stability, pilot targets, and proxy fairness slices -- see GET /model/evaluation.
  • Dated bad_12m outcome contract with 365-day maturity checks and automatic chronological development/calibration/OOT cohorts -- see GET /sandbox/outcome-contract and POST /sandbox/pilot-readiness.
  • Explicit public_demo, pilot, and production modes. Pilot/production startup fails closed until private credentials, IDBI-scoped artifacts, true OOT evidence, and durable audit storage pass -- see GET /deployment/readiness.

Architecture

SaakhScore architecture flow

Mermaid source (renders live on GitHub too; the image above is a committed fallback so the diagram never depends on a client-side renderer)
flowchart LR
  Reviewer["Judge / underwriter"] --> Cockpit["Deep-linkable credit cockpit"]
  Cockpit --> Guard["Request trace | CSP | limits | RBAC"]
  Guard --> Intake["Consent + AA/GST/UPI/EPFO normalisation"]
  Intake --> Score["Five-pillar health score"]
  Score --> Model["Calibrated monotonic XGBoost"]
  Model --> Explain["Exact TreeSHAP"]
  Explain --> Policy["Versioned lending policy"]
  Policy --> Memo["Memo + proposed limit"]
  Memo --> Audit["Genesis-anchored audit chain"]
  Model --> Monitor["Holdout + drift + fairness evidence"]
  Audit --> Gate["Fail-closed promotion gate"]
  Monitor --> Gate
  Outcomes["Dated IDBI outcomes - pending"] -.-> Temporal["365-day maturity + true OOT"]
  Temporal -.-> Gate
  Gate -->|"all pass"| Pilot["Approved pilot runtime"]
  Gate -->|"any block"| Refuse["Startup refused"]
Loading

Regenerate the image after editing the source: save the block above to a .mmd file and run mmdc -i file.mmd -o docs/diagrams/readme-architecture.svg.

Important endpoints:

Endpoint Purpose
GET /health/live, GET /health/ready Process liveness and release/model/artifact readiness
GET /msmes and GET /msmes/{id}/score Demo cohort and score packets
GET /submission/proof Judge-facing capability, architecture, rubric, runbook, competitor-gap, and truth-boundary proof
POST /score Underwriter-authenticated custom MSME scoring
POST /sandbox/score Normalize and score sandbox-style AA/GST/UPI/EPFO/Bureau payloads
POST /sandbox/recalibration/report Profile sandbox distributions and readiness for GBM/SHAP
GET /sandbox/outcome-contract, POST /sandbox/pilot-readiness Validate dated 12-month labels, maturity, chronological splits, NTC volume, and monitoring support
GET /deployment/readiness Show and enforce model/identity/OOT/audit promotion blockers
GET /portfolio, /governance, /pilot-metrics Portfolio impact and control evidence
GET /model/evaluation Champion/challenger selection, holdout metrics, uncertainty, fairness and artifact integrity
GET /validation/demo, POST /validation/report Explicit fixture contract and authenticated caller-supplied cohort validation
GET /audit-log, GET /model/status Auditor-gated pseudonymised trail and active champion metadata

Setup

cd backend
pip install -r requirements.txt
uvicorn main:app --reload

Open http://localhost:8000.

Demo-scoped credentials for protected write/audit routes (public by design for judging): saakhscore-demo-underwriter-key (underwriter role — scoring/sandbox/validation writes) and saakhscore-demo-auditor-key (auditor role — audit log). Real deployments override SAAKHSCORE_API_KEYS and SAAKHSCORE_AUDIT_HMAC_KEY (legacy UDYAMPULSE_* names are honored as a fallback).

Run tests:

python -m pytest backend -q

Container deploy:

docker build -t saakhscore .
docker run -d --name saakhscore -p 8000:8000 saakhscore
docker inspect --format='{{json .State.Health}}' saakhscore

The image runs as a non-root user and probes /health/ready. Dockerfile and render.yaml define the same single-service deployment used by Render.

Evidence

  • Test suite: 140 backend tests (167 total with the 9 frontend-unit and 18 Playwright e2e tests) covering scoring/policy routes, NTC reversal, model monotonicity, exact TreeSHAP reconstruction, runtime artifact hashes, honest holdout evidence, consent-at-decision scope, temporal leakage/maturity/split gates, production-scale validation, resource ceilings, request traces, fail-closed runtime modes, writable non-root audit persistence, genesis-anchored audit chaining, missing-source review routing, counterparty-concentration limit sizing, GST-vs-bank divergence detection, EMI-capacity limit sizing, favorable-only conduct-prior bounds, bilingual reason codes, v2 benchmark integrity and leakage exclusions, side-effect-free public reads, separated underwriter/auditor duties, chunked-body limits, doc-figure consistency, generative-memo fact-checking, OCEN offer determinism with recomputed EMI pricing, consent-contract self-validation against the enforcement model, bounded what-if hypotheticals, multi-lever sensitivity recomputed against direct pipeline runs, schema-clamped adverse stress batteries, governed screening routing, and API proof.
  • Model evidence: GET /model/evaluation reports random-holdout ROC-AUC 0.7497 (bootstrap 95% interval 0.7314-0.7678), Gini 0.4993, KS 0.4225, PR-AUC 0.4948, Brier 0.1415, and ECE 0.0122. It is reproducible with python backend/model_training/train_pd_model.py and explicitly not called OOT.
  • Real small-business outcome benchmark: GET /model/sme-benchmark serves the sba_sme_pd_v2 champion -- selected across 418,947 resolved real SBA 7(a) loans at natural base rates (197,716-loan train split) and validated on a true later-in-time out-of-time window (FY2017-19: 114,770 loans, ROC-AUC 0.9623, KS 0.82) and a recession stress cohort (257k loans, ROC-AUC 0.9255), with selective monotonicity, exact TreeSHAP, bootstrap intervals, and a pre-registered significance+materiality selection gate. The earlier case-sample benchmark stays committed as the baseline. Reproduce via backend/model_training/experiments/ + train_sme_pd_model_v2.py; the full experiment registry and analysis are in docs/research/BENCHMARK_REPORT.md. Real outcomes, real time axis -- still a US proxy domain, complementary to the alternate-data conduct pillars, and explicitly not an IDBI production calibration.
  • Public cohort impact: 2 NTC rescues and Rs 30,23,000 credit unlocked in the synthetic demo cohort (pilot targets, not measured lift -- these figures are computed by GET /portfolio, so the prose matches the live backend rather than drifting from it).
  • Governance evidence: policy guardrails with real consent-verification detail, source map, hash-chained audit count, real validation metrics, pilot KPI targets, and fairness slices are visible in the app.
  • Backend evidence: /submission/proof exposes the capability map, judge runbook, route catalog, rubric scorecard, competitor gap map, architecture flow, real held-out validation metrics, controls, and Stage 2 swap points directly from backend functions.
  • Security: custom/sandbox/validation writes require underwriter; /audit-log requires auditor; logs retain HMAC subject references rather than borrower names; CSP, CORS, consent, payload ceilings and rate budgets are enforced. See docs/SECURITY_COMPLIANCE.md and docs/THREAT_MODEL.md.
  • Promotion safety: the live public proxy is explicitly blocked from pilot use. SAAKHSCORE_MODE=pilot or production (legacy UDYAMPULSE_MODE) refuses startup until all machine-readable deployment gates pass.
  • Model transparency: MODEL_CARD.md documents the real training data/label, domain bridge, explainability, intended use and limitations. docs/ARCHITECTURE.md documents implementation boundaries; docs/PILOT_RUNBOOK.md defines promotion, sign-off and rollback.

Screenshots

SaakhScore two-rail workspace: decision stage with stamped approval card beside the open review packet
Two-rail workspace
One clear NTC rejection reversal beside a permanent review packet -- Decision, Evidence, Model, Governance, Proof, and Sources are always one click away, never hidden behind a modal.
Decision packet showing the five-pillar health ledger, bilingual reason codes, and EMI limit sizing
Decision packet
Five-pillar ledger, English/Hindi reason codes, underwriter next step, memo, and the full EMI limit-sizing breakdown.
Model evidence tab with the real-outcome benchmark, confidence intervals, and DeLong-tested baselines
Model evidence
The real-SBA v2 benchmark with bootstrap intervals, DeLong-tested baselines, artifact integrity, and outcome-linked fairness slices -- rendered from `GET /model/sme-benchmark`.
Governance packet with public proxy evidence and fail-closed pilot promotion status
Governance evidence
The public proxy boundary and blocking pilot gates are visible before any reviewer could mistake demo evidence for bank validation.
Proof tab showing truth boundary, rubric scorecard, judge runbook, and backend API catalog
Judge proof tab
Rubric scorecard, truth boundary, competitor gap map, runbook, and backend API catalog pulled from `/submission/proof`.
Mobile SaakhScore review flow
Mobile review
The packet stacks below the stage on a phone -- adapted, not amputated.

Full-resolution images remain in docs/deck/assets for detailed inspection.

Judging Proof

  • Track fit: IDBI's public MSME Inclusion track asks for a Financial Health Card using alternate data for faster credit decisions and finance access for underserved MSMEs.
  • Public event surface: the official public event venue found during review is IDBI Innovate 2026 on Hack2skill; no official IDBI Devpost page was found.
  • Sandbox interpretation: sandbox APIs and datasets are granted to shortlisted teams after the first round. This repo therefore ships synthetic proof plus a ready feed contract, dated outcome schema, automatic temporal/OOT readiness analysis, and fail-closed promotion controls without claiming early access.
  • Differentiation: many PS3 demos stop at a score; SaakhScore shows the bank decision pack around that score - rejection reversal, reasons, attribution, memo, source map, guardrails, audit, validation, pilot metrics, fairness checks, and a backend-verifiable judge proof endpoint.
  • Model roadmap (real-outcome benchmark + two-tower plan): docs/MSME_MODEL_ROADMAP.md
  • Submission checklist: docs/SUBMISSION_CHECKLIST.md

Limitations

  • Public data is synthetic and illustrative; it is not IDBI customer, sandbox, or repayment-outcome data.
  • The calibrated XGBoost champion is trained on a real default label from a public consumer-credit proxy, not Indian MSME outcomes. Its 4,500-row holdout is random and cross-sectional, not OOT; dated IDBI outcomes are still required.
  • Gender and age monitoring is real on the untouched proxy holdout, but is not a production fairness certification. NTC/NTB, sector, geography and vintage outcome slices remain unavailable pending sandbox data.
  • API authentication is a real, enforced bearer-token/role scheme sized for a public demo (no login flow or per-underwriter identity), not full IDBI SSO -- see docs/SECURITY_COMPLIANCE.md.
  • Pilot mode is intentionally not ready today: /deployment/readiness blocks it on public-proxy model scope, absent true OOT evidence, demo credentials/HMAC, and local JSONL audit storage.
  • AWS Bedrock memo generation is optional and requires configured credentials and a model ID; deterministic memo generation remains the default fallback.
  • SaakhScore is decision support for underwriters, not a fully automated approve/decline system without human review.

License

MIT - see LICENSE. The public synthetic cohort, model artifacts, and documentation in this repository are covered by the same terms; this does not extend to any IDBI, AA, GST, UPI, or EPFO data or credentials, which are never present in this codebase.

About

SaakhScore — explainable MSME Financial Health Card for IDBI Innovate 2026 (PS3). Live demo, 162 automated tests, PD model validated on real small-business outcomes with a true temporal holdout.

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages