Regulatory Architecture & Compliance Mapping

Regulatory architecture and compliance mapping are the discipline of translating statutory text into executable validation logic, immutable audit trails, and production filing pipelines that survive examination. For actuaries, compliance officers, and Python engineers building insurance valuation systems, this is the connective tissue between the numbers a model produces and the regulator who must be able to reconstruct, challenge, and sign off on them. This page maps the full pipeline — from statute to submission — and links out to the deep-dive frameworks for each stage: NAIC VM-20 Compliance Frameworks, OSFI Model Risk Management Guidelines, Actuarial Audit Trail Architecture, and Data Security & PII Boundaries for Filing Systems.

Why This Domain Exists

Insurance is one of the most heavily supervised industries on the planet because a reserve number that is wrong today becomes an insolvency five years from now. Every reserving and capital model that feeds a regulatory filing is now subject to prescriptive model-governance regimes, and each regime carries a different vocabulary for the same underlying demand: prove that the model is correct, prove that nobody tampered with it, and prove that you can reproduce the exact result on demand.

  • NAIC VM-20 and VM-21 (US life and variable annuity principle-based reserving) require a deterministic reserve, a stochastic reserve, and a documented reconciliation between them, together with an actuarial memorandum that a state examiner can trace back to source assumptions.
  • OSFI E-23 and LICAT (Canada) frame the same expectations as enterprise-wide model risk management — Principle-based governance, independent validation, and a capital adequacy test with prescribed yield-curve and shock calibrations.
  • IFRS 17 and LDTI (US GAAP long-duration targeted improvements) push measurement changes — contractual service margin, discount-rate unlocking — that must flow through the same validated pipeline rather than a parallel spreadsheet.
  • SR 11-7 (US Federal Reserve model risk guidance) is the reference text everyone borrows from: models are validated across conceptual soundness, ongoing monitoring, and outcomes analysis, with an inventory and effective challenge baked in.

The cost of ignoring this is not abstract. A filing that cannot be reproduced is a filing the examiner distrusts, and distrust escalates into re-openings, capital add-ons, and remediation orders. A single unlogged assumption override that moves a reserve by a few percent can invalidate an entire quarter’s submission. Regulatory architecture exists so that compliance is a property the system guarantees by construction, not a checklist someone runs the night before the deadline.

The engineering counterpart to these mandates lives across two sibling domains on this site: assumption governance is handled by the Assumption Validation & Rule Engine Design framework, and the upstream data plumbing is covered by Actuarial Model Ingestion & Testing Workflows. Compliance mapping is the layer that binds both to the regulator.

Architecture Overview

The pipeline moves left to right: statutory text is decomposed into a machine-readable rule matrix, assumptions and policy data are ingested and schema-checked, scenarios are executed, model output is validated against the rule matrix, and only a passing, hash-sealed record is assembled into a filing package. A breach never silently continues — it is routed to an exception queue with the offending citation attached.

Statute-to-filing compliance pipeline Statutory text is turned into a rule-mapping matrix, executed through a deterministic validation pipeline, and gated: passing records become an audit-ready compliance record and a regulatory filing package, while a breach is routed to an exception queue carrying the offending regulatory citation. pass breach Statutory text VM-20 · OSFI E-23 · IFRS 17 Rule mapping matrix Deterministic validation pipeline Audit-ready compliance record Regulatory filing package Exception queue citation attached
Statute to submission: a breach never silently continues — it is routed to the exception queue with its offending citation.

The sections below walk each phase in turn, with a runnable Python pattern and the actuarial or compliance logic behind it.

Phase 1 — Statutory Decomposition & Rule Traceability

Every compliant system begins by turning prose into structured metadata. A statutory framework such as VM-20 does not describe a single test; it describes dozens of interacting requirements about reserve adequacy, scenario counts, mortality margins, and disclosure. The first job of the architecture is to decompose that prose into a traceable rule matrix where each row links a specific regulatory citation to a validation routine, its input fields, and its numeric thresholds. The mechanics of that decomposition for the US regime are detailed in How to Map Actuarial Models to NAIC VM-20 Requirements.

Treating requirements as data rather than narrative is what makes automation possible. When each rule carries its citation, teams get a bidirectional traceability graph: from a failing check you can jump to the exact statute clause, and from a statute clause you can list every check that enforces it. That graph is precisely what an examiner asks for, and it is what an internal reviewer needs to perform effective challenge under SR 11-7.

