Tier 1 · Statutory Reserves

VM-22 Statutory Reserves (Non-Variable Annuity)

M-003 · lifecycle: development · RAT-003-v1.0.3

Intended Use

VM-22 Statutory Reserves (Non-Variable Annuity) Compute statutory reserves for fixed and indexed annuities under NAIC VM-22 (PBR for non-variable annuities).

Optional 2026, mandatory 2029. Methodology adapted from VM-20 PBR for non-variable annuity products including indexed annuities and RILA. Engine TBD; component composition will mirror VM-20 with annuity-specific cash-flow logic.


Components

Inputs, processing, outputs

data sources
DS-001
assumptions
A-001, A-002, A-010, A-011
engines
insmodel.L4.vm22_engine
insmodel.L4.mortality_engine
insmodel.L4.lapse_engine
insmodel.L6.projection_orchestrator
contracts
statutory_reserves_v1
upstream
M-120

Methodology & Mechanics

Methodology

M-003 is the model card for statutory reserves on non-variable annuities — fixed deferred annuities, payout/income annuities, indexed annuities (FIA), and registered index-linked annuities (RILA) — under the NAIC Valuation Manual Section 22 (VM-22) principles-based reserve (PBR) framework. VM-22 is optional from 2026-01-01 and mandatory from 2029, and it brings non-variable annuities into the same PBR family as VM-20 (life) and VM-21 (variable annuities). It is intended to supersede the deterministic Commissioners Annuity Reserve Valuation Method (CARVM) of Actuarial Guideline IX-C / AG 33 (income-annuity and elective-benefit valuation) with a VM-21-style CTE-based stochastic reserve plus a deterministic floor.

M-003 is under_development. There is no VM-22-specific engine in InsModel today. The target architecture — a vm22_engine analogous to the VM-20 vm20_engine, composing annuity-specific cash-flow logic over the common projection harness and producing a max(net-premium floor, deterministic reserve, stochastic CTE reserve) held amount — is planned for Q2–Q3 2026 and does not yet exist. The model registry (M-003) therefore binds insmodel.L4.reserve_engine_stat (STATReserveEngine, registry ID M-101S) as an explicit placeholder, alongside mortality_engine, lapse_engine, and the projection_orchestrator.

What STATReserveEngine computes today (the CARVM/CRVM stand-in)

STATReserveEngine (firmmodel/engines/stat_reserve_engine.py, v1.0.0) implements classical NAIC CRVM and NLP statutory reserves with prescribed mortality and a single prescribed valuation interest rate. For each policy it projects, per annual duration t:

  1. Net valuation premium (NVP) — the level annual premium, payable at the start of each year, whose present value equals the PV of future benefits at issue: NVP = PV(future benefits) / annuity-due(premium-paying period), computed at the valuation rate with survival-weighted prescribed mortality (_compute_net_valuation_premium).
  2. Net Level Premium (NLP) reserve at duration tPV(future benefits from t) − NVP · annuity-due(remaining years) (_compute_nlp_reserve).
  3. CRVM reserve — the NLP reserve graded linearly from 0 at issue to the full NLP reserve over the grading period (min(max_crvm_grading_years, premium-paying period)), per _compute_crvm_reserve. CRVM ≤ NLP during grading.
  4. Tabular cost of insuranceface · q_x / (1 + valuation_rate) for the period.
  5. Deficiency reserve — when the gross premium charged is below the NVP, (NVP − gross_premium) · annuity-due(remaining years), floored at zero (_compute_deficiency_reserve).
  6. Held reservetotal_stat_reserve = max(0, primary_reserve + deficiency_reserve), where the primary reserve is CRVM (default) or NLP per the reserve_method parameter.

Mortality comes from a reference-data lookup (2017 CSO) when a provider supplies it; otherwise the engine falls back to the deterministic closed form q_x = 0.00005 · 1.09^(age − 20) (_get_mortality_rates). The snapshot below uses the fallback path so it is fully reproducible with no live data.

What this is, and is not, relative to VM-22

