Tier 1 · Capital Solvency Assessment

Asset Adequacy Testing (AG 53)

M-004 · lifecycle: monitoring · RAT-004-v1.0.1

Intended Use

Asset Adequacy Testing (AG 53) Demonstrate reserve adequacy under stochastic asset and liability cash-flow projection per NAIC Actuarial Guideline 53.

Cash-flow testing across asset and liability sides under defined scenarios. Required annual exercise; output supports the actuarial opinion. AG 53 expanded scope post-2024 to address asset-intensive reinsurance.


Components

Inputs, processing, outputs

data sources
DS-001 · DS-008 · DS-021
assumptions
A-001, A-002, A-010, A-030, A-031, A-090
engines
insmodel.L4.cft_engine
insmodel.L4.asset_engine
insmodel.L4.investment_engine
insmodel.L4.mortality_engine
insmodel.L4.lapse_engine
insmodel.L6.multi_basis_orchestrator
contracts
aat_results_v1
upstream
M-120
dimensions
D7 · D4

Methodology & Mechanics

Methodology

M-004 implements statutory asset adequacy testing (AAT) by cash-flow testing: it projects asset and liability cash flows under a set of prescribed interest-rate scenarios and tests whether the assets supporting a block of business — together with the investment income they generate — remain sufficient to fund liability cash flows over the projection horizon. The engine insmodel.L4.cft_engine (CFTEngine, v1.0.0) is the calculation core; it backs the actuarial-opinion AAT exercise contemplated by NAIC Actuarial Guideline 53.

The mechanics, grounded in firmmodel/engines/cft_engine.py:

  1. Scenario generation (_generate_scenarios). Seven NAIC Model-822-style prescribed interest-rate scenarios are built from a single base_rate (default 4%): Level, +100bps, −100bps, +200bps, −200bps, +300bps, −300bps. Each scenario is a flat rate path across all periods (a constant shift, not a yield-curve evolution), floored at 0.1%.

  2. Asset cash-flow projection (_project_asset_cash_flows). Each holding is described by asset_value, coupon_rate, and maturity_years. The engine pays an annual coupon (value × coupon_rate) each year up to maturity and returns principal at the maturity period. Coupons are not re-projected at scenario rates — only reinvestment of accumulated surplus is rate-sensitive (step 4).

  3. Liability cash-flow projection (_project_liability_cash_flows). Net liability outflow per period is benefit + expense − premium, supplied as a flat per-period dict. The value is held constant across all periods and identical across all scenarios (deterministic liabilities).

  4. Single-scenario accumulation (_run_single_scenario). For each period, net_cf = asset_cf − liability_cf. Positive accumulated surplus earns reinvestment income at max(0, scenario_rate + reinvestment_spread) (default spread −50bps); surplus accumulates as accumulated + net_cf + reinvestment_income. Negative net cash flow draws down accumulated surplus, modelling asset liquidation at book value (no market-value haircut).

  5. Adequacy determination (_compute_adequacy_ratio). A scenario passes if its accumulated surplus never goes negative over the horizon. adequacy_ratio = (scenarios passed) / (total scenarios); worst_scenario_surplus = the minimum, across all scenarios, of each scenario's lowest accumulated-surplus point. The engine emits one row per (scenario, period) carrying asset_cf, liability_cf, net_cf, reinvestment_income, accumulated_surplus, scenario_passed, plus the portfolio-level adequacy_ratio and worst_scenario_surplus.

The default projection horizon is projection_horizon_months // 12 annual periods (120 → 10 years). The engine is fully configuration-driven with no hardcoded calibrations.

AG 53 scope note (honesty). AG 53's distinctive 2024 requirements — granular modelling of complex / illiquid assets, projected net investment income with asset-class-specific spreads and default/downgrade haircuts, and disclosure of reliance on reinvestment assumptions for asset-intensive (often reinsured) blocks — are not implemented. CFTEngine models a homogeneous fixed-coupon-bond asset side at book value with a single scalar reinvestment spread. The card documents a generic prescribed-scenario CFT engine that supports the AAT/AG-53 opinion workflow, not a full AG-53 complex-asset analyzer. See Limitations.


Key Assumptions

Key Assumptions and Their Justification

ID Name Value (canonical run) Derivation Justification for AAT / AG 53
A-030 Reinvestment spread −50 bps over scenario rate config_default Reinvestment of surplus below scenario rate is a conservative net-investment-income assumption consistent with AG 53's emphasis on reinvestment-rate reliance.
A-031 Prescribed scenario set 7 NAIC scenarios: Level, ±100/±200/±300 bps off a 4% base published_source NAIC Model 822 prescribed deterministic interest-rate scenarios — the regulatory minimum scenario family for the AAT opinion.
A-090 Projection horizon 10 years (projection_horizon_months = 120) config_default Standard CFT horizon for the actuarial-opinion exercise; configurable per block.
A-001 / A-002 Mortality basis / improvement bound but not consumed by CFTEngine published_source Listed as block components; in the current engine liabilities enter as a pre-computed net cash-flow dict, so these enter upstream (if at all), not inside CFTEngine.
A-010 Base lapse curve bound but not consumed by CFTEngine data_calibrated Lapse-driven liability dynamics are upstream of the flat per-period liability input.