from pydantic import BaseModel, Field
from typing import Literal

class ComplianceRule(BaseModel):
    """One row of the statute-to-code traceability matrix."""
    rule_id: str
    regulatory_citation: str          # e.g. "VM-20 Section 7.A"
    pipeline_component: str           # which validator enforces it
    metric_name: str                  # field on the model output
    min_threshold: float
    max_threshold: float
    severity: Literal["CRITICAL", "WARNING", "INFO"]

RULE_MATRIX = [
    ComplianceRule(
        rule_id="VM20-DR-01",
        regulatory_citation="VM-20 Section 4",
        pipeline_component="deterministic_reserve_validator",
        metric_name="reserve_adequacy_ratio",
        min_threshold=1.00, max_threshold=1.50,
        severity="CRITICAL",
    ),
    ComplianceRule(
        rule_id="VM20-SR-02",
        regulatory_citation="VM-20 Section 5",
        pipeline_component="stochastic_reserve_validator",
        metric_name="cte70_ratio",
        min_threshold=1.00, max_threshold=2.00,
        severity="CRITICAL",
    ),
]

Because the matrix is a Pydantic model, it is version-controlled, diff-reviewable, and self-documenting. A regulatory bulletin that tightens a threshold becomes a one-line change with a reviewable pull request rather than an untracked edit buried in a workbook.

Phase 2 — Assumption Ingestion & Schema Enforcement

Once the rule matrix exists, real data has to enter the pipeline: policy administration extracts, mortality and lapse tables, and economic assumption sets. This is the boundary where most filings quietly go wrong — a mis-typed face amount, a lapse rate expressed as a percentage instead of a decimal, a valuation date off by a quarter. The remedy is strict schema enforcement at the ingestion edge, the pattern documented in Schema Validation with Pydantic & Great Expectations.

Schema enforcement here is not merely type-checking; it encodes actuarial invariants. A reserve_amount cannot be negative, a lapse_rate must sit in [0,1][0, 1], and a valuation_date cannot post-date the run. Rejecting a malformed record at ingestion is orders of magnitude cheaper than discovering it in a filed actuarial memorandum.

from datetime import date
from pydantic import BaseModel, Field, field_validator

class PolicyValuation(BaseModel):
    policy_id: str
    valuation_date: date
    face_amount: float = Field(gt=0)
    lapse_rate: float = Field(ge=0.0, le=1.0)
    mortality_table: str
    reserve_amount: float = Field(ge=0)

    @field_validator("valuation_date")
    @classmethod
    def not_in_future(cls, v: date) -> date:
        if v > date.today():
            raise ValueError("valuation_date cannot be in the future")
        return v

The assumptions that feed these records — which mortality basis, which lapse curve, which interest scenario — are not free parameters; they are governed artifacts. That governance is the subject of the Assumption Validation & Rule Engine Design framework, which enforces the same threshold logic at the assumption boundary that this pipeline enforces at the output boundary.

Phase 3 — Scenario Execution & Deterministic Validation

Principle-based reserving is inherently stochastic: VM-20’s stochastic reserve is a CTE(70) over a large set of economic scenarios, and LICAT applies prescribed shocks to a base yield curve. Executing those scenarios reproducibly is a prerequisite for a defensible filing, and the frameworks for generating them are covered in Stochastic Scenario Generation Frameworks, with the regulatory yield-curve alignment handled by Economic Scenario Mapping & Yield Curve Alignment.

The non-negotiable engineering property is determinism. The prospective reserve at time tt is the expected present value of future benefits and expenses less future premiums,

tV=E ⁣[k=0ntvk(Bt+k+Et+kPt+k)],{}_{t}V = \mathbb{E}\!\left[\sum_{k=0}^{n-t} v^{k}\,\big(B_{t+k} + E_{t+k} - P_{t+k}\big)\right],

and if the discount factors vkv^{k} or the scenario draws shift between two runs of the same input, the number is no longer reproducible and the filing is no longer defensible. Every run therefore pins its random seed, records it in the audit payload, and validates the resulting reserve against the rule matrix before anything is written downstream.

import numpy as np