The bound engine is a death-benefit-style life-reserve calculator: it values a face amount against mortality and a level premium. That is a faithful CRVM/CARVM-family stand-in — CARVM and CRVM share the same net-premium/prospective-reserve machinery — but it is not VM-22. It does not implement the VM-22 components that distinguish annuity PBR from a net-premium life reserve: annuity payout/income cash-flow streams and elective-benefit (GLWB/GMIB) valuation, the CTE-based stochastic reserve over a prescribed economic scenario set, the VM-22 deterministic-reserve floor, indexed-annuity (FIA/RILA) option-budget and index-credit modelling, or dynamic policyholder behaviour. Those arrive only with the planned vm22_engine. The snapshot is documented as the CRVM/CARVM stand-in pending a real VM-22 PBR engine, consistent with how M-002 documents its reserve_engine_stat binding (registry open question Q-02).


Key Assumptions

Key Assumptions and Their Justification

The registry binds four A-NNN entries for M-003. Because the bound engine is the CRVM/CARVM stand-in, the engine exercises only the prescribed valuation rate and the mortality basis directly; the lapse and indexed-credit assumptions are bound for the forthcoming VM-22 engine and are not yet consumed by STATReserveEngine.

ID Name Value Derivation Justification / status under VM-22
A-001 Base mortality table 2017 CSO Loaded (Male/Female), or deterministic fallback when no reference data published_source Mortality basis for the death-benefit leg and survival weighting of annuity cash flows. Consumed by the stand-in via the reference-data lookup; falls back to q_x = 0.00005·1.09^(age−20) when unavailable.
A-002 Mortality improvement scale MP-2021 (SOA) published_source Latest SOA improvement scale; under VM-22 it grades projected annuitant mortality. Not exercised by the stand-in (no improvement layer in STATReserveEngine).
A-010 Base lapse curve (spread liability) Duration-graded: 15% Y1 → 5% Y10+ data_calibrated Persistency basis for fixed/spread annuity surrenders; central to a VM-22 cash-flow projection. Registry-bound but not consumed by the stand-in (no decrement-driven surrender in the net-premium reserve).
A-011 Base lapse curve (annuity w/ guarantees) Duration-graded: 8% Y1 → 3% Y10+ data_calibrated Lower persistency assumption for guaranteed-benefit annuities; the planned VM-22 engine will layer dynamic (moneyness-driven) lapse on top. Not consumed by the stand-in.

Operational assumptions exercised by the stand-in (engine parameters): - Valuation interest ratevaluation_rate = 3.5%, the prescribed maximum statutory valuation rate (SVL). Single flat rate; VM-22 uses a prescribed scenario-dependent discount structure. - Reserve methodCRVM (default); NLP available. CRVM grades the reserve from 0 over min(20, premium-paying period) years. - Deficiency reserve — enabled; triggers only when gross premium < NVP (zero in the canonical run, where the funding premium exceeds NVP). - Mortality source — deterministic fallback formula in the snapshot (no live reference data), making the result reproducible.

Honesty note: A-002, A-010, and A-011 are bound in the registry for the intended VM-22 model but are inert in the engine that runs today. This is the single largest gap between this card's assumption table and the engine's actual behaviour, and is restated in Limitations.


Output Snapshot

Output Snapshot

Deterministic single-policy run of the real VM22ReserveEngine v1.0.0 on a canonical FIA — reproducible (python scripts/model_snapshots.py M-003 in InsModel; exercised by tests/test_vm22_reserve_engine.py). The stochastic leg consumes the ratified GOES set (M-120 / RAT-120-v1.0.2, seed 42, amp 4.3).

Input: issue age 60 · account value $250,000 · FIA · participation 50% · cap 8% · guaranteed 1% · surrender-charge 7yr · valuation rate 3.5% · deterministic rate 4.5%.

output value meaning
carvm_reserve 226,884.06 CARVM greatest-present-value elective-benefit floor (AG IX-C / AG 33)
deterministic_reserve 227,245.41 VM-22 deterministic reserve (single prescribed scenario)
cte_stochastic_reserve 282,140.77 CTE70 stochastic reserve over 50 GOES scenarios
vm22_reserve (held) 282,140.77 max(CARVM, deterministic, CTE70) — the held VM-22 reserve
reserve_basis stochastic_cte the binding leg (the stochastic tail exceeds the deterministic floor)
account_value 250,000.00 annuity account value

