Country Instability Index (CII) Algorithm: Signals, Weighting, and Score Calculation Explained

The Country Instability Index aggregates dozens of real-time signals into four weighted components—Unrest (25%), Conflict (30%), Security (20%), and Information (25%)—then applies dynamic boosts and risk floors to generate a final 0-100 stability score.

The koala73/worldmonitor repository implements a sophisticated country instability index (CII) that transforms heterogeneous data streams—from ACLED conflict reports to GPS jamming events—into a normalized risk metric. This article breaks down the exact signals, component weightings, and algorithmic boosts defined in src/services/country-instability.ts that determine how the final score is calculated.

Core Components and Signal Sources

The CII algorithm aggregates raw signals into four capped components (0-100). Each component is computed by dedicated functions that normalize disparate data sources into comparable scores.

Unrest Component

The Unrest score captures civil disorder and information blackouts through social-unrest events and internet outages.

Conflict Component

The Conflict score measures kinetic violence and military engagements using armed conflict data and strike activity.

Security Component

The Security score tracks military mobilization and infrastructure disruptions.

Information Component

The Information score quantifies narrative velocity and alert status through news metadata.

Component Weighting and Base Score Calculation

Inside calculateCII, the four component scores are multiplied by fixed percentages to produce the event score. This weighting reflects the algorithm's emphasis on Conflict (30%) as the primary instability driver, with Unrest and Information equally weighted (25% each), and Security comprising the remaining 20%.

const eventScore =
    components.unrest * 0.25 +      // 25%
    components.conflict * 0.30 +    // 30%
    components.security * 0.20 +    // 20%
    components.information * 0.25;  // 25%

Source: calculateCII lines 1029-1030

Dynamic Boosts and Risk Modifiers

After computing the base event score, the algorithm applies a series of dynamic boosts that reflect real-time risk factors not captured by the core components. These modifiers are summed and added to the blended score.

  • Hot-spot Activity: Proximity to intel hotspots, conflict zones, and strategic waterways adds up to 10 points (Math.min(10, activity * 1.5)). Source: getHotspotBoost lines 885-888

  • News Urgency: High information scores trigger urgency boosts—+5 if the Information component is ≥70, or +3 if ≥50. Source: calculateCII lines 1032-1034

  • Focal-point Urgency: Real-time critical event detection adds +8 for critical urgency or +4 for elevated status. Source: calculateCII lines 1035-1038

  • Displacement: Refugee and asylum outflows add +8 for flows ≥1 million or +4 for flows ≥100,000. Source: calculateCII lines 1040-1042

  • Climate Stress: Direct addition of the climate-anomaly stress score (0-15). Source: calculateCII line 1043

  • OREF Blend: Israeli OREF alerts contribute 15 + min(25, alertCount * 5), yielding a range of 15-40 points when alerts are present. Source: getOrefBlendBoost lines 1024-1026

  • Travel Advisory: Government advisories add +15 for do-not-travel, +10 for reconsider, and +5 for caution, plus an additional +5 when three or more sources agree. Source: getAdvisoryBoost lines 66-76

  • Supplemental Signals: AIS disruptions (≤10), satellite fires (≤8), cyber threats (≤12), and temporal anomalies (≤6) combine for up to 36 additional points. Source: getSupplementalSignalBoost lines 86-102

The blended score formula combines the baseline risk, event score, and all dynamic boosts:

const blendedScore =
    baselineRisk * 0.4 + eventScore * 0.6 +
    hotspotBoost + newsUrgencyBoost + focalBoost +
    displacementBoost + climateBoost +
    getOrefBlendBoost(code, data) +
    advisoryBoost + supplementalSignalBoost;

Source: blendedScore calculation lines 1047-1048

Risk Floors and Final Score Enforcement

After calculating the blended score, the algorithm enforces minimum risk floors based on authoritative conflict datasets and travel advisories. The final score is the maximum of the blended score or the applicable floor, capped at 100.

UCDP Conflict Floor

The Uppsala Conflict Data Program (UCDP) status provides a hard floor when active conflict is documented:

  • War status: Floor of 70
  • Minor conflict: Floor of 50

Implementation: getUcdpFloor lines 363-368

Travel Advisory Floor

Government travel advisories enforce additional minimums:

  • Do-not-travel: Floor of 60
  • Reconsider travel: Floor of 50

Implementation: getAdvisoryFloor lines 79-83

Final Calculation

const finalScore = Math.min(100, Math.max(ucdpFloor, advisoryFloor, blendedScore));

Source: Final score logic lines 1049-1051

Summary

  • The country instability index aggregates signals across four components: Unrest (protests, outages), Conflict (ACLED violence, strikes), Security (military activity, GPS jamming), and Information (news velocity).
  • Weighting: Conflict receives the highest weight (30%), followed by Unrest and Information (25% each), and Security (20%).
  • Dynamic boosts add real-time risk factors including hotspot proximity (up to +10), displacement (+4 to +8), climate stress (+0 to +15), OREF alerts (+15 to +40), and supplemental signals (up to +36).
  • Risk floors enforce minimums based on UCDP conflict status (50 or 70) and travel advisories (50 or 60), ensuring the final score reflects documented high-risk conditions.

Frequently Asked Questions

What data sources feed the Country Instability Index?

The index ingests dozens of signal streams including ACLED conflict events, UCDP conflict status, social unrest and protest data, military flight and vessel tracking, internet outage reports, GPS jamming incidents, aviation disruptions, satellite fire detection, AIS maritime disruptions, cyber threat intelligence, refugee displacement figures, climate anomaly stress scores, Israeli OREF alerts, and government travel advisories.

How does the algorithm handle missing data for a specific country?

When primary conflict data is absent, the algorithm employs fallback mechanisms. For the Conflict component, calcConflictScore uses UCDP status as a fallback (HAPI integration), and if both ACLED and UCDP are missing, it applies a news-based floor to ensure the score does not underrepresent documented violence. Similarly, the Unrest component uses country-specific multipliers to normalize protest counts when historical baselines vary.

Why does the Conflict component have a higher weight than Security?

The Conflict component receives a 30% weight compared to Security's 20% because kinetic violence (battles, explosions, civilian targeting) is the primary driver of country instability in the model's design. The algorithm prioritizes active warfare and organized violence over military mobilization signals (Security), which may indicate preparation rather than active destabilization. This weighting is hardcoded in calculateCII at lines 1029-1030.

What prevents the CII score from dropping too low during active conflicts?

The algorithm enforces risk floors that override low blended scores when authoritative sources document active conflict. The UCDP floor sets a minimum of 50 for minor conflicts and 70 for wars, while the travel advisory floor sets minimums of 50 (reconsider) or 60 (do-not-travel). The final score is calculated as Math.max(ucdpFloor, advisoryFloor, blendedScore), ensuring that documented high-risk conditions maintain elevated index values regardless of other mitigating signals.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →