Skip to main content
Jira progress: loading…

GHG-ALIGN

GHG Scenario Alignment

1. Identity​

Loading identity…

Depends on module:

Canonical computation and modeling domain for ESG calculations, simulations, extrapolation, aggregation, normalization, and decision-grade metric synthesis. Provides governed, auditable compute services to other modules (e.g., Reporting, Risk, Net Zero, ZARA).
Domain:
computation-hub
Category:
analytics-modeling
Classification:
module
Lifecycle status:
active
Semver:
1.0.0
Introduced in:
v0.3
Governance
AI risk level:
high
Trust threshold policy:
—
Human review required:
true
Verifier involved:
false
Audit required:
true
Ownership
Primary owner:
Platform
Architecture board:
true
White-label allowed:
true
Entrypoints
Docs:
/computation-hub
UI:
/app/computation-hub
API:
/api/computation-hub
Dependencies
Modules
  • sis
  • input-hub
Unresolved tokens
  • BUME
  • SEM
  • VTE
Engines (declared)
  • DICE
  • DaVE
  • VTE
  • SEM
  • BUME
Micro-engines (from registry)
Micro-engines (declared)
None
Signals
USO
  • DATA.COMPUTATION
  • DATA.VALIDATION
  • DATA.EXTRAPOLATION
  • MODEL.SIMULATION
  • MODEL.UNCERTAINTY
CSI
  • CSI_COMPUTATION_HUB
SSSR tags
  • computation
  • modeling
  • simulation
  • monte-carlo
  • bayesian
  • extrapolation
  • aggregation
  • normalization
  • validation
  • mice
Workflows & Outputs
Workflows
  • MicroEngineRouting
  • RuleBasedComputeDispatch
  • ScenarioModeling
  • UncertaintyQuantification
  • AggregationAndRollups
  • NormalizationAndBenchmarking
  • ExtrapolationAndGapFilling
  • ComputeAuditAndReplay
Outputs
  • computed_metrics
  • scenario_ranges
  • confidence_intervals
  • normalized_values
  • validation_findings
  • trust_scored_compute_outputs
Audit
Ledger:
ALTD
Replay supported:
true
PII policy:
no_pii_in_omr
Tags


2. Executive Overview​

2.1. Purpose of GHG Scenario Alignment​

Purpose
Evaluates how closely an entity’s emissions trajectory aligns with a reference climate scenario (IPCC, IEA, SBTi, NGFS) and goal (e.g. 1.5°C, 2.0°C).

This engine represents the top of the GHG computation pyramid.

Typical usage

  • Alignment with IPCC / IEA pathways
  • Temperature score derivation
  • Inputs to transition-risk and strategy dashboards

Produces:

  • Alignment score
  • Distance/ratio/area metrics
  • Temperature score (optional)
  • Full governance metadata

Supports:

  • CSRD
  • ESRS E1
  • SBTi reporting
  • Climate transition risk modeling
  • Portfolio alignment

2. Purpose​

Evaluates how closely an entity’s emissions trajectory aligns with a reference climate scenario (IPCC, IEA, SBTi, NGFS).

Produces:

  • Alignment score
  • Distance/ratio/area metrics
  • Temperature score (optional)
  • Full governance metadata

Supports:

  • CSRD
  • ESRS E1
  • SBTi reporting
  • Climate transition risk modeling
  • Portfolio alignment

3. Contract Schemas (ZAR)​

All inputs and outputs MUST conform to ZAR-registered schemas.

3.1. Input Schema​

ZAR Address:

schema.compute.ghg.scenario.inputs.v1_0_0

Required:

  • emissions (time series)
  • scenario_curve_ref OR resolution inputs
  • alignment_metric (DISTANCE | RATIO | AREA)
  • alignment (BY_YEAR)

Optional:

  • scope
  • start_year
  • end_year
  • sector_key
  • region
  • tempTarget

3.2. Options Schema​

ZAR Address:

schema.compute.ghg.scenario.options.v1_0_0

Options:

  • normalization (NONE | BASE_YEAR)
  • temperature_mapping_ref
  • exceedance_policy (ALLOW | CLIP)
  • rounding
  • ensemble_policy (MEDIAN | P33 | P67)