The held reserve is ~113% of the account value — economically credible for an annuity statutory reserve (account value plus a guarantee/tail load), unlike the prior CRVM life stand-in which produced ~312 on the same $250k policy. The CTE70 leg binds above the deterministic floor, exactly the VM-22 greatest-of mechanic.

Captured 2026-06-28 · deterministic legs need no live data; stochastic leg uses the gitignored GOES CSVs (regenerable via scripts/generate_goes_scenarios.py).


Limitations

Limitations and Known Gaps

2026-06-28 update. Limitations 1–5 below described the CRVM stand-in and are now largely closed by the real VM22ReserveEngine (held = max(CARVM floor, deterministic, CTE stochastic over GOES); FIA/RILA index-credit live; A-002/A-010/A-011 now real engine levers — closes INV-002 / INV-012). Limitation 7 (no firm 10-K back-test, BV-032) remains open. The remaining honest gaps in the real engine are itemized in validation_evidence/M-003/v1.0.0/README.md §4 (prescribed-ERP deterministic assumption is first-order; surrender-charge schedule is representative; annuitization is a greater-of(AV, GBB) proxy; the richer P-003 option-pricing is not yet composed). The historical list is retained below.

  1. Model is under_development — there is no VM-22-specific engine. The registry status for M-003 is under_development (planned implementation Q2–Q3 2026; mandatory 2029). No vm22_engine exists. Every number in this card comes from a placeholder engine and must not be read as a VM-22 reserve. [2026-06-28: CLOSED — VM22ReserveEngine (M-101A) built and 2L-approved (RAT-003-v1.0.3); status promoted to active. The current Output Snapshot / Validation Packet are produced by the real VM-22 engine; the placeholder caveat applies only to the retained historical stand-in sections.]
  2. The bound engine is a CRVM/CARVM life-reserve stand-in, not annuity PBR. insmodel.L4.reserve_engine_stat (STATReserveEngine, M-101S) computes net-premium / CRVM statutory reserves against a face amount and mortality. It does not model annuity payout/income streams, account-value accumulation, or the CARVM elective-benefit greatest-present-value test (AG IX-C / AG 33). It is documented as a stand-in only, paralleling M-002's Q-02 caveat for the same engine binding.
  3. No stochastic reserve and no deterministic VM-22 floor. VM-22 PBR is a CTE-based stochastic reserve over a prescribed economic scenario set, floored by a deterministic reserve. Neither the scenario generation, the CTE aggregation, nor the deterministic floor exists for M-003. (M-002's C3Phase2Engine provides CTE mechanics for variable annuities, but it is not wired to M-003 and is not a non-variable-annuity engine.)
  4. No indexed-annuity (FIA / RILA) modelling. Fixed indexed annuities and RILAs require option-budget, index-credit, cap/participation, and buffer/floor mechanics. None of this is present; the stand-in treats the product as a fixed death-benefit contract.
  5. Bound lapse and improvement assumptions are inert. A-002 (mortality improvement), A-010 and A-011 (lapse curves) are registry-bound for the intended VM-22 model but are not consumed by STATReserveEngine. Dynamic (moneyness-driven) policyholder behaviour, central to annuity PBR, is absent.
  6. Reserve reflects only a mortality leg, not the annuity liability. Because the engine values a net-premium death benefit, the held reserve runs off to zero at the end of the premium-paying period and is small relative to the account value. A VM-22 reserve would hold the accumulation and guaranteed-payout liability; the magnitudes here are not comparable to a real annuity statutory reserve.
  7. Not validated against firm 10-K data. No 10-K reconciliation is claimed. The firm-financials path is divergent (finding BV-032); the snapshot is a synthetic canonical run with mock data only.

Remediation tracked (gated — requires engine/output changes, left for ratification, not applied in this documentation pass): INV-002 (build a real CARVM / VM-22 PBR engine with CTE stochastic reserve, deterministic floor, annuity payout & FIA/RILA mechanics — the substantive capability gap behind Limitations 1–4); INV-012 (thread the bound decrement curves A-010/A-011 and improvement scale A-002 into the engine, or relocate them to the upstream liability-projection step that consumes them — they are registry-bound but inert today, Limitation 5); and producing the VM-22 back-test / sensitivity evidence now shown as "pending/missing" in the Validation Packet.


Validation Evidence

Validation Packet

evidence status reference
Deterministic snapshot present scripts/model_snapshots.py M-003 (reproduces the Output Snapshot above).
Engine unit + mechanics tests present tests/test_vm22_reserve_engine.py — 28 tests: contract, greatest-of mechanic, CARVM elective-option behaviour, FIA/RILA index-credit + option budget, A-002/A-010/A-011 bindings, CTE hand-calc + monotonicity.
VM-22 engine present VM22ReserveEngine (insmodel.L4.vm22_engine, M-101A), built 2026-06-28 (INV-002).
Frozen VM-22 gold regression present tests/test_vm22_reserve_engine.py::TestVM22GoldDeterministic (CI-gated, no data) + ::TestVM22GoldStochastic (50-scenario GOES, seed 42 amp 4.3; data-gated).
VM-22 sensitivity suite present ::TestVM22AssumptionBindings + ::TestVM22IndexCredit (top-3 levers: A-002 mortality improvement, A-010/A-011 lapse, index-credit/option-budget).
Validation evidence pack present insightalm/modelling/validation_evidence/M-003/v1.0.0/README.md (clears COND-001/COND-002).
Independent challenge (2L) APPROVED RAT-003-v1.0.3 (2026-06-28) — model-lifecycle-reviewer 2L effective challenge approved the build; status promoted to active.
Back-test vs disclosed reserves missing Honest gap — blocked on firm annuity-reserve data (BV-032). Honesty anchor is the frozen synthetic gold, not firm data.

Model-vs-reality back-testing (SR 26-2 ongoing; canonical record backtest_results.yaml): records BT-012 and BT-013 are keyed to the engine insmodel.L4.reserve_engine_stat at the firm-book level, which M-003 shares with M-002 (model_membership: [M-002, M-003]). They co-validate the shared STATReserveEngine firm-book reconciliation, not M-003's own held reserve. This distinction matters for M-003 specifically: the stand-in's held number is a mortality-leg net-premium reserve (Limitations 6–7), which is not the VM-22 annuity reserve and is not comparable to a filed annuity statutory reserve — so it is not the figure being reconciled to filed reserves.

For context, the shared firm-book records read: 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) reconciles the firm-book reserve aggregate to reported policy reserves by reportable segment, superseding the earlier Mock-notional 0% (BT-011). Predictive record BT-013: at quarterly cadence a reserve roll-forward is benchmarked against naive persistence (~3.4% q/q baseline), which a structural roll-forward beats only where segment flows are cleanest.

