mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* feat(resilience): PR 3 §3.5 — retire fuelStockDays from core score permanently
First commit in PR 3 of the resilience repair plan. Retires
`fuelStockDays` from the core score with no replacement.
Why permanent, not replaced:
IEA emergency-stockholding rules are defined in days of NET IMPORTS
and do not bind net exporters by design. Norway/Canada/US measured
in days-of-imports are incomparable to Germany/Japan measured the
same way — the construct is fundamentally different across the two
country classes. No globally-comparable recovery-fuel signal can
be built from this source; the pre-repair probe showed 100% imputed
at 50 for every country in the April 2026 freeze.
scoreFuelStockDays:
- Rewritten to return coverage=0 + observedWeight=0 +
imputationClass='source-failure' for every country regardless
of seed content.
- Drops the dimension from the `recovery` domain's coverage-
weighted mean automatically; remaining recovery dimensions
pick up the share via re-normalisation in
`_shared.ts#coverageWeightedMean`.
- No explicit weight transfer needed — the coverage-weighted
blend handles redistribution.
Registry:
- recoveryFuelStockDays re-tagged from tier='enrichment' to
tier='experimental' so the Core coverage gate treats it as
out-of-score.
- Description updated to make the retirement explicit; entry
stays in the registry for structural continuity (the
dimension `fuelStockDays` remains in RESILIENCE_DIMENSION_ORDER
for the 19-dimension tests; removing the dimension entirely is
a PR 4 structural-audit concern).
Housekeeping:
- Removed `RESILIENCE_RECOVERY_FUEL_STOCKS_KEY` constant (no
longer read; noUnusedLocals would reject it).
- Removed `RecoveryFuelStocksCountry` interface for the same
reason. Comment at the removed declaration instructs future
maintainers not to re-add the type as a reservation; when a
new recovery-fuel concept lands, introduce a fresh interface.
Plan reference: §3.5 point 1 of
`docs/plans/2026-04-22-001-fix-resilience-scorer-structural-bias-plan.md`.
51 resilience tests pass, typecheck + biome clean. The
`recovery` domain's published score will shift slightly for every
country because the 0.10 slot that fuelStockDays was imputing to
now redistributes; the compare-harness acceptance-gate rerun at
merge time will quantify the shift per plan §6 gates.
* feat(resilience): PR 3 §3.5 — retire BIS-backed currencyExternal; rebuild on IMF inflation + WB reserves
BIS REER/DSR feeds were load-bearing in currencyExternal (weights 0.35
fxVolatility + 0.35 fxDeviation, ~70% of dimension). They cover ~60
countries max — so every non-BIS country fell through to
curated_list_absent (coverage 0.3) or a thin IMF proxy (coverage 0.45).
Combined with reserveMarginPct already removed in PR 1, currencyExternal
was the clearest "construct absent for most of the world" carrier left
in the scorer.
Changes:
_dimension-scorers.ts
- scoreCurrencyExternal now reads IMF macro (inflationPct) + WB FX
reserves only. Coverage ladder:
inflation + reserves → 0.85 (observed primary + secondary)
inflation only → 0.55
reserves only → 0.40
neither → 0.30 (IMPUTE.bisEer retained for snapshot
continuity; semantics read as
"no IMF + no WB reserves" now)
- Removed dead symbols: RESILIENCE_BIS_EXCHANGE_KEY constant (reserved
via comment only, flagged by noUnusedLocals), stddev() helper,
getCountryBisExchangeRates() loader, BisExchangeRate interface,
dateToSortableNumber() — all were exclusive callers of the retired
BIS path.
_indicator-registry.ts
- New core entry inflationStability (weight 0.60, tier=core,
sourceKey=economic:imf:macro:v2).
- fxReservesAdequacy weight 0.15 → 0.40 (secondary reliability
anchor).
- fxVolatility + fxDeviation demoted tier=enrichment → tier=experimental
(BIS ~60-country coverage; off the core weight sum).
- Non-experimental weights now sum to 1.0 (0.60 + 0.40).
scripts/compare-resilience-current-vs-proposed.mjs
- EXTRACTION_RULES: added inflationStability →
imf-macro-country-field field=inflationPct so the registry-parity
test passes and the correlation harness sees the new construct.
tests/resilience-dimension-scorers.test.mts
- Dropped BIS-era wording ("non-BIS country") and test 266
(BIS-outage coverage 0.35 branch) which collapsed to the inflation-
only path post-retirement.
- Updated coverage assertions: inflation-only 0.45 → 0.55; inflation+
reserves 0.55 → 0.85.
tests/resilience-scorers.test.mts
- domainAverages.economic 68.33 → 66.33 (US currencyExternal score
shifts slightly under IMF+reserves vs old BIS composite).
- stressScore 67.85 → 67.21; stressFactor 0.3215 → 0.3279.
- overallScore 65.82 → 65.52.
- baselineScore unchanged (currencyExternal is stress-only).
All 6324 data-tier tests pass. typecheck:api clean. No change to
seeders or Redis keys; this is a pure scorer + registry rebuild.
* feat(resilience): PR 3 §3.5 point 3 — re-goalpost externalDebtCoverage (0..5 → 0..2)
Plan §2.1 diagnosis table showed externalDebtCoverage saturating at
score=100 across all 9 probe countries — including stressed states.
Signal was collapsed. Root cause: (worst=5, best=0) gave every country
with ratio < 0.5 a score above 90, and mapped Greenspan-Guidotti's
reserve-adequacy threshold (ratio=1.0) to score 80 — well into "no
worry" territory instead of the "mild warning" it should be.
Re-anchored on Greenspan-Guidotti directly: ratio=1.0 now maps to score
50 (mild warning), ratio=2.0 to score 0 (acute rollover-shock exposure).
Ratios above 2.0 clamp to 0, consistent with "beyond this point the
country is already in crisis; exact value stops mattering."
Files changed:
- _indicator-registry.ts: recoveryDebtToReserves goalposts
{worst: 5, best: 0} → {worst: 2, best: 0}. Description updated to
cite Greenspan-Guidotti; inline comment documents anchor + rationale.
- _dimension-scorers.ts: scoreExternalDebtCoverage normalizer bound
changed from (0..5) to (0..2), with inline comment.
- docs/methodology/country-resilience-index.mdx: goalpost table row
5-0 → 2-0, description cites Greenspan-Guidotti.
- docs/methodology/indicator-sources.yaml:
* constructStatus: dead-signal → observed-mechanism (signal is now
discriminating).
* reviewNotes updated to describe the new anchor.
* mechanismTestRationale names the Greenspan-Guidotti rule.
- tests/resilience-dimension-monotonicity.test.mts: updated the
comment + picked values inside the (0..2) discriminating band (0.3
and 1.5). Old values (1 vs 4) had 4 clamping to 0.
- tests/resilience-dimension-scorers.test.mts: NO score threshold
relaxed >90 → >=85 (NO ratio=0.2 now scores 90, was 96).
- tests/resilience-scorers.test.mts: fixture drift:
* domainAverages.recovery 54.83 → 47.33 (US extDebt 70 → 25).
* baselineScore 63.63 → 60.12 (extDebt is baseline type).
* overallScore 65.52 → 63.27.
* stressScore / stressFactor unchanged (extDebt is baseline-only).
All 6324 data-tier tests pass. typecheck:api clean.
* feat(resilience): PR 3 §3.6 — CI gate on indicator coverage and nominal weight
Plan §3.6 adds a new acceptance criterion (also §5 item 5):
> No indicator with observed coverage below 70% may exceed 5% nominal
> weight OR 5% effective influence in the post-change sensitivity run.
This commit enforces the NOMINAL-WEIGHT half as a unit test that runs
on every CI build. The EFFECTIVE-INFLUENCE half is produced by
scripts/validate-resilience-sensitivity.mjs as a committed artifact;
the gate file only asserts that script still exists so a refactor that
removes it breaks the build loudly.
Why the gate exists (plan §3.6):
"A dimension at 30% observed coverage carries the same effective
weight as one at 95%. This contradicts the OECD/JRC handbook on
uncertainty analysis."
Implementation:
tests/resilience-coverage-influence-gate.test.mts — three tests:
1. Nominal-weight gate: for every core indicator with coverage < 137
countries (70% of the ~195-country universe), computes its nominal
overall weight as
indicator.weight × (1/dimensions-in-domain) × domain-weight
and asserts it does not exceed 5%. Equal-share-per-dimension is
the *upper bound* on runtime weight (coverage-weighted mean gives
a lower share when a dimension drops out), so this is a strict
bound: if the nominal number passes, the runtime number also
passes for every country.
2. Effective-influence contract: asserts the sensitivity script
exists at its expected path. Removing it (intentionally or by
refactor) breaks the build.
3. Audit visibility: prints the top 10 core indicators by nominal
overall weight. No assertion beyond "ran" — the list lets
reviewers spot outliers that pass the gate but are near the cap.
Current state (observed from audit output):
recoveryReserveMonths: nominal=4.17% coverage=188
recoveryDebtToReserves: nominal=4.17% coverage=185
recoveryImportHhi: nominal=4.17% coverage=190
inflationStability: nominal=3.40% coverage=185
electricityConsumption: nominal=3.30% coverage=217
ucdpConflict: nominal=3.09% coverage=193
Every core indicator has coverage ≥ 180 (already enforced by the
pre-existing indicator-tiering test), so the nominal-weight gate has
no current violators — its purpose is catching future drift, not
flagging today's state.
All 6327 data-tier tests pass. typecheck:api clean.
* docs(resilience): PR 3 methodology doc — document §3.5 dead-signal retirements + §3.6 coverage gate
Methodology-doc update capturing the three §3.5 landings and the §3.6 CI
gate. Five edits:
1. **Known construct limitations section (#5 and #6):** strikethrough the
original "dead signals" and "no coverage-based weight cap" items,
annotate them with "Landed in PR 3 §3.5"/"Landed in PR 3 §3.6" +
specifics of what shipped.
2. **Currency & External H4 section:** completely rewritten. Old table
(fxVolatility / fxDeviation / fxReservesAdequacy on BIS primary) is
replaced by the two-indicator post-PR-3 table (inflationStability at
0.60 + fxReservesAdequacy at 0.40). Coverage ladder spelled out
(0.85 / 0.55 / 0.40 / 0.30). Legacy BIS indicators named as
experimental-tier drill-downs only.
3. **Fuel Stock Days H4 section:** H4 heading text kept verbatim so the
methodology-lint H4-to-dimension mapping does not break; body
rewritten to explain that the dimension is retired from core but the
seeder still runs for IEA-member drill-downs.
4. **External Debt Coverage table row:** goalpost 5-0 → 2-0, description
cites Greenspan-Guidotti reserve-adequacy rule.
5. **New v2.2 changelog entry** — PR 3 dead-signal cleanup, covering
§3.5 points 1/2/3 + §3.6 + acceptance gates + construct-audit
updates.
No scoring or code changes in this commit. Methodology-lint test passes
(H4 mapping intact). All 6327 data-tier tests pass.
* fix(resilience): PR 3 §3.6 gate — correct share-denominator for coverage-weighted aggregation
Reviewer catch (thanks). The previous gate computed each indicator's
nominal overall weight as
indicator.weight × (1 / N_total_dimensions_in_domain) × domain_weight
and claimed this was an upper bound ("actual runtime weight is ≤ this
when some dimensions drop out on coverage"). That is BACKWARDS for
this scorer.
The domain aggregation is coverage-weighted
(server/worldmonitor/resilience/v1/_shared.ts coverageWeightedMean),
so when a dimension pins at coverage=0 it is EXCLUDED from the
denominator and the surviving dimensions' shares go UP, not down.
PR 3 commit 1 retires fuelStockDays by hard-coding its scorer to
coverage=0 for every country — so in the current live state the
recovery domain has 5 contributing dimensions (not 6), and each core
recovery indicator's nominal share is
1.0 × 1/5 × 0.25 = 5.00% (was mis-reported as 4.17%)
The old gate therefore under-estimated nominal influence and could
silently pass exactly the kind of low-coverage overweight regression
it is meant to block.
Fix:
- Added `coreBearingDimensions(domainId)` helper that counts only
dimensions that have ≥1 core indicator in the registry. A dimension
with only experimental/enrichment entries (post-retirement
fuelStockDays) has no core contribution → does not dilute shares.
- Updated `nominalOverallWeight` to divide by the core-bearing count,
not the raw dimension count.
- Rewrote the helper's doc comment to stop claiming this is a strict
upper bound — explicitly calls out the dynamic case (source failure
raising surviving dim shares further) as the sensitivity script's
responsibility.
- Added a new regression test: asserts (a) at least one recovery
dimension is all-non-core (fuelStockDays post-retirement),
(b) fuelStockDays has zero core indicators, and (c) recoveryDebt
ToReserves nominal = 0.05 exactly (not 0.0417) — any reversion
of the retirement or regression to N_total-denominator will fail
loudly.
Top-10 audit output now correctly shows:
recoveryReserveMonths: nominal=5% coverage=188
recoveryDebtToReserves: nominal=5% coverage=185
recoveryImportHhi: nominal=5% coverage=190
(was 4.17% each under the old math)
All 486 resilience tests pass. typecheck:api clean.
Note: the 5% figure is exactly AT the cap, not over it. "exceed" means
strictly > 5%, so it still passes. But now the reviewer / audit log
reflects reality.
* fix(resilience): PR 3 review — retired-dim confidence drag + false source-failure label
Addresses the Codex review P1 + P2 on PR #3297.
P1 — retired-dim drag on confidence averages
--------------------------------------------
scoreFuelStockDays returns coverage=0 by design (retired construct),
but computeLowConfidence, computeOverallCoverage, and the widget's
formatResilienceConfidence averaged across all 19 dimensions. That
dragged every country's reported averageCoverage down — US went from
0.8556 (active dims only) to 0.8105 (all dims) — enough drift to
misclassify edge countries as lowConfidence and to shift the ranking
widget's overallCoverage pill for every country.
Fix: introduce an authoritative RESILIENCE_RETIRED_DIMENSIONS set in
_dimension-scorers.ts and filter it out of all three averages. The
filter is keyed on the retired-dim REGISTRY, not on coverage === 0,
because a non-retired dim can legitimately emit coverage=0 on a
genuinely sparse-data country via weightedBlend fall-through — those
entries MUST keep dragging confidence down (that is the sparse-data
signal lowConfidence exists to surface). Verified: sparse-country
release-gate test (marks sparse WHO/FAO countries as low confidence)
still passes with the registry-keyed filter; would have failed with
a naive coverage=0 filter.
Server-client parity: widget-utils cannot import server code, so
RESILIENCE_RETIRED_DIMENSION_IDS is a hand-mirrored constant, kept
in lockstep by tests/resilience-retired-dimensions-parity.test.mts
(parses the widget file as text, same pattern as existing widget-util
tests that can't import the widget module directly).
P2 — false "Source down" label on retired dim
---------------------------------------------
scoreFuelStockDays hard-coded imputationClass: 'source-failure',
which the widget maps to "Source down: upstream seeder failed" with
a `!` icon for every country. That is semantically wrong for an
intentional retirement. Flipped to null so the widget's absent-path
renders a neutral cell without a false outage label. null is already
a legal value of ResilienceDimensionScore.imputationClass; no type
change needed.
Tests
-----
- tests/resilience-confidence-averaging.test.mts (new): pins the
registry-keyed filter semantic for computeOverallCoverage +
computeLowConfidence. Includes a negative-control test proving
non-retired coverage=0 dims still flip lowConfidence.
- tests/resilience-retired-dimensions-parity.test.mts (new):
lockstep gate between server and client retired-dim lists.
- Widget test adds a registry-keyed exclusion test with a non-retired
coverage=0 dim in the fixture to lock in the correct semantic.
- Existing tests asserting imputationClass: 'source-failure' for
fuelStockDays flipped to null.
All 494 resilience tests + full 6336/6336 data-tier suite pass.
Typecheck clean for both tsconfig.json and tsconfig.api.json.
* docs(resilience): align methodology + registry metadata with shipped imputationClass=null
Follow-up to the previous PR 3 review commit that flipped
scoreFuelStockDays's imputationClass from 'source-failure' to null to
avoid a false "Source down" widget label on every country. The code
changed; the doc and registry metadata did not, leaving three sites
in the methodology mdx and two comment/description sites in the
registry still claiming imputationClass='source-failure'. Any future
reviewer (or tooling that treats the registry description as
authoritative) would be misled.
This commit rewrites those sites to describe the shipped behavior:
- imputationClass=null (not 'source-failure'), with the rationale
- exclusion from confidence/coverage averages via the
RESILIENCE_RETIRED_DIMENSIONS registry filter
- the distinction between structural retirement (filtered) and
runtime coverage=0 (kept so sparse-data countries still flag
lowConfidence)
Touched:
- docs/methodology/country-resilience-index.mdx (lines ~33, ~268, ~590)
- server/worldmonitor/resilience/v1/_indicator-registry.ts
(recoveryFuelStockDays comment block + description field)
No code-behavior change. Docs-only.
Tests: 157 targeted resilience tests pass (incl. methodology-lint +
widget + release-gate + confidence-averaging). Typecheck clean on
both tsconfig.json and tsconfig.api.json.
687 lines
27 KiB
YAML
687 lines
27 KiB
YAML
# Resilience scorer indicator-source manifest (PR 0 scaffold, 2026-04-22).
|
||
#
|
||
# One entry per sub-indicator used inside a dimension scorer. Each entry
|
||
# answers the mechanism test from docs/plans/2026-04-22-001-fix-resilience-
|
||
# scorer-structural-bias-plan.md §1.1: what direct shock channel does this
|
||
# measure?
|
||
#
|
||
# Fields:
|
||
# indicator — scorer variable name (matches the weighted-blend entry)
|
||
# dimension — parent dimension id (matches RESILIENCE_DIMENSION_ORDER)
|
||
# domain — parent domain id
|
||
# weight — current nominal weight inside the dimension blend
|
||
# direction — higher-better | lower-better | composite
|
||
# source — authority that publishes the series
|
||
# seriesId — canonical series id where applicable (e.g. EG.IMP.CONS.ZS)
|
||
# seriesUrl — direct link to source documentation
|
||
# coveragePct — observed-data coverage across the 222-country static index (first-pass estimate; authoritative value lives in the matching seeder's seed-meta.coverage field)
|
||
# lastObservedYear — most-recent year with global data in the source
|
||
# license — reuse license (CC-BY, CC0, OGL, Proprietary-with-fair-use, etc.)
|
||
# mechanismTestRationale — one-sentence answer to "what direct shock channel does this measure?"
|
||
# constructStatus — observed-mechanism | wealth-proxy | imputed-floor | regional-only | dead-signal
|
||
#
|
||
# constructStatus is the v3-plan classification:
|
||
# observed-mechanism — passes the mechanism test; kept as-is pending goalpost review
|
||
# wealth-proxy — fails the mechanism test; slated for removal or threshold-transform
|
||
# imputed-floor — data source not wired; producing only the imputed midpoint
|
||
# regional-only — data source covers <50% of scorable countries
|
||
# dead-signal — saturated or compressed; signal collapsed across the ranking
|
||
|
||
# ECONOMIC DOMAIN (weight 0.17) -------------------------------------------
|
||
|
||
- indicator: govRevenuePct
|
||
dimension: macroFiscal
|
||
domain: economic
|
||
weight: 0.50
|
||
direction: higher-better
|
||
source: IMF
|
||
seriesId: GGR_G01_GDP_PT
|
||
seriesUrl: https://www.imf.org/external/datamapper/GGR_G01_GDP_PT@FM/
|
||
coveragePct: 0.90
|
||
lastObservedYear: 2024
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: Government revenue % GDP is the policy-response headroom a state can deploy during a fiscal shock; higher = more ability to absorb.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Goalpost 5-45 is probably too wide at the top; Nordic revenue/GDP ≥ 50% saturates. Review in PR 4 goalpost pass.
|
||
|
||
- indicator: debtGrowthRate
|
||
dimension: macroFiscal
|
||
domain: economic
|
||
weight: 0.20
|
||
direction: lower-better
|
||
source: National debt databases (IMF + WB cross-source)
|
||
seriesId: TBD
|
||
seriesUrl: TBD
|
||
coveragePct: 0.80
|
||
lastObservedYear: 2024
|
||
license: Mixed (per-source)
|
||
mechanismTestRationale: Rising debt growth indicates deteriorating fiscal trajectory and reduced capacity to finance a shock response.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: currentAccountPct
|
||
dimension: macroFiscal
|
||
domain: economic
|
||
weight: 0.30
|
||
direction: higher-better
|
||
source: IMF
|
||
seriesId: BCA_NGDPD
|
||
seriesUrl: https://www.imf.org/external/datamapper/BCA_NGDPD@WEO/
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2024
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: Current account surplus indicates external-payments resilience; deficit indicates vulnerability to external-finance shocks.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: fxVolatility
|
||
dimension: currencyExternal
|
||
domain: economic
|
||
weight: 0.60
|
||
direction: lower-better
|
||
source: BIS Data Portal
|
||
seriesId: Broad Effective Exchange Rate
|
||
seriesUrl: https://data.bis.org/topics/EER
|
||
coveragePct: 0.30 # BIS covers 64 economies
|
||
lastObservedYear: 2024
|
||
license: CC-BY
|
||
mechanismTestRationale: FX volatility measures monetary-shock transmission risk.
|
||
constructStatus: regional-only
|
||
reviewNotes: BIS EER covers only 64 economies. Replace with FR.INR.RINR (real interest rate) or IMF inflation volatility in PR 3.
|
||
|
||
- indicator: fxDeviation
|
||
dimension: currencyExternal
|
||
domain: economic
|
||
weight: 0.25
|
||
direction: lower-better
|
||
source: BIS Data Portal
|
||
seriesId: EER deviation from equilibrium
|
||
seriesUrl: https://data.bis.org/topics/EER
|
||
coveragePct: 0.30
|
||
lastObservedYear: 2024
|
||
license: CC-BY
|
||
mechanismTestRationale: EER deviation from equilibrium proxies mis-aligned exchange rates that create abrupt-correction risk.
|
||
constructStatus: regional-only
|
||
reviewNotes: Same 64-economy limitation. Retire in PR 3.
|
||
|
||
- indicator: fxReservesAdequacy
|
||
dimension: currencyExternal
|
||
domain: economic
|
||
weight: 0.15
|
||
direction: higher-better
|
||
source: World Bank
|
||
seriesId: FI.RES.TOTL.MO
|
||
seriesUrl: https://data.worldbank.org/indicator/FI.RES.TOTL.MO
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Reserves in months of imports directly measures immediate external-finance cushion.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Also enters reserveAdequacy at 1.0 weight. Double-counting risk across dimensions; review in PR 2.
|
||
|
||
- indicator: sanctionCount
|
||
dimension: tradeSanctions
|
||
domain: economic
|
||
weight: 0.45
|
||
direction: lower-better
|
||
source: OFAC
|
||
seriesId: Consolidated Sanctions List (count per country)
|
||
seriesUrl: https://sanctionslist.ofac.treas.gov/
|
||
coveragePct: 1.00
|
||
lastObservedYear: 2026
|
||
license: US Government public domain
|
||
mechanismTestRationale: Active sanctions restrict trade/finance channels; higher count = more channels restricted.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: OFAC-only. PR 4 adds EU/UK/CN sanctions for directional completeness.
|
||
|
||
- indicator: tradeRestrictions
|
||
dimension: tradeSanctions
|
||
domain: economic
|
||
weight: 0.15
|
||
direction: lower-better
|
||
source: WTO
|
||
seriesId: Trade Monitoring Database
|
||
seriesUrl: https://www.wto.org/english/tratop_e/tpr_e/trade_monitoring_e.htm
|
||
coveragePct: 0.75
|
||
lastObservedYear: 2025
|
||
license: Open
|
||
mechanismTestRationale: Active trade restrictions (in-force, weighted 3×) directly measure market-access loss.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: tradeBarriers
|
||
dimension: tradeSanctions
|
||
domain: economic
|
||
weight: 0.15
|
||
direction: lower-better
|
||
source: WTO
|
||
seriesId: Trade Barriers Notifications
|
||
seriesUrl: https://tradebarriers.wto.org/
|
||
coveragePct: 0.70
|
||
lastObservedYear: 2025
|
||
license: Open
|
||
mechanismTestRationale: Notified trade barriers (not yet in force) indicate near-term market-access risk.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: appliedTariffRate
|
||
dimension: tradeSanctions
|
||
domain: economic
|
||
weight: 0.25
|
||
direction: lower-better
|
||
source: World Bank / WITS
|
||
seriesId: TM.TAX.MRCH.WM.AR.ZS
|
||
seriesUrl: https://data.worldbank.org/indicator/TM.TAX.MRCH.WM.AR.ZS
|
||
coveragePct: 0.90
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Applied tariff rates measure cost of trade restriction on imports.
|
||
constructStatus: observed-mechanism
|
||
|
||
# INFRASTRUCTURE DOMAIN (weight 0.15) -------------------------------------
|
||
|
||
- indicator: cyberThreats
|
||
dimension: cyberDigital
|
||
domain: infrastructure
|
||
weight: 0.45
|
||
direction: lower-better
|
||
source: Cyber threat feeds (mixed Western-origin)
|
||
seriesId: severity-weighted count (critical 3×, high 2×, medium 1×, low 0.5×)
|
||
seriesUrl: Internal seed
|
||
coveragePct: 0.70
|
||
lastObservedYear: 2026
|
||
license: Proprietary feeds (aggregated)
|
||
mechanismTestRationale: Severity-weighted cyber threat count directly measures ongoing cyber-attack pressure on national digital infrastructure.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Western-feed bias; non-English cyber activity under-represented. PR 4 §4.8 tracks this.
|
||
|
||
- indicator: internetOutages
|
||
dimension: cyberDigital
|
||
domain: infrastructure
|
||
weight: 0.35
|
||
direction: lower-better
|
||
source: Cloudflare Radar + internal monitoring
|
||
seriesId: Outage penalty (total 4×, major 2×, partial 1×)
|
||
seriesUrl: https://radar.cloudflare.com/
|
||
coveragePct: 0.95
|
||
lastObservedYear: 2026
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Internet outages directly measure digital-infrastructure availability under current stress.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: gpsJamming
|
||
dimension: cyberDigital
|
||
domain: infrastructure
|
||
weight: 0.20
|
||
direction: lower-better
|
||
source: GPSJam
|
||
seriesId: Hex penalty (high 3×, medium 1×)
|
||
seriesUrl: https://gpsjam.org/
|
||
coveragePct: 0.95
|
||
lastObservedYear: 2026
|
||
license: Open data
|
||
mechanismTestRationale: GPS jamming intensity measures electronic-warfare / navigation-disruption exposure.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: logisticsPerformanceIndex
|
||
dimension: logisticsSupply
|
||
domain: infrastructure
|
||
weight: TBD
|
||
direction: higher-better
|
||
source: World Bank LPI
|
||
seriesId: LP.LPI.OVRL.XQ
|
||
seriesUrl: https://lpi.worldbank.org/
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Logistics Performance Index measures functional capacity to move goods; directly shocks during supply-chain disruptions.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Goalpost anchors OECD-centric; PR 4 review.
|
||
|
||
- indicator: infrastructureSubcomponents
|
||
dimension: infrastructure
|
||
domain: infrastructure
|
||
weight: TBD
|
||
direction: higher-better
|
||
source: World Bank + WEF Global Competitiveness
|
||
seriesId: Composite
|
||
seriesUrl: TBD
|
||
coveragePct: 0.80
|
||
lastObservedYear: 2024
|
||
license: Mixed
|
||
mechanismTestRationale: Physical infrastructure quality is the baseline capacity for delivering services during normal and crisis periods.
|
||
constructStatus: observed-mechanism
|
||
|
||
# ENERGY DOMAIN (weight 0.11) --------------------------------------------
|
||
|
||
- indicator: dependency
|
||
dimension: energy
|
||
domain: energy
|
||
weight: 0.25
|
||
direction: lower-better
|
||
source: IEA (via static seed)
|
||
seriesId: Energy import dependency (%)
|
||
seriesUrl: https://www.iea.org/data-and-statistics/data-browser
|
||
coveragePct: 0.50 # IEA detail covers OECD + major non-OECD
|
||
lastObservedYear: 2023
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: Share of energy consumption that is imported; direct supply-shock exposure.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: PR 1 §3.2 replaces with World Bank EG.IMP.CONS.ZS (better coverage) as part of importedFossilDependence composite.
|
||
|
||
- indicator: gasShare
|
||
dimension: energy
|
||
domain: energy
|
||
weight: 0.12
|
||
direction: lower-better
|
||
source: IEA World Energy Balances via static seed
|
||
seriesId: Natural gas share of primary energy
|
||
seriesUrl: https://www.iea.org/data-and-statistics/data-browser
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2023
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: CURRENT SCORER applies this as a vulnerability (lower-better) but it CONFLATES fossil-dominance with fossil-import-dependence. Domestic gas is a resilience asset, not a vulnerability.
|
||
constructStatus: wealth-proxy
|
||
reviewNotes: PR 1 §3.2 removes as standalone input; folds into importedFossilDependence under power-system framing.
|
||
|
||
- indicator: coalShare
|
||
dimension: energy
|
||
domain: energy
|
||
weight: 0.08
|
||
direction: lower-better
|
||
source: IEA World Energy Balances via static seed
|
||
seriesId: Coal share of primary energy
|
||
seriesUrl: https://www.iea.org/data-and-statistics/data-browser
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2023
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: Same concern as gasShare — penalty is climate-frame, not resilience-frame. Fails mechanism test under absolute-resilience contract.
|
||
constructStatus: wealth-proxy
|
||
reviewNotes: PR 1 §3.2 removes.
|
||
|
||
- indicator: renewShare
|
||
dimension: energy
|
||
domain: energy
|
||
weight: 0.05
|
||
direction: higher-better
|
||
source: IEA / World Bank
|
||
seriesId: EG.ELC.RNEW.ZS
|
||
seriesUrl: https://data.worldbank.org/indicator/EG.ELC.RNEW.ZS
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Share of electricity from renewables, proxies low-carbon-firm-generation capacity (for hydro/geothermal) and diversity-of-supply (for wind/solar).
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: PR 1 §3.3 collapses with nuclearShare (currently missing) into one lowCarbonGenerationShare indicator.
|
||
|
||
- indicator: storageStress
|
||
dimension: energy
|
||
domain: energy
|
||
weight: 0.10
|
||
direction: lower-better
|
||
source: GIE AGSI+
|
||
seriesId: EU gas storage fill % (per country)
|
||
seriesUrl: https://agsi.gie.eu/
|
||
coveragePct: 0.15 # EU + UK + a handful
|
||
lastObservedYear: 2026
|
||
license: Open
|
||
mechanismTestRationale: EU gas storage fill directly measures winter-heating-shock buffer. European-only platform.
|
||
constructStatus: regional-only
|
||
reviewNotes: PR 1 §3.5 renames to euGasStorageStress and scopes to EU-only (weight 0 for non-EU).
|
||
|
||
- indicator: exposedEnergyStress
|
||
dimension: energy
|
||
domain: energy
|
||
weight: 0.10
|
||
direction: composite
|
||
source: Internal composite (energy-price-stress × import-exposure)
|
||
seriesId: Derived
|
||
seriesUrl: Internal seed
|
||
coveragePct: 0.70
|
||
lastObservedYear: 2026
|
||
license: Internal
|
||
mechanismTestRationale: Combines energy-price shocks with import-exposure to measure price-shock transmission.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: PR 1 may simplify given importedFossilDependence covers import-exposure directly.
|
||
|
||
- indicator: electricityConsumption
|
||
dimension: energy
|
||
domain: energy
|
||
weight: 0.30
|
||
direction: higher-better
|
||
source: World Bank
|
||
seriesId: EG.USE.ELEC.KH.PC
|
||
seriesUrl: https://data.worldbank.org/indicator/EG.USE.ELEC.KH.PC
|
||
coveragePct: 0.90
|
||
lastObservedYear: 2022
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: FAILS the mechanism test. Per-capita electricity consumption tracks GDP per capita; it is a level-of-load measure not a resilience mechanism. IEA energy-security framing treats EFFICIENCY (lower load for same output) as resilience, which this indicator inversely rewards.
|
||
constructStatus: wealth-proxy
|
||
reviewNotes: PR 1 §3.1 removes. Replaced with powerLossesPct (EG.ELC.LOSS.ZS), reserveMarginPct (IEA), and accessToElectricityPct (EG.ELC.ACCS.ZS) moved to infrastructure domain.
|
||
|
||
# SOCIAL-GOVERNANCE DOMAIN (weight 0.19) ---------------------------------
|
||
|
||
- indicator: wgiComposite
|
||
dimension: governanceInstitutional
|
||
domain: social-governance
|
||
weight: 1.0
|
||
direction: higher-better
|
||
source: World Bank WGI
|
||
seriesId: Voice/Accountability, Political Stability, Government Effectiveness, Regulatory Quality, Rule of Law, Control of Corruption
|
||
seriesUrl: https://info.worldbank.org/governance/wgi/
|
||
coveragePct: 0.98
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: WGI subscores measure state capacity to design and enforce policy response to shocks. Passes the mechanism test conditionally — the composite is a direct policy-response-capacity signal.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Weights review in PR 4. Individual WGI subscores may need separate weighting vs equal-blend.
|
||
|
||
- indicator: gpiScore
|
||
dimension: socialCohesion
|
||
domain: social-governance
|
||
weight: 0.40 # approximate
|
||
direction: lower-better
|
||
source: Institute for Economics and Peace
|
||
seriesId: Global Peace Index
|
||
seriesUrl: https://www.visionofhumanity.org/
|
||
coveragePct: 0.75
|
||
lastObservedYear: 2024
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: GPI measures internal conflict, militarization, and external conflict intensity — direct social-cohesion-shock exposure.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Known Western-democracy bias in GPI methodology; PR 4 review.
|
||
|
||
- indicator: displacementMetric
|
||
dimension: socialCohesion
|
||
domain: social-governance
|
||
weight: 0.30 # approximate
|
||
direction: lower-better
|
||
source: UNHCR
|
||
seriesId: totalDisplaced
|
||
seriesUrl: https://data.unhcr.org/
|
||
coveragePct: 0.95
|
||
lastObservedYear: 2025
|
||
license: Open
|
||
mechanismTestRationale: Total displaced persons directly measures ongoing forced-migration pressure. BIAS: currently blends origin + host; penalizes Jordan/Turkey/Germany for HOSTING.
|
||
constructStatus: wealth-proxy # classified as biased — bias label
|
||
reviewNotes: PR 4 §4.2 splits origin (negative signal) from host (mixed signal).
|
||
|
||
- indicator: unrestMetric
|
||
dimension: socialCohesion
|
||
domain: social-governance
|
||
weight: 0.30 # approximate
|
||
direction: lower-better
|
||
source: Internal unrest seed (cross-source signals + UCDP)
|
||
seriesId: unrestCount + sqrt(fatalities)
|
||
seriesUrl: Internal seed
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2026
|
||
license: Mixed
|
||
mechanismTestRationale: Active unrest events measure current social-cohesion stress.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: borderSecuritySubs
|
||
dimension: borderSecurity
|
||
domain: social-governance
|
||
weight: TBD
|
||
direction: composite
|
||
source: Composite (UNHCR displacement + UCDP conflict + governance)
|
||
seriesId: Derived
|
||
seriesUrl: Internal seed
|
||
coveragePct: 0.80
|
||
lastObservedYear: 2026
|
||
license: Mixed
|
||
mechanismTestRationale: Border-security composite captures cross-border shock transmission exposure.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Inherits displacement host-vs-sending bias from socialCohesion. PR 4 fix.
|
||
|
||
- indicator: rsfPressFreedom
|
||
dimension: informationCognitive
|
||
domain: social-governance
|
||
weight: TBD
|
||
direction: higher-better
|
||
source: Reporters Sans Frontieres
|
||
seriesId: Press Freedom Index
|
||
seriesUrl: https://rsf.org/en/index
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2024
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: Press freedom proxies quality of information-shock response and independent verification capacity.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: languageNormalizedSocialVelocity
|
||
dimension: informationCognitive
|
||
domain: social-governance
|
||
weight: TBD
|
||
direction: composite
|
||
source: Reddit + cross-source + internal language-coverage-weighting
|
||
seriesId: Internal
|
||
seriesUrl: Internal seed
|
||
coveragePct: 0.95
|
||
lastObservedYear: 2026
|
||
license: Mixed
|
||
mechanismTestRationale: Language-normalized social-information velocity measures information-shock propagation speed adjusted for source-density bias.
|
||
constructStatus: observed-mechanism
|
||
|
||
# HEALTH-FOOD DOMAIN (weight 0.13) ---------------------------------------
|
||
|
||
- indicator: whoHealthExpenditure
|
||
dimension: healthPublicService
|
||
domain: health-food
|
||
weight: TBD
|
||
direction: higher-better
|
||
source: WHO Global Health Observatory
|
||
seriesId: Current health expenditure per capita, PPP
|
||
seriesUrl: https://www.who.int/data/gho
|
||
coveragePct: 0.95
|
||
lastObservedYear: 2022
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Health expenditure per capita proxies health-system capacity. FAILS the strict mechanism test — it measures SPEND, not CAPACITY. Should be replaced with surge-capacity / bed-density / ICU-density threshold signal.
|
||
constructStatus: wealth-proxy
|
||
reviewNotes: PR 4 §4.9 replacement.
|
||
|
||
- indicator: ipcPhase
|
||
dimension: foodWater
|
||
domain: health-food
|
||
weight: 0.15
|
||
direction: lower-better
|
||
source: FAO IPC (Integrated Food Security Phase Classification)
|
||
seriesId: IPC Phase (1-5)
|
||
seriesUrl: https://www.ipcinfo.org/
|
||
coveragePct: 0.40 # IPC covers acutely-affected countries
|
||
lastObservedYear: 2025
|
||
license: Open
|
||
mechanismTestRationale: IPC phase directly measures current food-security-crisis severity.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Coverage is inherently partial — IPC only tracks countries with current/imminent food crises. Imputed to a resilient-default for non-tracked countries.
|
||
|
||
- indicator: aquastatWaterStress
|
||
dimension: foodWater
|
||
domain: health-food
|
||
weight: 0.25
|
||
direction: lower-better
|
||
source: FAO AQUASTAT
|
||
seriesId: Water stress (withdrawal / renewable resources)
|
||
seriesUrl: https://www.fao.org/aquastat/
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2020
|
||
license: Open
|
||
mechanismTestRationale: Water stress directly measures water-supply-shock exposure.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: aquastatWaterAvailability
|
||
dimension: foodWater
|
||
domain: health-food
|
||
weight: 0.15
|
||
direction: higher-better
|
||
source: FAO AQUASTAT
|
||
seriesId: Water availability (m³/capita)
|
||
seriesUrl: https://www.fao.org/aquastat/
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2020
|
||
license: Open
|
||
mechanismTestRationale: Water availability per capita proxies baseline water-security-shock buffer.
|
||
constructStatus: observed-mechanism
|
||
|
||
# RECOVERY DOMAIN (weight 0.25) ------------------------------------------
|
||
|
||
- indicator: recoveryGovRevenue
|
||
dimension: fiscalSpace
|
||
domain: recovery
|
||
weight: 0.40
|
||
direction: higher-better
|
||
source: IMF
|
||
seriesId: GGR_G01_GDP_PT
|
||
seriesUrl: https://www.imf.org/external/datamapper/GGR_G01_GDP_PT@FM/
|
||
coveragePct: 0.90
|
||
lastObservedYear: 2024
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: Government revenue % GDP for recovery scenarios — policy-response fiscal headroom.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Duplicate with macroFiscal.govRevenuePct. PR 4 may de-duplicate.
|
||
|
||
- indicator: recoveryFiscalBalance
|
||
dimension: fiscalSpace
|
||
domain: recovery
|
||
weight: 0.30
|
||
direction: higher-better
|
||
source: IMF
|
||
seriesId: GGXCNL_G01_GDP_PT
|
||
seriesUrl: https://www.imf.org/external/datamapper/GGXCNL_G01_GDP_PT@FM/
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2024
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: General government net lending/borrowing as % of GDP — direct fiscal-response-capacity signal.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: recoveryDebtToGdp
|
||
dimension: fiscalSpace
|
||
domain: recovery
|
||
weight: 0.30
|
||
direction: lower-better
|
||
source: IMF
|
||
seriesId: GGXWDG_NGDP_PT
|
||
seriesUrl: https://www.imf.org/external/datamapper/GGXWDG_NGDP_PT@FM/
|
||
coveragePct: 0.90
|
||
lastObservedYear: 2024
|
||
license: Proprietary-with-fair-use
|
||
mechanismTestRationale: General government gross debt to GDP — fiscal-stress cushion.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Goalpost 0-150 is too linear; Japan at 260% (mostly domestic, yen-denominated) scores 0 despite weak real fiscal-stress risk. PR 4 §4.4 adds holder-composition modifier.
|
||
|
||
- indicator: recoveryReserveMonths
|
||
dimension: reserveAdequacy
|
||
domain: recovery
|
||
weight: 1.00
|
||
direction: higher-better
|
||
source: World Bank
|
||
seriesId: FI.RES.TOTL.MO
|
||
seriesUrl: https://data.worldbank.org/indicator/FI.RES.TOTL.MO
|
||
coveragePct: 0.85
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Central-bank reserves in months of imports — immediate external-liquidity cushion.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: PR 2 §3.4 renames to liquidReserveAdequacy; new dimension sovereignFiscalBuffer added.
|
||
|
||
- indicator: recoveryDebtToReserves
|
||
dimension: externalDebtCoverage
|
||
domain: recovery
|
||
weight: 1.00
|
||
direction: lower-better
|
||
source: World Bank
|
||
seriesId: DT.DOD.DSTC.CD / FI.RES.TOTL.CD
|
||
seriesUrl: https://data.worldbank.org/indicator/DT.DOD.DSTC.CD
|
||
coveragePct: 0.75
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: Short-term external debt to reserves ratio — rollover-shock exposure. Goalpost anchored on Greenspan-Guidotti (ratio≥1 = reserve inadequacy).
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: PR 3 §3.5 point 3 re-goalposted from (0..5) to (0..2). Old goalpost saturated at 100 across the 9-country probe including stressed states; new anchor maps ratio=1.0 to score 50 and ratio=2.0 to score 0.
|
||
|
||
- indicator: recoveryImportHhi
|
||
dimension: importConcentration
|
||
domain: recovery
|
||
weight: 1.00
|
||
direction: lower-better
|
||
source: UN Comtrade
|
||
seriesId: HS2 bilateral Herfindahl-Hirschman Index
|
||
seriesUrl: https://comtrade.un.org/
|
||
coveragePct: 0.70
|
||
lastObservedYear: 2023
|
||
license: Open
|
||
mechanismTestRationale: Import-partner concentration (HHI) — supplier-shock exposure.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Coverage gap for UAE and small-island states; PR 1+ audit.
|
||
|
||
- indicator: recoveryWgiContinuity
|
||
dimension: stateContinuity
|
||
domain: recovery
|
||
weight: 0.50
|
||
direction: higher-better
|
||
source: World Bank WGI
|
||
seriesId: Mean of WGI subscores
|
||
seriesUrl: https://info.worldbank.org/governance/wgi/
|
||
coveragePct: 0.98
|
||
lastObservedYear: 2023
|
||
license: CC-BY-4.0
|
||
mechanismTestRationale: WGI composite as state-continuity proxy — institutional durability through shocks.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Duplicate with governanceInstitutional.wgiComposite. PR 4 de-duplicate.
|
||
|
||
- indicator: recoveryConflictPressure
|
||
dimension: stateContinuity
|
||
domain: recovery
|
||
weight: 0.30
|
||
direction: lower-better
|
||
source: UCDP
|
||
seriesId: Armed conflict events / fatalities
|
||
seriesUrl: https://ucdp.uu.se/
|
||
coveragePct: 0.95
|
||
lastObservedYear: 2026
|
||
license: Open
|
||
mechanismTestRationale: UCDP conflict intensity — direct state-continuity-shock metric.
|
||
constructStatus: observed-mechanism
|
||
|
||
- indicator: recoveryDisplacementVelocity
|
||
dimension: stateContinuity
|
||
domain: recovery
|
||
weight: 0.20
|
||
direction: lower-better
|
||
source: UNHCR
|
||
seriesId: Displacement as share of population
|
||
seriesUrl: https://data.unhcr.org/
|
||
coveragePct: 0.95
|
||
lastObservedYear: 2025
|
||
license: Open
|
||
mechanismTestRationale: Displacement velocity — population-scale state-continuity stress.
|
||
constructStatus: observed-mechanism
|
||
reviewNotes: Inherits host-vs-sending bias. PR 4 §4.2 fix.
|
||
|
||
- indicator: recoveryFuelStockDays
|
||
dimension: fuelStockDays
|
||
domain: recovery
|
||
weight: 1.00
|
||
direction: higher-better
|
||
source: IEA / EIA
|
||
seriesId: Days of fuel stock cover
|
||
seriesUrl: https://www.iea.org/data-and-statistics/data-tools/oil-stocks-of-iea-countries
|
||
coveragePct: 0.30 # imputed for every country
|
||
lastObservedYear: null
|
||
license: Proprietary
|
||
mechanismTestRationale: Days of fuel stock for import-shock coverage. IEA rules bind only net importers; net exporters get no observed value.
|
||
constructStatus: imputed-floor
|
||
reviewNotes: PR 3 §3.5 retires from core score (permanent). Enrichment-only if IEA/EIA connector ever wires.
|
||
|
||
# PENDING ADDITIONS FOR PR 1+ --------------------------------------------
|
||
|
||
# PR 1 additions (not yet in the scorer):
|
||
# - powerLossesPct → EG.ELC.LOSS.ZS (transmission+distribution losses, lower-better)
|
||
# - reserveMarginPct → IEA electricity balance (generation reserve margin, higher-better)
|
||
# - accessToElectricityPct → EG.ELC.ACCS.ZS (threshold/saturating, moved to infrastructure domain)
|
||
# - importedFossilDependence → EG.IMP.CONS.ZS × fossil-generation-share (Option B power-system framing)
|
||
# - lowCarbonGenerationShare → EG.ELC.NUCL.ZS + EG.ELC.RNEW.ZS (higher-better)
|
||
|
||
# PR 2 additions (not yet in the scorer):
|
||
# - liquidReserveAdequacy → FI.RES.TOTL.MO (rename of current reserveMonths)
|
||
# - sovereignFiscalBuffer → IFSWF + official disclosures × access × liquidity × transparency
|
||
|
||
# PR 3 replacements (not yet in the scorer):
|
||
# - realInterestRate → FR.INR.RINR (replaces currencyExternal for non-BIS countries)
|