3.3. Output Schema​

ZAR Address:

schema.compute.ghg.scenario.output.v1_0_0

Output MUST include:

alignment_score
distance_series
temperature_score (optional)
metadata

4. Architectural Principles (Normative)​

4.1. Separation of Concerns (MANDATORY)​

The engine MUST strictly separate:

  1. Scenario Resolution
  2. Provider Selection
  3. License Validation
  4. Region Fallback
  5. Variable Harmonization
  6. Alignment Mathematics

Alignment mathematics MUST NOT perform provider selection logic.

Violation of this rule invalidates audit guarantees.


5. Scenario Resolution Architecture​

Scenario resolution occurs before alignment.

Inputs:

  • sector_key
  • region
  • temperature target
  • canonical_variable_key

Outputs:

  • scenario artifact (fully resolved)

6. Sector-Priority Policy (Normative)​

6.1. Policy Artifact​

Scenario resolution MUST be governed by:

scenario_align.policy.vX.json

Artifact MUST be:

  • Versioned
  • Hashable
  • Immutable once published
  • Audit-referenceable

Defines:

  • provider precedence
  • region ladder
  • sector defaults
  • metric defaults
  • quality ranking

6.2. Provider Order​

Example:

"preferred_order": ["IEA","SBTi","NGFS","IPCC"]

Rules:

  1. Providers MUST be attempted in declared order.
  2. Dynamic reordering is forbidden.
  3. Policy version MUST be recorded in metadata.

7. License-Gated Provider Resolution​

The engine MUST call:

LicenseService.check(clientId, provider, purpose="analytics")

The engine MUST NOT inspect license flags directly.

Resolution algorithm:

  1. Load provider order from policy.
  2. For each provider:
  • Check license
  • If granted → attempt resolution
  • If denied → skip
  1. If none available:
  • Fallback to IPCC baseline
  1. If still unresolved:
  • Raise SCENARIO_PROVIDER_UNAVAILABLE

7.1. Mandatory Metadata​

metadata.selection = {
policy_version,
providers_tried,
provider_selected,
license_status,
region_used,
metric_used
}

Required for:

  • CSRD defensibility
  • External assurance
  • Federation reproducibility

8. Region Ladder Resolution​

Default ladder:

COUNTRY → EU27 → OECD → GLOBAL

Rules:

  1. Attempt country.
  2. If unavailable, escalate.
  3. First valid match MUST be selected.
  4. Ladder steps MUST be recorded.

If adjustment factors exist:

  • Apply AFTER region fallback.
  • Record adjustment in metadata.

9. Canonical Variable Resolution​

All scenario artifacts MUST expose:

canonical_variable_key

Examples:

  • gco2_per_kwh
  • tco2_per_t_steel
  • co2_total_gt_per_year

Provider adapters MUST map external variable names to canonical keys.

Mappings MUST be versioned in EngineAliasMap.


10. Metric Harmonization​

If company metric ≠ scenario metric:

Conversion MUST occur before alignment.

Rules:

  • Absolute ↔ Intensity conversions MUST be deterministic.
  • Derivations MUST be logged.
  • All transformations MUST be reproducible.

11. Scope Handling​

Supported:

  • TOTAL
  • SCOPE1+2
  • SCOPE1+2+3

If scope not provided:

  • Engine MUST default to sector-defined scope from NACE metadata.

Scope used MUST be recorded.


Absolutely — here’s a production-ready rewrite of Section 12 that’s tighter, less repetitive, and gives engineers exactly what to implement. It also cleanly replaces the old 4.5.1 without duplicating it.


12. IPCC Ensemble Construction (Normative)​

When the selected provider is IPCC (AR6 IAM pathways), the engine MUST resolve scenario curves by constructing an ensemble time-series from vetted IAM rows.

12.0. Inputs and Outputs​

Inputs (minimum):

  • scenario_class (derived from tempTarget, e.g. C1 for 1p5C, C3 for 2C)
  • canonical_variable_key
  • region_resolved (after region ladder)
  • years (horizon)
  • ensemble_policy (MEDIAN default; optional P33, P67)

