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:
- Runs (or has an analyst run) the scenario matrix against the client's real portfolio
and hazard data, and requests the
orsapack. - 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.
- Incorporates the physical-risk figures into the ORSA climate chapter alongside a transition-risk assessment sourced elsewhere — the platform does not attempt that half.
- 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.