Tier 1 · Financial Reporting

Banking CECL Allowance (ASC 326)

M-421 · lifecycle: development · RAT-421-v1.0.1 · conditionally-approved scaffold

Intended Use

Banking CECL Allowance (ASC 326) Compute the lifetime expected-credit-loss allowance for a bank loan book under ASC 326 (CECL), reconciled to the bank's disclosed allowance.

BUILT (1L, Decision 060 Phase 2c) — under_development pending 2L effective-challenge sign-off. Real ASC-326 segment-aggregate lifetime-ECL engine (banklib.L3.cecl_allowance in the bankview repo, the banking analogue of finlib): ACL = Σ_segment EAD·PD_lifetime·LGD·Q, with a lifetime survival PD (reusing finlib.cecl's hazard-survival framing at the loan- segment level) and a qualitative/macro overlay Q. The overlay is CALIBRATED so modelled ACL reconciles to the disclosed loan-loss allowance from each bank's FY2025 10-K (JPM/BAC/WFC + the other GSIBs with a disclosed anchor). Replaces the M-420 scaffold's single-point PD×LGD provision term. The segment PD/LGD/EAD decomposition is a modelled prior (not in XBRL) — flagged not-sourced; the disclosed ACL anchor and citations are in banklib/disclosed_anchors.yaml. Reconciliation evidence: validation_evidence/M-421/RECONCILIATION.md (modelled vs disclosed ACL, implied Q overlay, per-segment coverage). Status stays under_development until 2L ratifies (Decision 052/053).


Components

Inputs, processing, outputs

engines
banklib.L3.cecl_allowance
dimensions
D3

Methodology & Mechanics

Methodology

Segment-aggregate lifetime ECL:

ACL = Σ_segment  EAD_s · PD_lifetime,s · LGD_s · Q
  • EAD_s — segment exposure = sourced total net loans × segment share.
  • PD_lifetime,s — lifetime cumulative PD from a marginal 1-yr PD compounded over the segment's expected life via a discrete survival curve (1 − (1 − pd)^life) — the loan-segment analogue of finlib.cecl's hazard-survival bond ECL (REUSE, not re-derive).
  • LGD_s — segment loss-given-default (1 − recovery).
  • Q — a single per-firm qualitative/macro (reasonable-and-supportable) overlay, calibrated so modelled ACL reconciles to the disclosed ACL balance. The reported Q is the implied overlay (a real CECL-model output); an implausible Q (≫1 or ≪1) is flagged as a mis-scaled raw loss prior.

Model Documentation

What is sourced vs flagged

  • Sourced: total net loans (investorMgmt content store via the bankview adapter); the disclosed loan-loss allowance anchor (FY2025 10-Ks, with per-figure citations in banklib/disclosed_anchors.yaml).
  • Modelled & flagged (segments_sourced=False): the loan-segment PD/LGD/EAD decomposition — loan-class mix and through-the-cycle PD/LGD are not in XBRL (MD&A narrative). Decomposes a sourced total; never a disclosed segment balance presented as filed. Where no disclosed ACL anchor exists for a firm, the raw modelled ACL is returned calibrated=False and flagged (honest partial).
  • Validated against disclosed segments (C-421-03): the disclosed ACL-by-segment (10-K credit-quality footnote — free public, cited in disclosed_anchors.yaml) is the back-test anchor for the split. The modelled vs disclosed share-of-ACL per disclosed segment is reported per firm; a max share error >15pp is flagged as material mis-allocation for that firm's book.

Validation Evidence

Validation Evidence

bankview/validation_evidence/M-421/ — per-firm modelled-vs-disclosed ACL reconciliation (RECONCILIATION.md, reconciliation.json). Reconciles exactly to the disclosed loan-loss allowance for JPM/BAC/WFC/USB/COF (Citi sourced-but- not-consumable); the cross-firm signal is the implied Q-overlay spread (BAC 0.41 → COF 1.95). Segment-decomposition validation (C-421-03): the same evidence file now carries the modelled-vs-disclosed ACL-by-segment share per firm (BAC 0.7pp, JPM 18.9pp, WFC 16.2pp, COF 44.3pp max share error; USB not broken out). Unit tests: tests/test_banklib_cecl.py (incl. segment-validation cases).


Change Log

Change Log

  • 2026-06-28 — Created as a planned backlog stub (Decision 060 / insightalm #3389).
  • 2026-06-28 — 1L build (insightalm #3412): real ASC-326 lifetime-ECL engine (banklib.L3.cecl_allowance), calibrated to disclosed ACL for JPM/BAC/WFC; validation evidence + engine_registry binding added. Status → under_development. Ready for 2L re-review.
  • 2026-06-28 — 2L verdict (RAT-421-v1.0.0): CONDITIONALLY APPROVED. Registry lifecycle.ratification_ref set to RAT-421-v1.0.0 via the reconciler promote channel. Status held at under_development (not promoted to active) pending the open condition: per-segment ECL decomposition independently validated against disclosed segment-level ACLs.
  • 2026-06-29 — 1L: condition C-421-03 addressed (issue #3430). Added validate_segment_decomposition to banklib.cecl_allowance: the modelled segment split is back-tested against the disclosed ACL-by-segment (free public 10-K credit-quality footnotes, Decision 062) for the GSIB cohort (JPM/BAC/WFC/USB/COF; Citi sourced-but-not-consumable). Surfaced in the operator
  • validation_evidence/M-421. Honest finding: validates for diversified books (BAC 0.7pp) but materially mis-allocates for concentrated books (COF card monoline 44pp) — firm-level allowance stays the validated booked number, segment-level stays decision-support with per-firm Δshare flagged. New unit tests. Ready for 2L re-review.

2L Inventory Review

Open findings (1)

Independent 2nd-line review (INV-2026-06) — implemented capability vs registered scope. Each carries a recommended fix and is tracked in insightalm-mrm until closed.

HIGH INV-029 · P5 · validation-gap

Validation evidence + change logs missing across most of the inventory

Only M-001/M-020/M-050 carried full documentation packs before this pass. Most models record validation_evidence: missing and change_log: missing with peer_review: pending. Gold tests freeze behaviour but many assert only structural invariants (e.g. reserve>0), not correctness against external truth. The flagship T0-vs-10-K match is circular (BV-032).

Recommendation: For each Tier-1 model: produce a validation-evidence pack (back-test vs disclosed results once BV-032 re-calibration lands, sensitivity suite, challenger comparison), a change log, and a 2L ratification. Sequence behind BV-032 (firm-data) for anything needing 10-K reconciliation.


Validation Coverage

Per-tier expectations

Per MRM Framework §10.2 + §10.3, this model's regulatory_frameworks tag list activates the following overlays:

asc_326 sr_26_2 internal
component tier-1 expectation status
Registry entry required present
Model card (§10.5 doc pack) required present
Validation evidence required present
Change log required present
Independent effective challenge (2L) required n/a

Ratification

Conditionally-approved scaffold — RAT-421-v1.0.1

2L issued RAT-421-v1.0.1 as a conditionally-approved Tier 3 analytic scaffold. The model exists, runs, and matches its card — but its approval is intelligence-use-only: its outputs must never be read as a booked, regulatory, capital, or reserving figure. Booked use (and tier promotion) is gated on the PLANNED engines, which are not built. The conditions below are on record.

id deadline condition
C-421-01
C-421-02
C-421-03
C-421-04 2026-09-28 SEGMENT-LEVEL USE STAYS DECISION-SUPPORT ONLY (firm-level + implied-Q approved in-scope). The segment-decomposition validation (C-421-03) was performed and is NEGATIVE for concentrated books: of 4 testable GSIBs only the diversified BAC passes (0.7pp), while COF (44.3pp), JPM (18.9pp) and WFC (16.2pp) breach the 15pp materiality flag, and USB/Citi are untestable. For a Tier-1 financial- reporting model, per-segment ECL / segment coverage bps therefore CANNOT be read as booked numbers. To clear toward `approved`: recalibrate the DEFAULT_SEGMENTS PD/LGD/EAD priors (or add a per-firm book-mix prior, e.g. a monoline/card-concentration adjustment) so the modelled segment shares reconcile to the disclosed ACL-by-segment within a STATED tolerance for the concentrated archetypes, AND extend coverage to USB/Citi as their free-public segment disclosures / loan bases become consumable (D062). Until then M-421 is approved for the FIRM-LEVEL allowance + the cross-firm implied- Q signal ONLY, segment outputs stay flagged decision-support, and the model stays under_development.