Output (resolved scenario artifact MUST include):

  • series: [[year, value], ...] for ensemble statistic(s)
  • ensemble_meta: provenance + traceability block (see 12.3)

12.1. Scenario Class Routing (Normative)​

IPCC alignment MUST use AR6 category codes (C1–C7) to route temperature intent:

  • 1p5C → C1 (no/limited overshoot)
  • 2C → C3 (well-below 2°C)

The class routing MUST be deterministic and versioned (policy or engine mapping).


12.2. Row Selection Rules (Normative)​

The engine MUST select candidate rows from the IPCC scenario store using the following filters: 1. Class filter Select only rows where category_code == scenario_class. 2. Vetting filter (default = strict) Rows MUST be vetted (e.g., category_vetting_historical == true or equivalent vetted flag).

  • Non-vetted rows MUST be excluded unless options.allow_non_vetted = true. 3. Region filter Select rows matching the resolved region.
  • If the IPCC dataset is global-only for the requested variable, the engine MUST treat region as GLOBAL and record this in metadata. 4. Variable filter Only include rows that map to the requested canonical_variable_key.
  • Variable mapping MUST be resolved via EngineAliasMap (versioned). 5. Year coverage requirement Candidate rows MUST cover the requested horizon.
  • If partial coverage exists, the engine MUST either:
  • (a) truncate to overlapping years, or
  • (b) error with SCENARIO_NO_OVERLAP, depending on engine option options.year_policy. 6. Minimum ensemble size If fewer than min_models_required rows remain (default: 3), the engine MUST return SCENARIO_PROVIDER_UNAVAILABLE (or a more specific IPCC_ENSEMBLE_TOO_SMALL) and include counts in the error payload.

12.3. Ensemble Construction Rules (Normative)​

For each (year, canonical_variable_key, region_resolved):

  1. Collect values across all selected IAM rows.
  2. Compute MEDIAN (mandatory).
  3. If requested and available, compute P33 and/or P67.
  4. Construct the ensemble series as:
{
"ensemble": "median",
"canonical_variable_key": "gco2_per_kwh",
"unit": "gCO2/kWh",
"series": [[2025, 320.0], [2030, 180.0], ...]
}

Determinism requirements:

  • Sorting of models MUST be stable (e.g., lexical by model, then scenario) before any aggregation.
  • The ensemble MUST be reproducible given identical dataset version + filters.

12.4. Output Traceability Requirements (Normative)​

The resolved IPCC scenario artifact MUST include an audit block sufficient to reproduce the ensemble externally:

"ensemble_meta": {
"scenario_class": "C1",
"ensemble_policy": ["MEDIAN","P33","P67"],
"models_used": ["REMIND-MAgPIE","GCAM","WITCH-GLOBIOM"],
"model_count": 3,
"source_rows_ref": ["<row_id_1>","<row_id_2>","<row_id_3>"],
"dataset_ref": "ipcc_ar6_vetted_withclimate_short",
"dataset_version": "2024.0",
"dataset_checksum": "sha256:...",
"filters_applied": {
"vetted_only": true,
"region": "EU27",
"canonical_variable_key": "gco2_per_kwh",
"years": [2025,2050]
}
}

Additionally:

  • If available in the selected rows, the engine MUST propagate exceedance probabilities into metadata:
    • p_exceed_1p5c_*, p_exceed_2c_* (and emulator cross-checks if present)
  • Row-level lineage MUST be reconstructible (via source_rows_ref or equivalent).

12.5. Error Conditions (Normative)​

The engine MUST raise structured errors with context:

  • IPCC_VARIABLE_RESOLUTION_FAILED
  • IPCC_NO_ROWS_MATCH
  • IPCC_ENSEMBLE_TOO_SMALL
  • SCENARIO_NO_OVERLAP

Errors MUST include:

  • scenario_class
  • canonical_variable_key
  • region_resolved
  • vetted_only
  • candidate_row_count
  • selected_row_count
  • dataset_version/checksum

13. Alignment Mathematics (Normative)​

Let:

  • E(t)E(t) = company emissions at year tt
  • S(t)S(t) = scenario emissions at year tt
  • Horizon defined as t∈[t0,tn]t \in [t_0, t_n]
  • nn = number of years in the overlapping horizon