Operational assumptions beyond the formal IDs: - Flat scenario paths. Each scenario applies a single constant rate across all periods rather than a projected yield-curve path; a simplification of Model-822 dynamic scenarios. - Book-value liquidation. Negative net cash flow is funded from accumulated surplus with no market-value adjustment — no disinvestment loss on a falling-rate/credit-stress path. - Asset side = fixed-coupon bonds. Only asset_value, coupon_rate, maturity_years are modelled; coupons are not re-projected at scenario rates (only surplus reinvestment is rate-sensitive). - Deterministic, scenario-invariant liabilities. Liability cash flows do not vary by scenario (no dynamic lapse / interest-sensitive surrender behavior inside the engine).


Output Snapshot

Output Snapshot

Deterministic single-block run of CFTEngine v1.0.0 — reproducible, requires no live firm data (python scripts/model_snapshots.py M-004 in InsModel; the cash-flow decomposition is asserted by tests/mrm/test_gold_tier0.py::TestGoldCFT::test_gold_cft).

Input: 1 bond · asset_value $1,000,000 · coupon 5% · maturity 5yr · liability benefit $60K/yr · premium $80K/yr · expense $10K/yr · base_rate 4% · reinvestment_spread −50bps · 7 NAIC scenarios · 10-year horizon

output value meaning
n_scenarios 7 NAIC prescribed interest-rate scenarios run
scenarios_passed 7 scenarios in which accumulated surplus never goes negative
adequacy_ratio 1.00 fraction of scenarios passing → assets adequate under all 7
assets_adequate True adequacy_ratio ≥ 1.0
worst_scenario_surplus 60,000.00 min, over all scenarios, of each scenario's lowest surplus point
surplus[Level] @yr10 1,623,446.60 terminal accumulated surplus, level scenario
surplus[−300bps] @yr10 1,386,420.31 terminal surplus, lowest-rate scenario (least reinvestment income)
surplus[+300bps] @yr10 1,895,069.97 terminal surplus, highest-rate scenario (most reinvestment income)
level_p1_asset_cf 50,000.00 year-1 coupon = $1M × 5%
level_p1_liability_cf −10,000.00 net liability = 60K + 10K − 80K (premium exceeds outflow)
level_p1_net_cf 60,000.00 asset_cf − liability_cf = 50K − (−10K)

In this canonical block the premium income exceeds benefit+expense outflow, so net liability cash flow is negative (a net inflow of $10K/yr) and every period adds positive surplus; the block is adequate in all 7 scenarios (adequacy_ratio = 1.00). Terminal surplus rises monotonically with the scenario rate because higher rates earn more reinvestment income on accumulated surplus — the only rate-sensitive channel in the engine. The three level_p1_* rows reproduce the frozen gold-test values exactly.

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


Limitations

Limitations and Known Gaps

  1. No AG 53 complex-asset modelling. The engine's distinguishing AG 53 features are absent: no asset-class taxonomy, no spread/default/downgrade modelling, no separate treatment of complex/illiquid assets. The asset side is a homogeneous fixed-coupon bond projection.
  2. Flat scenario rates, not yield-curve paths. Each scenario is a single constant rate floored at 0.1%; no term structure, no dynamic rate evolution. Weaker than the full NAIC Model 822 / GOES prescribed family.
  3. Reinvestment is the only rate-sensitive channel. Asset coupons are fixed; only reinvestment of accumulated surplus responds to the scenario rate. Understates rate sensitivity for floating-rate/callable assets and cannot show disintermediation losses.
  4. Book-value liquidation, no market-value haircut. Negative net cash flow draws down surplus at book value; no disinvestment loss on a rising-rate path.
  5. Liabilities are flat and scenario-invariant. Net liability is a single constant per-period figure identical across scenarios. No interest-sensitive lapse, no dynamic behavior, no link to the mortality/lapse engines the card lists as components.
  6. Card-vs-code component divergence. The Components section lists asset_engine, investment_engine, mortality_engine, lapse_engine, multi_basis_orchestrator, but CFTEngine does not import or compose any of them; it consumes a bond DataFrame and a liability-CF dict directly. Multi-engine AAT composition is orchestrated elsewhere, not inside this engine.
  7. No stochastic / CTE output. AAT here is deterministic across 7 prescribed scenarios; adequacy_ratio is a pass-count fraction, not a tail measure.
  8. Firm-data path divergent (BV-032). The snapshot uses a MagicMock provider; no 10-K-derived figures are claimed.