For M-003 the honest state is: reserve back-test pending a real VM-22 engine. The BT-012 firm-book reconciliation co-validates the shared STATReserveEngine; it does not validate the VM-22 annuity reserve, which has no engine to back-test (see Validation Packet rows "VM-22 engine: missing" and "Back-test vs disclosed reserves: missing"). Sign-off requires a real VM-22 PBR engine and a back-test against disclosed VM-22 / annuity reserves.


References

References

Regulatory: - NAIC Valuation Manual VM-22 — Statutory Maximum Valuation Interest Rates / PBR for non-variable (fixed and indexed) annuities; optional 2026-01-01, mandatory 2029. - NAIC Actuarial Guideline IX-C / AG 33 (CARVM) — Commissioners Annuity Reserve Valuation Method; deterministic valuation of annuity benefits and elective benefits, the framework VM-22 PBR supersedes. - NAIC Standard Valuation Law (SVL) — prescribed maximum statutory valuation interest rate (the valuation_rate parameter). - NAIC Valuation Manual VM-G / VM-31 — governance and documentation taxonomy for PBR. - ASOP No. 56 — Modeling (intended use, sensitivity, reliance, documentation).

Source code: - Engine (registry-bound, current): ecosystem/InsModel/Models/firmmodel/engines/vm22_reserve_engine.py (VM22ReserveEngine, insmodel.L4.vm22_engine, registry id M-101A) — the real VM-22 PBR engine: CARVM greatest-PV floor, deterministic reserve, CTE stochastic reserve over GOES, FIA/RILA option-budget + index-credit. - Tests: ecosystem/InsModel/Models/tests/test_vm22_reserve_engine.py. - Snapshot generator: ecosystem/InsModel/Models/scripts/model_snapshots.py (snap_M_003, python scripts/model_snapshots.py M-003). - Historical (superseded stand-in): firmmodel/engines/stat_reserve_engine.py (STATReserveEngine, M-101S) — CRVM/NLP life statutory reserves, the former CARVM/CRVM stand-in (retained for the historical sections below).