All alignment metrics MUST be computed only on the overlapping year domain after scenario resolution and normalization.


13.1. Distance Metric (Default)​

Per-year distance:

d(t)=E(t)−S(t)d(t) = E(t) - S(t)

Aggregate alignment score:

D=1n∑t=t0tnd(t)D = \frac{1}{n} \sum_{t=t_0}^{t_n} d(t)

Properties:

  • Positive DD indicates average exceedance.
  • Negative DD indicates average underperformance (below pathway).
  • Units preserved from input metric.

13.2. Ratio Metric​

Per-year ratio:

r(t)=E(t)max⁡(S(t),ϵ)r(t) = \frac{E(t)}{\max(S(t), \epsilon)}

Where:

  • ϵ\epsilon is a small positive constant to prevent division by zero.

Aggregate ratio score:

R=1n∑t=t0tnr(t)R = \frac{1}{n} \sum_{t=t_0}^{t_n} r(t)

Properties:

  • R=1.0R = 1.0 → perfect alignment.
  • R>1.0R > 1.0 → exceedance.
  • R<1.0R < 1.0 → outperforming scenario.

13.3. Area Metric (Cumulative Overshoot)​

Cumulative exceedance over horizon:

A=∑t=t0tnmax⁡(0,E(t)−S(t))A = \sum_{t=t_0}^{t_n} \max(0, E(t) - S(t))

Properties:

  • Only positive exceedance is accumulated.
  • Units match emissions metric.
  • Represents total overshoot across horizon.
  • Sensitive to horizon length (non-normalized).

13.4. Horizon Determination Rules (Normative)​

%reduction_required_2030 = 1 − (pathway_2030 / entity_2024)

Reduction Logic:

R2030=1−S(2030)E(2024)R_{2030} = 1 - \frac{S(2030)}{E(2024)}

Absolute reduction:

ΔE2030=E(2024)−S(2030)\Delta E_{2030} = E(2024) - S(2030)


13.5. Cumulative Budget Overshoot​

Σ emissions 2025–2050 vs integrated pathway

Budgetentity=∑t=20252050E(t)Budget_{entity} = \sum_{t=2025}^{2050} E(t)

Budgetpathway=∑t=20252050S(t)Budget_{pathway} = \sum_{t=2025}^{2050} S(t)

Overshoot=Budgetentity−BudgetpathwayOvershoot = Budget_{entity} - Budget_{pathway}


13.6. Temperature Score Mapping​

  1. Derive implied annual reduction rate:

r=E(t1)−E(t2)E(t1)r = \frac{E(t_1) - E(t_2)}{E(t_1)}

  1. Map to temperature via provider-specific function:

T=fprovider(r,sector)T = f_{provider}(r, sector)

And require:

  • mapping functions versioned
  • deterministic
  • provider-dependent

13.7. Horizon Determination Rules (Normative)​

The effective horizon MUST be:

[t0,tn]=intersection of emissions and scenario year domains[t_0, t_n] = \text{intersection of emissions and scenario year domains}

If intersection is empty: → Raise SCENARIO_NO_OVERLAP

If partial overlap:

  • Either truncate (default)
  • Or error if options.year_policy = STRICT

Horizon MUST be recorded in metadata:

"alignment_horizon": {
"start": 2025,
"end": 2050,
"n_years": 26
}

14. Normalization​

If BASE_YEAR normalization:

  • Normalize E(t)E(t) and S(t)S(t) to 1.0 at base year.
  • Compute alignment on normalized curves.

Metadata MUST record:

  • base year
  • normalization applied

15. Temperature Mapping​

If temperature_mapping_ref provided:

  • Map alignment score to implied temperature
  • Mapping MUST be deterministic
  • Mapping MUST be versioned

16. Error Model (Production Registry)​

Engine MUST use structured error codes:

  • SCENARIO_PROVIDER_UNAVAILABLE
  • LICENSE_DENIED
  • REGION_FALLBACK_FAILED
  • VARIABLE_RESOLUTION_FAILED
  • METRIC_TYPE_MISMATCH
  • SCENARIO_NO_OVERLAP
  • SCENARIO_NON_FINITE_VALUE

