Skip to content

13.6 Underwriting

Build the decision-making core of the platform: a versioned, auditable, configurable engine that combines rule-based eligibility and scorecard-based grading into a sanction proposal — with a manual review path for refers and a deviation workflow for exceptions.

The engine is the platform’s competitive moat. It must be fast (sub-minute for auto-decisions), transparent (every decision traceable to specific rules), flexible (rules editable without engineering deploy), and safe (champion-challenger before broad rollout).

  1. As a credit head, I want to author and edit rules in an admin UI without engineering involvement, then test against historical applications before deploying.
  2. As an analyst, I want to see a single case view with all scorecard outputs, all rule traces, all documents, the BO graph, and the recommended sanction terms — everything in one screen.
  3. As a borrower, I want a fast yes (within minutes) or a clear no (with a reason I can act on).
  4. As a CRO, I want to approve / reject deviations per the delegation matrix without surfacing them through engineering.
  5. As a system, I want every decision to record the exact policy version that ran, the inputs at decision time, every rule’s outcome, and the final recommendation — for audit, for borrower explainability, and for model improvement.
  6. As a credit head, I want to test a new policy version in shadow mode for 3 months before deciding whether to promote it to production.
  7. As an analyst, I want segment-specific rule sets (pharma, FMCG, services, e-commerce, manufacturing) to layer on top of base rules automatically based on the borrower’s NIC code.
  8. As a co-lending operator, I want every co-lent application to run through both the originator’s policy and the partner’s policy in parallel and get a combined outcome.
  9. As an analyst handling a refer case, I want to query the borrower or DSA, capture their response, and re-run the decision with new data without losing the audit trail.
  10. As a compliance officer, I want decline reasons to come from a controlled vocabulary so that pattern analysis across declines is meaningful.
  11. As a CRO, I want a dashboard of deviation rate per channel, per analyst, per product — to spot drift toward looser standards under sales pressure.
  12. As a borrower, I want my decline letter in vernacular language with a clear reason and a guidance on how / when to re-apply.
  13. As a data scientist, I want every decision_run’s input snapshot accessible as training data for the next scorecard iteration.
  14. As an internal auditor, I want for any past loan to reconstruct the exact decision logic that produced the sanction — which policy version, which rules fired, which scorecards graded, which deviations were approved.
  15. As a senior credit analyst, I want to escalate a complex case to the credit committee with a structured risk memo generated automatically.
  • POST /v1/decisions/run — execute decision against an application. Body: { application_id, policy_id? }. Returns { decision_run_id, decision, grade, recommended } (sync) or { decision_run_id, status: "in_progress" } (async for complex models).
  • GET /v1/decisions/{id} — full decision with trace, scorecards, recommendation.
  • GET /v1/decisions/{id}/trace — rule-by-rule trace JSON.
  • POST /v1/decisions/{id}/re-run — re-run with refreshed data.
  • POST /v1/policies — create new policy version. Body: rule set + metadata.
  • GET /v1/policies?product={p}&partner={p} — list policies.
  • GET /v1/policies/{id} — retrieve.
  • POST /v1/policies/{id}/activate — activate (effective date).
  • POST /v1/policies/{id}/sandbox-test — test against historical applications. Body: { test_set_id }. Returns { test_run_id }.
  • GET /v1/policies/{id}/sandbox-results/{test_run_id} — results.
  • POST /v1/policies/{id}/champion-challenger — start champion-challenger run.
  • POST /v1/decisions/{id}/deviation — request deviation. Body: { reason, requested_overrides_json }.
  • GET /v1/deviations?status=pending — pending deviation queue.
  • POST /v1/deviations/{id}/approve — approve. Body: { approver_id, conditions? }.
  • POST /v1/deviations/{id}/decline — decline. Body: { reason }.
  • GET /v1/cases?queue={q}&assigned_to=me — analyst’s queue.
  • POST /v1/cases/{id}/assign — claim.
  • POST /v1/cases/{id}/notes — add note.
  • POST /v1/cases/{id}/queries — raise borrower / DSA query.
  • POST /v1/cases/{id}/recommend — analyst’s recommendation.
  • POST /v1/cases/{id}/approve — checker approval.
  • POST /v1/cases/{id}/decline — analyst / checker decline.
  • GET /v1/cases/{id}/audit-log — full action history.
  • GET /v1/decisions/{id}/sanction-proposal — recommended terms (amount, tenure, rate, fees, conditions).
  • POST /v1/decisions/{id}/sanction-proposal/override — analyst override with deviation.
  • GET /v1/pricing/grids/current — current pricing grid.
  • POST /v1/admin/pricing/grids — update grid (versioned).
  • GET /v1/exposure/borrower/{id} — current exposure.
  • GET /v1/exposure/group/{id} — current group exposure.
  • policy, decision_run, deviation, case, case_query, case_note, risk_memo, sanction_proposal.
  • pricing_grid, tenure_grid, exposure_snapshot.