def stochastic_reserve(cash_flows: np.ndarray,
                       discount_factors: np.ndarray,
                       cte_level: float = 0.70) -> float:
    """CTE(70) reserve over a scenario x time cash-flow matrix.

    cash_flows: shape (n_scenarios, n_periods), benefit - premium per period.
    discount_factors: shape (n_periods,), scenario-consistent v**k.
    """
    pv_by_scenario = cash_flows @ discount_factors        # (n_scenarios,)
    worst = np.sort(pv_by_scenario)[::-1]                 # descending losses
    tail_count = int(np.ceil((1 - cte_level) * worst.size))
    return float(worst[:tail_count].mean())               # mean of worst tail

Phase 4 — Compliance Evaluation Engine

With validated output and executed scenarios in hand, the compliance evaluation engine applies the rule matrix and produces the single artifact everything else depends on: a hash-sealed pass/fail record. This is where statutory citations, actual metric values, and cryptographic fingerprints converge. The engine never mutates the model output; it observes it, evaluates it, and emits an immutable record — the design principle expanded in Actuarial Audit Trail Architecture.

import hashlib
import json
from datetime import datetime, timezone
from typing import Any, Dict, List

def evaluate_compliance(valuation: Dict[str, Any],
                        rules: List[ComplianceRule]) -> Dict[str, Any]:
    """Validate one valuation record against the rule matrix and seal it."""
    input_hash = hashlib.sha256(
        json.dumps(valuation, sort_keys=True, default=str).encode()
    ).hexdigest()

    violations = []
    for rule in rules:
        value = valuation.get(rule.metric_name)
        if value is None:
            continue
        if not (rule.min_threshold <= value <= rule.max_threshold):
            violations.append({
                "rule_id": rule.rule_id,
                "citation": rule.regulatory_citation,
                "component": rule.pipeline_component,
                "actual": value,
                "bounds": (rule.min_threshold, rule.max_threshold),
                "severity": rule.severity,
            })

    record = {
        "evaluation_id": hashlib.sha256(
            f"{valuation['policy_id']}{input_hash}".encode()
        ).hexdigest(),
        "evaluated_at": datetime.now(timezone.utc).isoformat(),
        "input_hash": input_hash,
        "violations": violations,
        "status": "FAIL" if any(
            v["severity"] == "CRITICAL" for v in violations
        ) else "PASS",
    }
    return record

The status gate is deliberately conservative: any CRITICAL breach fails the record outright and routes it to the exception queue, while WARNING and INFO findings are retained for reviewer context without blocking a clean submission. Binding the input_hash into the evaluation_id means the record is cryptographically tied to the exact bytes that produced it — change one input and the identity changes, which is exactly the tamper-evidence an examiner expects.

Phase 5 — Filing Assembly & Data Security

The final phase assembles passing records into a submission package and ships it to a state or federal portal. Because that package carries policyholder data and proprietary model parameters, it is governed by strict Data Security & PII Boundaries for Filing Systems: direct identifiers are tokenized, reserve fields are encrypted at the field level, and validation workers never persist raw PII. Non-essential identifiers are stripped before transmission so the filing satisfies both actuarial confidentiality standards and data-protection statutes.

Assembly is also deadline-bound. VM-20 filings, LICAT returns, and IFRS 17 disclosures all land on fixed dates, and a missed date is itself a compliance event. Automating that clock — the pattern in Automating NAIC Filing Deadline Alerts in Python — turns the deadline from a calendar reminder into a monitored SLA with escalation.

Assumption Governance

A filing is only as defensible as the assumptions beneath it. Mortality, lapse, and interest assumptions must be selected from credible experience, documented with an effective date and source authority, and linked to the experience study that justifies them. Under VM-20 the prudent estimate is the anticipated experience plus a margin for adverse deviation, and both the anticipated basis and the margin must be traceable to data — not asserted.

The governance boundary is enforced by the same threshold machinery used downstream. Drift in an assumption is caught before it reaches the projection engine by Dynamic Threshold Tuning for Assumption Drift, and every assumption set carries immutable metadata: version hash, approver, effective date, and the regulatory citation it maps to. This is what lets a reviewer reconstruct the exact assumption state behind any historical filing, and it is why assumption governance is treated as a first-class stage of the compliance architecture rather than an input to it.