Errors MUST include:

  • provider attempted
  • policy_version
  • region ladder state
  • canonical_variable_key
  • execution_ref

17. Federation & Audit Requirements​

To reproduce externally, export MUST include:

  • MEID
  • Build hash
  • Execution reference
  • Input schema version
  • Options schema version
  • Scenario artifact
  • Policy artifact hash
  • Alignment metric
  • Normalization settings
  • Emissions trajectory

Provenance chain MUST show:

MEID_GHG_AGGR_AGGREGATION
→ MEID_GHG_CALC_BUDGET
→ MEID_GHG_PROJECT_ALIGNMENT

Rebuild MUST produce identical output.


18. Performance Characteristics​

  • Time Complexity: O(n)
  • Memory: O(n)
  • Suitable for long-horizon analysis (to 2100)
  • Designed for portfolio-scale batch execution

19. Compliance & Governance Alignment​

Engine supports:

  • CSRD Article 19a
  • ESRS E1
  • SBTi temperature scoring
  • NGFS portfolio alignment
  • Financial climate risk disclosures

20. Production Guarantees​

This engine guarantees:

  • Deterministic output
  • Provider auditability
  • License compliance
  • Region fallback transparency
  • Canonical variable integrity
  • Federation reproducibility
  • Strict architectural separation

Demo​

This micro-engine demonstrates:

  • SSOT policy artifact (provider fallback order + sector dictionary + defaults)
  • Strong typing (sectorKey union generated from policy JSON)
  • Query normalization (defaults injected + required-field validation)
  • Provider selection (policy chain + license gating)
  • Series output with audit metadata suitable for governance and reporting

Demo 1: Power generation (EU27), 1.5°C, 2025–2050​

Query
{
  "providerPolicy": [
    "IEA",
    "SBTi",
    "NGFS",
    "IPCC"
  ],
  "licenseFlags": {
    "iea": false
  },
  "preferredStat": "median",
  "includeUncertainty": "core",
  "interpolation": "linear",
  "sectorKey": "power_generation",
  "region": "EU27",
  "variable": "gco2_per_kwh",
  "tempTarget": "1p5C",
  "horizon": {
    "start": 2025,
    "end": 2050
  },
  "title": "Power generation decarbonization trajectory"
}
Selection metadata
Loading...
Loading chart...
Note: this demo uses a deterministic mock provider for documentation. Swap to real provider adapter for production.

Demo 2: Steel (GLOBAL), 2°C, 2025–2050​

Query
{
  "providerPolicy": [
    "IEA",
    "SBTi",
    "NGFS",
    "IPCC"
  ],
  "licenseFlags": {
    "iea": false
  },
  "preferredStat": "median",
  "includeUncertainty": "core",
  "interpolation": "linear",
  "sectorKey": "steel",
  "region": "GLOBAL",
  "variable": "tco2_per_t_steel",
  "tempTarget": "2C",
  "horizon": {
    "start": 2025,
    "end": 2050
  },
  "title": "Steel intensity trajectory"
}
Selection metadata
Loading...
Loading chart...
Note: this demo uses a deterministic mock provider for documentation. Swap to real provider adapter for production.

Governance notes​

  • The provider order is defined in the policy artifact (scenario_align.policy.v1.json)
  • The selected provider is recorded in metadata.selection.policyApplied
  • The policy artifact can be hashed and referenced for auditability in future reporting pipelines

Accompanying files: /workspaces/zayaz-docs/docusaurus/src/engines/ghg/scenario_align


APPENDIXES​


Appendix A — Reference Tables and Seeds (Production)​

A.1. seed_provider_policy.csv (Sector-Priority Policy)​

sector_key,preferred_order,region_ladder,temp_targets,metric_default,policy_profile,quality_rank,notes
autos.c29_1,"[IEA,SBTi,NGFS,IPCC]","[COUNTRY,EU27,EEA,GLOBAL]","[1p5C,2C]",intensity,default,4,"Use-phase intensity benchmark with fallbacks."
steel.c24_1,"[IEA,SBTi,NGFS,IPCC]","[COUNTRY,EU27,OECD,GLOBAL]","[1p5C,2C]",intensity,default,5,"Primary vs EAF handled by subsector/variant."
power_generation.d35,"[IEA,NGFS,IPCC]","[COUNTRY,EU27,GLOBAL]","[1p5C,2C]",intensity,default,5,"Grid intensity is canonical variable."

