Tier 1 · Gaap Ifrs Financial Reporting

LDTI / ASC 944 GAAP Reserves

M-020 · lifecycle: monitoring · RAT-020-v1.0.0

Intended Use

LDTI / ASC 944 GAAP Reserves Compute GAAP reserves and DAC under ASC 944 / LDTI (Long-Duration Targeted Improvements).

LDTI net premium reserve, market-risk-benefit (MRB) fair value, deferred profit liability, and DAC amortization. Quarterly remeasurement with NPR / true-up cycle. MRB fair-value change is split per ASC 820 between OCI (the instrument-specific own-credit / NPR component) and net income (all other changes); the OCI leg is a documented deferred refinement pending FinView credit-spread integration (card limitation #2). AF-01 audit gap acknowledged: experience data plumbing for remeasurement is unbuilt; consumer documentation states this limitation per Decision 020 §AP-19.


Components

Inputs, processing, outputs

data sources
DS-001 · DS-008
assumptions
A-001, A-002, A-010, A-070, A-071, A-072
engines
insmodel.L4.reserve_engine_ldti
insmodel.L4.reserve_engine_gaap
insmodel.L4.dac_engine
insmodel.L4.dac_projection
insmodel.L4.mortality_engine
insmodel.L4.lapse_engine
insmodel.L4.expense_engine
insmodel.L6.multi_basis_orchestrator
contracts
gaap_reserves_v1
upstream
M-120
dimensions
D6

Methodology & Mechanics

Methodology

M-020 implements ASC 944 with the FASB Long-Duration Targeted Improvements (LDTI) update for non-participating traditional and limited-pay long-duration insurance contracts. The model produces, per cohort (issue-year × product-type grouping), four GAAP financial-statement quantities:

  1. Net Premium Reserve (NPR) — present value of future benefits less present value of future net premiums, discounted at the upper-medium grade fixed-income rate (single-A spot curve) locked at the cohort's issue date for OCI tracking. Computed by insmodel.L4.reserve_engine_ldti consuming mortality_engine, lapse_engine, and expense_engine outputs.
  2. Reserve remeasurement — at each reporting period, cash flow assumptions are updated based on actual-to-expected experience (the "true-up cycle"). The remeasurement catch-up adjustment flows to net income for cash flow assumption updates and to OCI for discount rate updates; this split is one of the central mechanics LDTI introduced.
  3. Contractual Service Margin (CSM) roll-forward — implemented by the GAAP engine (insmodel.L4.reserve_engine_gaap, GAAPReserveEngine). At inception, initial_csm = max(0, EPV(premiums) − EPV(benefits)) (the unearned profit margin); if benefits exceed premiums, a loss_component is recognized immediately. Each period the CSM accretes interest at the locked-in rate, absorbs adverse experience variances, and amortizes via the coverage-units method (csm_amortization = csm_balance / remaining_coverage_units — straight-line over remaining coverage). When adverse movements would drive the CSM negative, it is floored at 0 and the excess flows to the loss component (_roll_forward_csm / _amortize_csm). This CSM mechanic is the core of the GAAP engine path the Output Snapshot exercises.
  4. Deferred Acquisition Costs (DAC) amortization — amortized on a constant-level basis over the cohort's expected coverage period (insurance in-force, simplified to straight-line for many product classes), computed by dac_engine / dac_projection. LDTI removed the pre-LDTI gross-profits-based amortization model.
  5. Deferred Profit Liability (DPL) — for limited-pay contracts, the unearned profit at issue is held as a liability and recognized over the coverage period. DPL is computed by the LDTI reserve engine (insmodel.L4.reserve_engine_ldti, reserve_engine.py) via _calculate_dpl (a simplified margin: benefit_reserve_current × (1 − net_premium_ratio) × dpl_margin_factor, floored at 0), distinct from the CSM roll-forward in the GAAP engine.

The insmodel.L6.multi_basis_orchestrator composes these engines per cohort, runs both the GAAP-NPR and (separately) the statutory VM-20 reserves (M-001), and emits cohort-level results via the gaap_reserves_v1 contract. Cohort grouping is capped: NPR cohorts cannot offset losses on one issue year against gains on another, so the cohort definition (issue-year × product-class) is structurally narrower than statutory VM-20's life-only segmentation.

Market Risk Benefits (MRBs) are NOT YET MODELLED in M-020. Under LDTI, separate-account guarantees (e.g., GMxB on variable annuities) receive fair-value measurement, with the fair-value change split between OCI (instrument-specific credit risk) and net income (all other changes). No MRB / fair-value / own-credit code exists in any M-020 engine (gaap_reserve_engine.py, reserve_engine.py, multi_basis_orchestrator.py) — the only GMxB-related code in the InsModel stack lives in c3_phase2_engine.py, which backs C-3 / VM-21 capital (M-002), not M-020. MRB fair-value measurement and the ASC 820 own-credit OCI split are therefore out of scope / pending for M-020 (see Limitations); they are not implemented and produce no M-020 outputs today.


Key Assumptions

Key Assumptions and Their Justification

The six formally-bound A-NNN entries plus operational choices:

ID Name Value Derivation Justification for LDTI
A-001 Base mortality table 2017 CSO Loaded (Male/Female) published_source Same base table as VM-20; LDTI is silent on mortality basis selection, so the regulatory-minimum 2017 CSO is used as the conservative baseline. Cohort experience overlays this base at remeasurement.
A-002 Mortality improvement scale MP-2021 (SOA) published_source Latest SOA-published improvement scale at the as-of date; applied to CSO base. Updated annually with each SOA scale release.
A-010 Base lapse curve (spread liability) Duration-graded: 15% Y1 → 5% Y10+ data_calibrated Calibrated against 5-year industry experience for MYGA/SPDA-type products. LDTI lapse-rate updates flow through the remeasurement true-up cycle.
A-070 Per-policy maintenance expense $75–150/policy/year (product-dep) data_calibrated Range based on industry FY2024 expense studies; product-specific values selected at cohort issue. Expense assumption updates trigger reserve remeasurement.
A-071 Expense inflation rate 2.5% p.a. published_source Long-run CPI proxy; aligns with Decision 020 / DS-062 effective-date catalog.
A-072 Commission first-year rate 5–8% of premium (product-dependent) published_source Used in DAC capitalization. First-year commission is a DAC-eligible cost; level commission (years 2+) is expensed.

Operational assumptions beyond the formal IDs: - Discount rate: upper-medium grade (single-A) spot curve from DS-001 (canonical market data). Locked at issue for OCI tracking; current at each remeasurement for the net-income split. - Cohort grouping: issue-year × product-class. Cohort definitions cannot be re-cut mid-life. Conservative grouping (narrower cohorts) is acceptable under LDTI; broader grouping that produces offsetting effects is not. - DAC amortization basis: constant-level over expected coverage period. Coverage period proxied by 80% in-force duration for most product classes; explicit projection for limited-pay. - MRB measurement: not modelled in M-020 — there is no MRB fair-value code in any M-020 engine. Separate-account guarantee capital is handled by M-002 (VM-21, c3_phase2_engine.py); the GAAP MRB fair-value measurement and the ASC 820 own-credit OCI split are out of scope / pending here (see Limitations). - Experience-adjustment inputs: actual_deaths, actual_lapses, actual_expenses (optional cohort inputs), expense_ae_factor, and the SOA A/E integration (soa_ae_experience_enabled_apply_soa_ae_adjustment / soa_experience_config). These mechanics exist in GAAPReserveEngine but default to expected experience when no actual feeds are supplied (see Limitations #1).


Output Snapshot

Output Snapshot

Deterministic single-cohort run of GAAPReserveEngine — reproducible, no live firm data (python scripts/model_snapshots.py M-020 in InsModel; asserted by tests/mrm/test_gold_tier0.py::TestGoldGAAPReserve).

Version-label convention: the snapshot header reads "GAAPReserveEngine v2.0.0", which is the InsModel release tag used uniformly across snapshot headers (the same convention M-001 uses for VM20ReserveEngine v2.0.0). It is not the class version attribute, which is version = "1.0.0" on GAAPReserveEngine in gaap_reserve_engine.py. The change-log / limitations below refer to the v1.0.0 class baseline. No output numbers change with this clarification; the snapshot script is deterministic with fixed params and reproduces the card values.

Input: 1,000-policy cohort · face $100K · locked-in rate 4.0% · current rate 4.5% · mortality 0.5%/yr · lapse 3.0%/yr · premium $2,000/policy · 20-yr coverage · period 1

output value meaning
beginning_reserve 0.00 new cohort — no opening liability
npr (net premium ratio) 0.2500 EPV benefits ÷ EPV premiums, locked at issue (ASC 944-40)
ending_reserve 1,019,274.48 period-1 liability for future policy benefits (LFPB)
aoci_impact −45,399.71 current-rate (4.5%) remeasurement vs locked (4.0%) → lower reserve → negative OCI

The net premium ratio (0.25) is the LDTI engine's core mechanic: benefits are funded as a constant fraction of premiums, locked at issue and unlocked only on assumption review. The AOCI impact isolates LDTI's distinctive current-rate remeasurement — discounting the same benefit cash flows at the higher current rate (4.5% vs the locked 4.0%) lowers the liability, booking a negative adjustment to other comprehensive income while net income continues to run on the locked rate. That split is the LDTI signal this engine is built to reproduce.

Captured 2026-06-04 · deterministic, no live data.


Limitations

Limitations and Known Gaps

  1. Experience-adjustment mechanics exist but are inert without actual feeds (AF-01). The remeasurement true-up requires actual-vs-expected mortality, lapse, and expense data. The plumbing is built in GAAPReserveEngine: optional cohort inputs actual_deaths / actual_lapses / actual_expenses, the expense_ae_factor parameter, and SOA A/E integration (soa_ae_experience_enabled_apply_soa_ae_adjustment / soa_experience_config); the engine's change_history records v1.2.0 "Added expense_ae_factor for non-zero expense experience adjustments (AF-01 closure)". The remaining gap: when no actual experience feed is supplied, the engine falls back to expected experience (placeholders/defaults), so the experience-adjustment term is zero/neutral and remeasurement does not reflect realized mortality/lapse/expense. Wiring live actual-vs-expected feeds into the true-up is the substantive AF-01 closure and remains tracked — see insightalm/governance/audit_log.yaml::AF-01. Ratification does NOT close AF-01.
  2. MRB (Market Risk Benefit) fair-value measurement is NOT YET MODELLED — out of scope / pending. Under ASC 944-40 / ASC 820, a Market Risk Benefit (separate-account guarantee such as GMxB) is measured at fair value, and its period change is split between OCI (the instrument-specific own-credit component) and net income (all other changes). No MRB code exists in any M-020 enginegrep for mrb / market_risk_benefit / fair_value across gaap_reserve_engine.py, reserve_engine.py, and multi_basis_orchestrator.py returns nothing. The only GMxB code in the InsModel stack is in c3_phase2_engine.py, which backs C-3 / VM-21 capital (M-002), not the M-020 GAAP reserve path. Both the MRB fair-value base mechanic and the own-credit OCI-vs-net-income split are therefore unbuilt; M-020 produces no MRB output today. Implementing MRB fair value and the ASC 820 own-credit OCI split is an output-changing enhancement tracked for ratification (see note at end of this section), not a built-but-deferred-leg.
  3. Cohort grouping is product-class-coarse. Issue-year × product-class cohorts may be narrower than competitor groupings (some insurers group by issue-year + product-class + rider). Narrower cohorts produce more conservative reserves (less offsetting); ASC 944 permits this. Documented for transparency.
  4. No reinsurance ceded mechanics yet. Cohort-level reserves are gross of reinsurance. Ceded reserves require a separate cohort and offsetting cash flows; deferred until reinsurance modeling is brought into the InsModel stack.
  5. DAC for limited-pay contracts uses straight-line proxy. ASC 944 permits a more granular schedule based on the in-force pattern; the straight-line approximation is a v1.0.0 simplification. Refinement is tracked as a Phase 2 enhancement.
  6. DPL release schedule shares the NPR mortality assumption. A separate DPL-specific mortality assumption (e.g., for products with substantively different mortality experience) would require an A-NNN extension. None currently warranted.
  7. CSM amortization uses straight-line coverage units. The GAAP engine amortizes the CSM via csm_balance / remaining_coverage_units (per the engine change_history note "CSM amortization uses straight-line coverage units, not a more complex pattern"). A more granular coverage-unit pattern (e.g., discounted or in-force-weighted units) is a possible future refinement.
  8. Remeasurement uses a mid-point-duration discount approximation. The current-rate remeasurement (_remeasure_at_current_rate) approximates with ((1+locked)/(1+current))^(remaining/2) rather than a full cash-flow re-projection at the current curve — tracked for ratification (see note below).

Output-changing enhancements tracked for ratification (not applied in this documentation pass): - Implement MRB fair-value measurement and the ASC 820 own-credit OCI-vs-net-income split in the M-020 engine path (today no MRB code exists; building it produces new model outputs). - Wire live actual-vs-expected experience feeds into the remeasurement true-up (the substantive AF-01 closure) so remeasurement reflects realized mortality/lapse/expense rather than expected fallbacks. - Produce real Tier-1 validation evidence required by INV-029 (back-test vs disclosed/filed results, sensitivity suite, challenger comparison) for M-020. - Improve the remeasurement method beyond the mid-point-duration approximation to a full cash-flow re-projection at the current curve.


Validation Evidence

Validation Packet

Reserve identity (mechanically enforced in reserve_engine_ldti): for each cohort, NPR(t) = PV(future benefits at t) − PV(future net premiums at t) where the discount curve is the cohort's locked single-A spot curve.

Cohort-level loss-recognition test: an additional check ensures reserves never go negative at the cohort level (a hallmark of LDTI rigor). Tested in test_ldti_cohort_invariants.py::TestNonNegativeReserve.

Track C cross-check (Gold Copy validation, per crosscheck_pricing_v1 contract): InsModel's LDTI cohort reserves are compared against goldcopy.L7.cross_check for 4 representative LDTI archetypes (term-15y, term-20y, whole-life, limited-pay-20yr); tolerance ±2% on PV-reserved, ±$1k/policy on NPR.

Gold test suite (Models/tests/test_engine_golden_cases.py): frozen reserve values for representative LDTI policy archetypes; CI-gated regression — any reserve drift outside tolerance breaks the build.

Sensitivity packet (intended to close COND-001 in RAT-020-v1.0.0): canonical index at validation_evidence/M-020/v1.0.0/README.md (present in the evidence tree) is intended to map each §10.5 item-5 sub-requirement to specific InsModel test files. Link-integrity / completeness of the referenced sensitivity, Track C cross-check, and gold suites should be confirmed against the actual evidence tree and InsModel test files before relying on them for sign-off — this card's documentation pass verified the README is present but did not re-run or re-confirm each referenced artifact.

INV-029 Tier-1 evidence (pending). Full Tier-1 validation under INV-029 — back-test vs disclosed/filed results, a complete sensitivity suite, and a challenger comparison — is pending. Producing this evidence is an output/work item tracked for ratification (see Limitations note); it is not represented as complete here.

Peer-review (AP-26 / ASC 944): under Decision 028, peer-review attestation moved from 1L to 2L. The 2L technical ratification is vsdhaka/insightalm-mrm:ratifications/RAT-020-v1.0.0.yaml (decision: approved, expires 2027-05-25).

Model-vs-reality back-testing (SR 26-2 ongoing; canonical record backtest_results.yaml): under Decision 048 (A4-30) the aggregate reserve is reconciled to filed reserves through the firm-calibrated book — each firm's canonical segment-reserve decomposition (DS-073), not a notional cohort. Record BT-012 (status: covered): the reserve aggregate reconciles to reported policy reserves by reportable segment for the segment-grade cohort, superseding the earlier Mock-notional 0% (BT-011). Predictive record BT-013: at quarterly cadence a reserve roll-forward is benchmarked against naive persistence — persistence is a tight ~3.4% q/q baseline that a structural roll-forward beats only where segment flows are cleanest; the data needed to beat it robustly (segment-level flows / disclosed θ sensitivities) is named, not assumed.


References

References

Accounting / regulatory: - FASB ASC 944 — Financial Services—Insurance. - FASB ASU 2018-12 — Targeted Improvements to the Accounting for Long-Duration Contracts (LDTI). - FASB ASC 820 — Fair Value Measurement (for MRB and instrument-specific-credit-risk split). - Federal Reserve SR 26-2 (April 2026, supersedes SR 11-7) — Model risk management for banks (applicable to InsightALM platform consumers via Decision 018 MRM Framework). - PCAOB AS 2501 — Auditing Accounting Estimates.

Actuarial standards: - ASOP No. 25 — Credibility Procedures (basis for experience factor application). - ASOP No. 56 — Modeling (cross-cutting modeling standard).

Source data: - 2017 Commissioners Standard Ordinary (CSO) Mortality Tables — NAIC, loaded composite. - Society of Actuaries (SOA) Mortality Improvement Scale MP-2021.

Internal: - Decision 018 (MRM Framework) — Management/decisions/018-mrm-framework-multi-regime.md. - Decision 019 (Data Policy) — for the AF-01 experience-data plumbing gap. - Decision 020 (Assumption Policy v1.2) — insightalm/modelling/charters/assumption_policy.md. - Decision 023 (Policy-Based Binding Architecture) — Management/decisions/023-policy-based-binding-architecture.md. - Decision 028 (Independent 2L MRM Workspace) — moves peer-review from 1L to 2L.


Change Log

Change Log

Canonical going-forward change log: M-020-changes.md (present in model_cards/; Keep-a-Changelog format, versioned with the InsModel release cycle). Code-side change history lives in git log of the component files and in the engine legacy_metadata change_history (GAAPReserveEngine.yaml); release notes in ecosystem/InsModel/CHANGELOG.md.

Registry reconciliation: the model registry lifecycle.documentation_pack currently flags change_log: missing for M-020 even though the canonical M-020-changes.md is present. The §10.5 item-7 change-log requirement is satisfied by the present file; the registry flag should be updated to reflect it (registry-data fix, tracked separately — not a card change).

Pre-baseline authorship history of this card:

  • 2026-05-08 — stub created from registry data per Decision 023 Phase 5 / B-07.
  • 2026-05-09 — added DS-018 + DS-062 references and Standards Coverage section per Stage B (DG-005 closure); Methodology / Key Assumptions / Validation sections remain stubbed for actuarial author follow-on.
  • 2026-05-25 — Tier-1 hand-authoring of Methodology, Key Assumptions and Their Justification, Limitations and Known Gaps, Validation Packet, and References sections. Removed DS-018 + DS-062 lines (registry has DS-001 + DS-008 only; the 2026-05-09 additions were template residue from M-001 stub-copy). Stub marker advanced from to. Phase 1 "documentation-first" path: this hand-authoring is part of the v1.0.0 baseline, issued BEFORE 2L ratification.
  • 2026-06-04 — Validation Packet: added the model-vs-reality back-test reference (BT-012 firm-calibrated reserve reconciliation; BT-013 predictive vs persistence) per A4-30 / Decision 048. SR 26-2 ongoing back-testing now documented on the card.
  • 2026-06-05 — Sharpened known-limitation #2 (MRB instrument-specific-credit-risk OCI-vs-net-income split): made the ASC 820 / ASC 944-40 own-credit (NPR) mechanics explicit, grounded in PRU/MET own-credit MRB adjustments, and stated the OCI leg is tracked-not-closed pending FinView credit-spread integration. Registry M-020 description updated to mirror. No code or output change — the OCI split remains a deferred refinement (the FinView credit-spread feed is the blocker). Draft pending 2L re-attestation.
  • 2026-06-06 — Documentation accuracy pass grounded in actual engine code (gaap_reserve_engine.py, reserve_engine.py, multi_basis_orchestrator.py) and GAAPReserveEngine.yaml legacy_metadata. (1) Corrected the MRB over-claim: MRB / market-risk-benefit / fair-value machinery does NOT exist in any M-020 engine (grep for mrb/market_risk_benefit/fair_value returns nothing; the only GMxB code is in c3_phase2_engine.py backing M-002 C-3/VM-21). Description, Methodology, and Limitation #2 rewritten so MRB fair value and the ASC 820 own-credit OCI split are honestly described as NOT YET MODELLED / out of scope-pending, not a built-mechanic-with-a-deferred-OCI-leg. (2) Reframed AF-01 (Limitation #1): experience-adjustment plumbing (actual_deaths/actual_lapses/actual_expenses, expense_ae_factor, SOA A/E via _apply_soa_ae_adjustment/soa_experience_config; legacy_metadata v1.2.0 "AF-01 closure") exists in code but is inert without actual experience feeds (defaults fall back to expected). (3) Added the CSM mechanic the GAAP engine centers on (initial_csm, coverage-units straight-line csm_amortization, loss_component on CSM exhaustion) to Methodology, and clarified that DPL lives in the LDTI reserve engine (reserve_engine.py) while CSM lives in gaap_reserve_engine.py. (4) Documented the engine version-label convention: "v2.0.0" is the InsModel release tag (same as M-001's snapshot header); the GAAPReserveEngine class attribute is version = "1.0.0". No output numbers changed. (5) Flagged INV-029 Tier-1 evidence as pending, noted validation-link integrity unverified, and reconciled the M-020-changes.md pointer against the registry change_log: missing flag. Output-changing enhancements (MRB build, live A/E feeds, INV-029 evidence, full-curve remeasurement) listed under Limitations as tracked-for-ratification, not applied. Draft pending 2L re-attestation.

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:

asop_56 asc_944 sr_26_2 pcaob_as_2501 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 attested

Ratification

Ratified — RAT-020-v1.0.0

Latest ratification on file: RAT-020-v1.0.0. Authored by 2L (mrm-peer-reviewer) per Decision 028 charter §5 Pattern A.