Assumption governance lifecycle with a drift-threshold gate Experience study to prudent-estimate selection (anticipated plus margin for adverse deviation) to a versioned, hashed assumption set, then through a drift-threshold gate into the projection engine — the gate catches assumption drift before it reaches the reserve and capital run. Experience study credible mortality / lapse data Prudent-estimate selection anticipated + MfAD margin Versioned assumption set hash · approver · effective date Δ drift-threshold gate Projection engine reserve & capital run
Every assumption set carries immutable metadata; the drift gate catches a shifting basis before it reaches the projection engine.

Regulatory Audit Trail Requirements

An audit trail is the difference between “the model says 1.2” and “here is the sealed, reproducible evidence that the model computed 1.2 from these inputs, with this seed, under this rule version, at this time.” Examiner-ready evidence has three structural requirements:

  1. Cryptographic data lineage. Every input, intermediate, and output is fingerprinted with a content hash, and records are chained so that altering any earlier record invalidates every later one. The concrete WORM-storage and hash-chaining patterns are detailed in Building Secure Audit Logs for Regulatory Submissions.
  2. Immutable, append-only logs. Audit records are never updated in place. A correction is a new record that references the superseded one, preserving the full history an examiner may reconstruct.
  3. An examiner-ready package structure. The submission bundles the actuarial memorandum, the rule-matrix version, the assumption set hashes, the scenario seeds, and the sealed evaluation records into a single navigable artifact, so effective challenge does not require access to the running system.

Together these satisfy the reproducibility and outcomes-analysis expectations of SR 11-7 and the independent-validation expectations of OSFI E-23, walked through concretely in the Step-by-Step OSFI Model Validation Checklist for Life Insurers.

Failure Modes & Operational Risk

Compliance pipelines fail in a small number of characteristic ways, and each has a known mitigation. Designing for these before they occur is what separates a system that passes examination from one that merely passes on a good day.

  • Seed non-determinism. An unpinned or globally-mutated RNG makes the stochastic reserve irreproducible. Mitigation: pin per-run seeds, record them in the audit payload, and assert reproducibility in CI against a golden dataset.
  • Schema drift. An upstream extract silently adds, renames, or re-types a column, and validation either crashes or — worse — coerces silently. Mitigation: strict Pydantic models with no implicit coercion, plus Great Expectations checkpoints that fail the run on a contract breach.
  • Memory exhaustion. A full stochastic run over millions of policies and thousands of scenarios blows the heap. Mitigation: chunked, vectorized projection and streaming aggregation rather than materializing the full scenario cube.
  • Stale rule matrix. A regulatory bulletin tightens a threshold but the deployed matrix lags. Mitigation: treat the rule matrix as a versioned artifact, default to the most recent verified snapshot, and alert compliance officers when a newer version is available.
  • Filing-deadline miss. The clock is the risk. Mitigation: monitored SLAs with escalation, idempotent retries with backoff, and circuit breakers that queue rather than duplicate a submission when a portal is unavailable.

Every fallback state is logged with an explicit deviation flag, so an examiner asking “what happened on the day the portal was down” gets a precise, timestamped answer rather than a silence.

Compliance Mapping Table

The table below is the compact form of the traceability graph — the mapping every examiner ultimately wants: from a regulation, to the pipeline component that enforces it, to the concrete implementation artifact that proves it.

Regulation Pipeline component Implementation artifact
VM-20 Section 4 (deterministic reserve) deterministic_reserve_validator Rule-matrix row VM20-DR-01, sealed evaluation record
VM-20 Section 5 (stochastic reserve, CTE70) stochastic_reserve_validator Scenario seed log + CTE(70) computation + hash
VM-20 Section 9 (assumptions & margins) Assumption governance gate Versioned assumption set, experience-study link
OSFI E-23 Principle 4 (independent validation) Validation checklist runner OSFI validation checklist evidence bundle
LICAT (yield-curve shocks) Scenario execution engine Prescribed-curve calibration + reproducible run
IFRS 17 (discount-rate unlocking) Measurement transform Unlocking calculation record + audit chain
SR 11-7 (model inventory & lineage) Audit-trail service Hash-chained, append-only WORM log
Data-protection statutes Filing assembly + PII boundary Tokenized identifiers, field-level encryption

Up: Actuarial Validation & Filing Automation — the home for regulatory filing automation, assumption validation, and model ingestion workflows.