A.2. seed_region_ladder.csv​

sector_key,region_from,region_to,order
autos.c29_1,ISO2,EU27,1
autos.c29_1,ISO2,EEA,2
autos.c29_1,ISO2,GLOBAL,3
autos.c29_1,EU27,GLOBAL,4
autos.c29_1,EEA,GLOBAL,5

A.3. seed_variable_mapping_autos.csv (minimal end-to-end)​

sector_key,variable_key,description,units,aggregation,scope,notes
autos.c29_1,gco2_per_km_passenger,"WTW passenger vehicle intensity (fleet avg)","gCO2/km",as_is,S3,"Primary alignment variable."
autos.c29_1,grid_intensity_gco2_per_kwh,"Grid intensity for BEV/PHEV conversion","gCO2/kWh",as_is,S2,"Used when deriving BEV use-phase."
autos.c29_1,pkm_total,"Passenger-km activity (road)","billion pkm/yr",median,Total,"Used if intensity must be derived from totals."
autos.c29_1,co2_transport_total,"Total transport CO2","MtCO2/yr",median,Total,"Backstop / reconstruction."

Appendix B — dbt Models / Views (Contracts)​

B.1. Effective policy view​

models/scenario_policy/provider_policy_effective.sql

select
sector_key,
preferred_order,
region_ladder,
temp_targets,
metric_default,
policy_profile,
quality_rank
from {{ ref('seed_provider_policy') }};

B.2. NACE alignment defaults view (exact JSON for adapter)​

models/nace/vw_nace_alignment_defaults.sql

select
n.sector_key,
n.nace_code,
jsonb_build_object(
'sectorKey', n.sector_key,
'naceCode', n.nace_code,
'policyProfile', coalesce(n.policy_profile, p.policy_profile),
'qualityRank', coalesce(n.quality_rank, p.quality_rank),
'providerOrder', p.preferred_order,
'regionLadder', coalesce(n.region_ladder_override, p.region_ladder),
'tempTargets', coalesce(n.default_temp_targets, p.temp_targets),
'metricDefault', coalesce(n.default_metric, p.metric_default),
'variables', coalesce(n.variable_keys, '[]'::jsonb),
'intensity', jsonb_build_object(
'denominatorKey', n.intensity_denominator_key,
'units', n.intensity_units,
'activityUnits', n.activity_units
)
) as adapter_payload
from {{ ref('dim_nace_codes') }} n
join {{ ref('provider_policy_effective') }} p
on p.sector_key = n.sector_key;

B.3. Materialized version + indexes​

models/nace/mv_nace_alignment_defaults.sql

{{ config(materialized='materialized', indexes=[
{'columns': ['sector_key']},
{'columns': ['nace_code']},
{'columns': ['adapter_payload'], 'type': 'gin'}
]) }}

select * from {{ ref('vw_nace_alignment_defaults') }};

Result: adapter can query one row per NACE and get the JSON blob it needs.


Appendix C — License Module Integration (Production Contract)​

C.1. License check response shape (minimum)​

type LicenseDecision = {
provider: "IEA"|"SBTi"|"NGFS"|"IPCC";
result: "granted"|"denied";
entitlementRef?: string; // artifact id / subscription id
checksum?: string; // immutability proof
checkedAt: string; // ISO timestamp
reason?: string; // human-readable
}

C.2. Provider selection MUST log tried providers​

type ProviderSelectionLog = {
policyVersion: string;
policyProfile: string;
providersTried: Array<{provider: string; decision: "granted"|"denied"}>;
providerSelected: string;
regionUsed: string;
regionPathTried: string[];
canonicalVariableKey: string;
}

Appendix D — Provider Selection Flow (TS Skeleton)​

import { LicenseService } from "@zayaz/licensing";

type Provider = "IEA" | "SBTi" | "NGFS" | "IPCC";