The output-changing items above (AG-53 complex-asset capability per INV-003; the listed asset/investment/mortality/lapse/orchestrator engines as upstream producers not composed by CFTEngine per INV-003 / INV-012; and the absent Tier-1 validation-evidence pack / qualified-actuary effective challenge / annual backtest) are tracked for ratification, not resolved in this documentation pass.


Validation Evidence

Validation Packet

evidence status reference
Frozen gold regression present tests/mrm/test_gold_tier0.py::TestGoldCFT::test_gold_cft — freezes the level-scenario period-1 cash-flow decomposition (50,000 / −10,000 / 60,000).
Deterministic snapshot present scripts/model_snapshots.py M-004.
Fail-path coverage partial The canonical block is trivially adequate (net inflow); a shortfall/fail input is not exercised in the frozen case.
Complex-asset / AG-53 validation missing AG-53-specific asset modelling is not built.
Independent challenge (2L) pending Ratification artifact RAT-004-v1.0.0; registry peer_review.status = pending, signed_off_by = platform-staff — platform-staff attestation, not yet a qualified-actuary independent effective challenge (VM-G / AP-26).
Validation evidence pack pending No validation_evidence/M-004/ index yet (registry documentation_pack.validation_evidence = missing); needs a §10.5-style pack analogous to validation_evidence/M-001/v7.0.0/README.md.
Backtesting (SR 26-2 / MRM §10.2) pending No model-vs-reality reconciliation. What is needed: realized asset-adequacy outcomes / filed actuarial-opinion (asset-adequacy) results to reconcile the engine's adequacy determination against.

References

References

Regulatory: - NAIC Actuarial Guideline 53 (AG 53) — Application of the Valuation Manual for Testing the Adequacy of Reserves; complex-asset and projected-net-investment-income disclosure. - NAIC Model Regulation 822 (Actuarial Opinion and Memorandum Regulation) — prescribed interest-rate scenarios. - ASOP No. 7 — Analysis of Life, Health, and P&C Insurer Cash Flows. - ASOP No. 22 — Statements of Actuarial Opinion Based on Asset Adequacy Analysis. - ASOP No. 56 — Modeling.

Source code: - Engine: ecosystem/InsModel/Models/firmmodel/engines/cft_engine.py (CFTEngine, insmodel.L4.cft_engine, v1.0.0). - Frozen gold test: tests/mrm/test_gold_tier0.py::TestGoldCFT::test_gold_cft. - Snapshot: scripts/model_snapshots.py M-004.


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 — Tier-1 hand-authoring of Methodology, Key Assumptions and Their Justification, Output Snapshot, Limitations and Known Gaps, Validation Packet, and References sections from CFTEngine (firmmodel/engines/cft_engine.py) + bound A-NNN entries + frozen gold test. Stub marker advanced from to.
  • 2026-06-04 — recorded the INV-003 component-divergence annotation in the M-004 registry entry: cft_engine = composed (AAT core); asset_engine / investment_engine / mortality_engine / lapse_engine / multi_basis_orchestrator = upstream producers, not composed by CFTEngine (see Limitation 6).
  • 2026-06-06 — documentation pass: named the ratification artifact RAT-004-v1.0.0 and recorded peer-review pending (signed_off_by = platform-staff, not yet a qualified-actuary independent challenge); added honest validation-evidence-pack-pending and backtesting-pending rows (registry documentation_pack.validation_evidence/change_log = missing); flagged the gated/output-changing findings as tracked-for-ratification under Limitations. Companion engine_registry fix: corrected insmodel.L4.cft_engine path from investment_engine.py to cft_engine.py (D049 doc-currency watermark map was watching the wrong file).

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-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.

MEDIUM INV-003 · P1 · capability-gap

AG-53 has no complex-asset modelling; listed component engines not composed

CFTEngine is a generic 7-scenario flat-rate cash-flow-testing engine over a homogeneous fixed-coupon bond book at book value. AG 53's defining requirements — complex/illiquid asset modelling, projected net investment income with asset-class spreads + default/ downgrade haircuts — are absent. Separately, the M-004 Components list asset/investment/ mortality/lapse/multi_basis engines, but CFTEngine imports NONE of them; it takes a pre-computed liability-CF dict + a bond DataFrame directly (card-vs-code divergence).

Recommendation: (1) Add an asset taxonomy + spread/default/downgrade haircut model and projected-NII for complex assets to meet AG-53; (2) either wire the listed component engines into an AAT orchestrator that feeds CFTEngine, or correct the M-004 Components to reflect that CFT consumes pre-computed inputs. Replace flat scenarios with the prescribed Model-822 paths.

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 naic_ag53 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 attested

Ratification

Ratified — RAT-004-v1.0.1

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