Skip to content

ORSA climate module

The scenario-shaped physical-risk report pack for the EU insurer ORSA climate chapter — the first product wave defined in docs/plan/exploration/02-personas.md. This page states what the module is, what it deliberately is not, and how a consultant or actuary would use it to complete a filing. Read this before demoing it — it is the page a prospective user reads first, and it is written to not oversell.

What it is

A completed scenario-matrix batch (scenarios × horizons, run against one portfolio) can be composed into a single, provenance-cited PDF — the orsa report template (src/climate_lama/core/reports/orsa.py, src/climate_lama/core/reports/templates/orsa_report.html, rendered by render_report(batch_id, template="orsa") per ADR-039). The pack contains:

  • A cover page with an explicit scope box, and a "basis of preparation" section
  • An executive-summary grid: EAD/AAI per scenario × horizon, with each cell's realized EIOPA branch
  • A horizon-comparison chart and an exceedance-probability panel per scenario/horizon
  • A methodology section that cites EIOPA scenario mapping rather than restating it, plus a per-cell reproducibility stamp (engine, version, dataset checksums, curve version)
  • An assumptions annex and an attribution annex (one entry per distinct hazard footprint the batch actually used)

Every claim the pack makes about EIOPA is quoted verbatim from the sources recorded in EIOPA scenario mapping — no article numbers, no invented requirement wording. The perils and datasets behind the numbers are documented in Greek historical catalog (historical) and EIOPA scenario mapping (scenario-conditioned).

Positioning, per the exploration track: this is the first sellable unit of the ORSA climate module, sized to "sidestep both validation gates" (earthquake coverage, per-asset granularity) by staying portfolio-level and climate-only. The realistic buyer is the actuarial-consultancy channel, not a self-serve insurer purchase — see docs/plan/exploration/02-personas.md.

What it is NOT

Physical-risk module only. Transition risk — policy, legal, technology, market and reputational exposure from the shift to a lower-carbon economy — is not modelled anywhere in the pack. Every rendered document states this on the cover, in the basis of preparation, and again in the assumptions annex, so a reader entering at any point learns it. This is an input to an ORSA climate chapter, never a complete one.

Score bands are self-set v1, behind a feature flag, pending review. Where a banded 1–10/RAG score appears anywhere in the platform, its thresholds are self-set from published ordinal scales — not a supervisory or industry-standard classification — and ship behind score_bands_enabled (default False, ADR-043, issue #375). No banded output reaches a payload until an operator deliberately opts in, and the ORSA pack's own assumptions annex flags this with a literal [ASSUMPTION] basis wherever it applies.

Historical peril coverage is river-flood only. The full-Greece historical catalog currently ingests river flood only; national wildfire and windstorm footprints are a documented, verified gap (no publicly, anonymously redistributable source was found for either — see Greek historical catalog) tracked as issue #412. The scenario-conditioned mapping in EIOPA scenario mapping evaluated more perils than it ingested — river flood is the only one with a verified, scenario-conditioned, anonymously downloadable footprint source; wildfire and windstorm are gaps there too, for the same sourcing reasons. Every rendered pack states exactly which perils it covers in its assumptions annex — never silently.

REST composes and downloads the pack; no SDK wrapper or UI yet. The render pipeline (render_report(batch_id, template="orsa"), tests/test_core/test_orsa_report.py, tests/test_worker/test_render_report.py, tests/test_core/test_report_gather_matrix.py) is wired to REST (issue #415) alongside the single-result routes in src/climate_lama/api/v1/reports.py: POST /v1/compute/impact/matrix/{batch_id}/report queues a render (202 + job_id, poll GET /v1/jobs/{job_id}), then GET /v1/compute/impact/matrix/{batch_id}/report serves the stored PDF (404 E_REPORT_NOT_RENDERED until a render completes). Both still 422/404 the same way POST /v1/results/{id}/report does for a mismatched template or an unknown/wrong-kind subject — see _resolve_matrix_report_template and _load_batch_or_404 in src/climate_lama/api/v1/compute.py. scripts/orsa_report_demo.py is a thin HTTP client against these two routes — see the walkthrough. What is still missing is a Python SDK wrapper method (client.reports...) and a UI download button; both are tracked as fast follows now that the routes exist.

The tracked matrix batch resolves a hazard dataset per cell (issue #420). POST /v1/compute/impact/matrix resolves each cell's own hazard dataset from its scenario_label/horizon_year against the catalog — the request's hazard_dataset_id only supplies the hazard type and region every cell resolves within (see the endpoint's own docstring in src/climate_lama/api/v1/compute.py and core.compute_batch_service.resolve_matrix_cell_datasets). A cell whose scenario/horizon has no matching dataset in the org is not silently computed against the request's dataset — it is recorded with job_id: null and a per-cell error_message, the same never-blocks-the-batch posture as a cell whose dispatched job later fails. Producing a batch whose cells are genuinely scenario-differentiated requires hazard datasets ingested per scenario × horizon (see scripts/ingest_scenario_hazards.py, issue #386, which now also records each dataset's supported_years so the matrix endpoint can tell one horizon's dataset apart from another's). The seeded demo stack only ingests one historical, baseline-scenario dataset, so a matrix run against it there resolves the baseline column and reports the other scenario columns as absent — the walkthrough below is explicit about that.

Demo seeder gap. scripts/seed_demo.py does not currently create Assets, portfolio membership, or admin boundaries (issue #405). That does not block this pack — it only needs an exposure dataset and a hazard dataset, both of which the seeder does provide — but it does mean the platform's asset- or portfolio-level views cannot be demoed against the seeded stack yet.

Private only. Nothing here is published to PyPI or any public repository. The Python SDK (sdk/python/) is likewise unpublished. The walkthrough and the SDK example both run against the private docker-compose.yml stack, never against a hosted environment.

No completeness claim. The pack states what was modelled and how, never what a filing is required to contain — no article numbers, no "must contain" language, anywhere in the rendered document (asserted in tests/test_core/test_orsa_report.py).

How a consultant/actuary completes the filing

The module produces the physical-risk half of an ORSA climate chapter — two EIOPA long-term scenarios × three horizons × one portfolio, documented and reproducible. It does not, and is not meant to, produce a filing on its own. In the consultant-channel positioning the exploration track lays out, the actuary or consultant:

  1. Runs (or has an analyst run) the scenario matrix against the client's real portfolio and hazard data, and requests the orsa pack.
  2. Reviews the pack's assumptions annex, scope statement, and per-cell reproducibility stamps before citing any figure — the annex names every proxy, gap, and self-set threshold so nothing is taken at face value.
  3. Incorporates the physical-risk figures into the ORSA climate chapter alongside a transition-risk assessment sourced elsewhere — the platform does not attempt that half.
  4. Owns the regulatory completeness judgment: the pack never claims to satisfy a specific supervisory expectation, so that judgment is the consultant's, not the platform's.

Buy less often than you might assume. docs/concepts/eiopa-scenario-mapping.md does not itself state a filing cadence — the "below-2°C / well-above-2°C" scenario requirement it quotes carries no EIOPA-stated frequency. The product-planning working assumption behind this module's positioning is that ORSA runs on a multi-year (often cited as roughly 3-year) cycle in practice rather than annually, with carve-outs for smaller insurers in some jurisdictions — see docs/plan/exploration/02-personas.md for that working assumption and the interview questions meant to confirm or correct it [ASSUMPTION]. If it holds, a pack rendered today is meant to stay the reference artifact for that undertaking's next cycle, not something re-run continuously — which is also why this platform makes no claim about when a given client needs a new one.

Try it