export async function pickProvider(ctx: {
clientId: string;
sectorKey: string;
region: string;
tempTarget?: "1p5C"|"2C";
metric?: "absolute"|"intensity";
canonicalVariableKey: string;
policy: {
preferred_order: Provider[];
region_ladder: string[];
temp_targets: ("1p5C"|"2C")[];
metric_default: "absolute"|"intensity";
policy_version: string;
policy_profile: string;
};
}) {
const tried: Array<{provider: Provider; decision: "granted"|"denied"}> = [];

for (const provider of ctx.policy.preferred_order) {
const decision = await LicenseService.check({
clientId: ctx.clientId,
provider,
purpose: "analytics",
sectorKey: ctx.sectorKey
});

tried.push({ provider, decision: decision.result });

if (decision.result === "granted") {
return { provider, license: decision, tried };
}
}

// if policy didn't include IPCC, allow public baseline
if (!ctx.policy.preferred_order.includes("IPCC")) {
return {
provider: "IPCC" as const,
license: { provider: "IPCC", result: "granted", entitlementRef: "public", checkedAt: new Date().toISOString() },
tried
};
}

throw new Error(`SCENARIO_PROVIDER_UNAVAILABLE: tried=${JSON.stringify(tried)}`);
}

Appendix E — Region Ladder Flow (Pseudo + Expected behavior)​

Algorithm

  1. Take requested region (ISO2/ISO3 if country).
  2. Walk ladder until a provider returns a series for (scenario, variable, region).
  3. Stop at first match (deterministic).

Example tried regions (autos)

NO → EU27 → EEA → GLOBAL

Metadata MUST record

  • regionUsed
  • regionsTried (in order)

Appendix F — Scenario Artifact Contract (Stored/Resolved)​

Minimum schema stored in ZAR registry:

{
"provider": "NGFS",
"scenarioId": "NetZero2050",
"temperatureIntent": "1p5C",
"region": "EU27",
"canonicalVariableKey": "gco2_per_kwh",
"metricType": "intensity",
"unit": "gCO2/kWh",
"series": [[2025, 320.0], [2030, 180.0], [2040, 70.0], [2050, 10.0]],
"version": "2025.1",
"provenanceHash": "sha256:..."
}

Appendix G — End-to-End Example Request/Response​

G.1. Request (adapter-resolved)**​

{
"clientId": "ECO-196-123-456-789",
"sectorKey": "autos.c29_1",
"region": "NO",
"tempTarget": "1p5C",
"canonicalVariableKey": "gco2_per_km_passenger",
"horizon": { "start": 2025, "end": 2050 },
"mode": "scoring",
"alignmentMetric": "DISTANCE",
"normalization": "BASE_YEAR"
}

G.2. Response (includes audit block)**​

{
"alignmentScore": 0.82,
"distanceSeries": [[2025,0.0],[2030,12.4],[2040,8.1],[2050,1.2]],
"metadata": {
"selection": {
"policyVersion": "1.0.0",
"policyProfile": "default",
"providersTried": [{"provider":"IEA","decision":"denied"},{"provider":"SBTi","decision":"granted"}],
"providerSelected": "SBTi",
"regionsTried": ["NO","EU27","GLOBAL"],
"regionUsed": "EU27",
"canonicalVariableKey": "gco2_per_km_passenger",
"metricUsed": "intensity"
},
"scenarioArtifactRef": "zar:scenario/SBTi/Transport_SDA_1p5/v2024.0",
"normalization": { "type": "BASE_YEAR", "baseYear": 2025 }
}
}

Appendix H — “What programmers implement first” checklist​

Phase 0 (Dev E2E)

  • Seed tables: provider policy, region ladder, autos variable mapping
  • vw_nace_alignment_defaults (or materialized mv_*)
  • pickProvider() wired to License Module
  • Provider adapters stubbed: return mock series per provider
  • Scenario artifact resolution stub (by ref or query)
  • Output metadata block exactly as spec

Phase 1 (Real data)

  • IEA adapter reads licensed dataset
  • NGFS adapter reads NGFS pathways store
  • SBTi adapter reads SDA curves store
  • IPCC adapter builds ensembles from IAM rows
  • Variable canonicalization + unit normalization





GitHub RepoRequest for Change (RFC)