Internal: - Model registry entry M-003 (status active; engine binding insmodel.L4.vm22_engine; lifecycle.ratification_ref: RAT-003-v1.0.3): insightalm/modelling/model_registry.yaml. - Decision 018 (MRM Framework); Decision 020 (Assumption Policy). - Finding BV-032 — firm-financials path divergence (no 10-K reconciliation claimed).


Change Log

Change Log

Card change history. Code-side change history lives in git log of the component files.

  • 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-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-28Real VM-22 engine built (INV-002, 1L model-builder per Decision 053). Bound VM22ReserveEngine (insmodel.L4.vm22_engine, M-101A) in place of the CRVM stand-in. Implements held = max(CARVM greatest-PV floor, deterministic reserve, CTE stochastic reserve over GOES M-120/amp 4.3); FIA/RILA option-budget + index-credit mechanics; A-002/A-010/A-011 now live engine levers (closes INV-012). Updated Output Snapshot (FIA, held 282,140.77 CTE-bound), Validation Packet (engine/gold/sensitivity now present), Limitations (1–5 closed, 7 open), and added the validation_evidence/M-003/v1.0.0 pack. Registry: engine binding swapped, M-120 dependency declared, validation_evidence → present. Status stays under_development pending 2L promotion (1L does not self-ratify). Earlier stand-in sections retained for history with the supersession banner at the top.
  • 2026-06-06 — Documentation pass (safe fixes only; no engine/output changes): added the Dependencies section (13-section gold-standard order; honest "no upstream-model dependencies declared", planned vm22_engine GOES-style scenario dependency, no current downstream consumer per R-24 element 8). Reconciled the Validation Packet BT-012/BT-013 paragraph with Limitations 6–7 — clarified these records are keyed to the shared STATReserveEngine firm-book (shared with M-002), not to M-003's held mortality-leg reserve; honest state is "reserve back-test pending a real VM-22 engine". Added a sentence to Standards Coverage explaining it is broader than the registry regulatory_frameworks regime tags, flagging ASOP_52 / VM_31 as intended-model standards not yet exercised. Noted gated remediation (INV-002, INV-012, VM-22 back-test evidence) under Limitations as tracked-for-ratification. Engine-governance cross-check filed separately: engine_registry.yaml path for insmodel.L4.reserve_engine_stat points at firmmodel/engines/reserve_engine.py (which holds the LDTI ReserveEngine); the actual STATReserveEngine lives in firmmodel/engines/stat_reserve_engine.py, which this card cites correctly — registry path fix is outside the card.

2L Inventory Review

Open findings (3)

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-002 · P1 · capability-gap

VM-22 has no VM-22 engine (CRVM life stand-in)

M-003 (Non-Variable Annuity statutory) is status under_development and binds reserve_engine_stat (STATReserveEngine), a CRVM *life* death-benefit reserve calculator. It values a mortality leg that runs off to zero at end of premium-paying period, not an annuity accumulation/payout liability. There is no CARVM or VM-22 PBR engine.

Recommendation: Build a CARVM engine for fixed/payout annuities (greatest-present-value of guaranteed benefit streams) as the near-term statutory basis, with a VM-22 PBR path as the roadmap target. Until then keep status under_development and label the card a CRVM stand-in (done). Add the engine to engine_registry as E-NNN.

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.

LOW INV-012 · P2 · paper-binding

Lapse/mortality curves bound but not consumed by the engine

M-003 binds lapse curves (A-010/A-011) that STATReserveEngine never reads; M-004 lists mortality/lapse among components but CFTEngine takes a pre-computed liability-CF dict, so they enter (if at all) upstream, not inside the engine.

Recommendation: Thread the bound decrement curves into the engines (M-003 once a CARVM/VM-22 engine exists, INV-002), or move the bindings to the upstream liability-projection step that actually consumes them.


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 vm_g_vm22 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-003-v1.0.3

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