See 5.3 Core data model and 5.9 Schema reference.

  • Queue view — assigned cases with priority, SLA timer, value.
  • Case view — single screen with: application detail, data room, all scorecards with breakdown, full rule trace, BO graph, documents, history of borrower’s interaction with platform.
  • Query interface — raise structured queries to borrower / DSA; track responses.
  • Recommendation form — analyst captures recommendation, deviation request if needed, conditions.
  • Approval queue — deviations + non-auto approvals.
  • Side-by-side — engine recommendation vs analyst recommendation + deviation reason.
  • Approval action with reason capture.
  • Committee agenda — cases queued for committee.
  • Risk memo viewer — structured PDF generated from case.
  • Committee minutes capture.
  • Policy editor with sandbox.
  • Champion-challenger dashboard.
  • Deviation analytics — rate by channel, analyst, product, over time.
  • Decision-engine performance dashboard — approval rate, decline reasons, refer rate.
  • Status screen showing application progress.
  • Decision communication — vernacular language, clear reason on decline.
  • Decision engine — runs rules + scorecards; produces decision.
  • Policy management service — versioned storage; sandbox harness.
  • Manual review service — case routing, assignment, notes, queries.
  • Deviation workflow service — runs via workflow engine.
  • Sanction proposal service — combines decision + grids into proposal.
  • Risk memo generator — structured PDF from case data.
  • Read from data ingestion module (bureau, BSA, GST, Tally, MCA, AA outputs).
  • Read from KYC / KYB module (verified status).
  • Write to documentation module (sanction proposal triggers KFS) and to LMS (sanction triggers loan account).
  • Auto-decision returns APPROVE for clean A-grade borrower in < 60 seconds.
  • Auto-decision returns DECLINE with controlled reason code for ineligible.
  • REFER case routes to analyst queue with full data context.
  • Deviation routes per matrix to correct approver.
  • Champion-challenger comparison generates daily metrics.
  • Sandbox test runs against 1000 historical applications in < 5 minutes.
  • New data arrives mid-decision → re-run after data settles.
  • Conflicting rules (one passes, one fails) → precedence applied per policy.
  • Policy bug declines genuine borrowers → sandbox catches before production.
  • Co-lending dual policy → one passes, one declines → outcome per policy.
  • Repeat borrower with new product → both repeat rules and product-specific rules apply.
  • Engine timeout (> 60 seconds) → graceful failure; case routes to manual.
  • Every decision records exact policy version, inputs, rule trace.
  • Decline reasons from controlled vocabulary.
  • Decline letter generated in borrower’s chosen language.
  • Deviation approval matrix enforced — no out-of-matrix approval.
  • Audit trail captures every state change.
  • Borrower with multiple loan products in pipeline (one approved, one in process) — exposure check considers in-process.
  • Borrower applies, declined, re-applies after 6 months — separate decision but historical context available.
  • Group borrower’s group exposure changes mid-decision due to a parallel application — refresh exposure at sanction.
  • Co-lending partner adds a new restriction post-sanction — affects only new applications, not the in-flight one.
  • Champion-challenger results materially diverge mid-run — alert risk team.
  • Rule version updated between application start and submit — application uses the version at start time.
  • BO graph incomplete at decision but completed before sanction — block sanction, allow decision.
  • Manual review SLA breached — auto-escalate.
  • Auto-decision in < 60 seconds for full-auto path; < 5 days p95 for manual.
  • Every decision auditable end-to-end with policy version, inputs, trace.
  • Policy editable by non-engineers; sandbox testable.
  • Deviation rate trackable per channel / analyst / product.
  • Decline letter in chosen language with clear reason.
  • Champion-challenger framework operational by Phase 4.
  • Segment overlay applied automatically based on NIC code.
  • Co-lending dual-policy execution operational.
  • Digital Lending Guidelines — credit decision must be the RE’s (not LSP’s alone); recorded.
  • Fair Practices Code — decline reason in writing, vernacular.
  • DPDP — only consented data feeds decisioning.
  • CICRA — bureau pull recorded with enquiry submission.
  • Co-Lending guidelines — both lenders’ policies executed.