────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Abstract
This page documents the implemented calculator, not an aspirational model. It describes the public APIs, static datasets, mathematical transformations, fallback rules, uncertainty treatment, and audit notes that currently drive the application.
The system treats war-cost estimation as a transparent accounting exercise. Every user-facing number must either come from a named public source or from a deterministic transformation applied to those sources. When live APIs fail or provide no coverage, the code falls back to explicit local datasets rather than silently imputing values.
The calculator is intentionally conservative in scope. It prices military operations, armaments and intercepts, economic dislocation, humanitarian displacement support, direct casualty cost, and reconstruction. It does not claim to price the full social cost of war, and it explicitly excludes nuclear escalation, long-run trauma, ecological damage, alliance cascades, and other second-order effects that are either methodologically unstable or not yet parameterized in code.
headlineCost = military + humanitarian + reconstruction + armaments
economicImpact is reported separately from headlineCost
netPosition = revenue - headlineCost
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Data Pipeline
The codebase is organized as a small Next.js application: static pages at the top, server routes in the middle, and deterministic calculation modules beneath them.
Internal Routes
ROUTE│/api/countriesPURPOSE│Builds the selectable country list from REST Countries and appends curated records for Taiwan, Palestine, and Kosovo.OUTPUT│195 selectable country records with coordinates, flags, region tags, and population baselines.
ROUTE│/api/calculatePURPOSE│Main orchestration endpoint. Fetches live indicators, merges fallbacks, resolves sanctions, commodity, Comtrade, and ACLED data, then runs every model module.OUTPUT│Cost ranges, module breakdowns, line-item assumptions, data freshness labels, ACLED fragility overlays, human toll estimates, and best-case revenue counterfactual.
ROUTE│/api/world-bank/[indicator]PURPOSE│Thin allowlisted proxy for selected World Bank indicators used by the UI and by external inspection.OUTPUT│JSON map of country codes to the latest non-null World Bank value returned in the retrieval window.
ROUTE│/api/opportunity-contextPURPOSE│Fetches the target-country baseline metrics used in the gravity comparison panel for opportunity-cost context.OUTPUT│Current national baselines for beds, nurses, water, sanitation, undernourishment, child population, and forest area.
Country Assembly Pipeline
The calculation route starts by building two enriched country objects. Geographic metadata comes from REST Countries, live indicators come from World Bank, GDP can fall back to IMF DataMapper, military and sanctions context can fall back to local datasets, and missing data-sparse states are explicitly labeled through the hasStaticFallback flag.
country = merge(staticCountries, worldbank, imf?, sipri, staticFallback?)militaryBudget = WB.MS.MIL.XPND.CD ?? SIPRI.expenditureUsd ?? GDP x (militaryPctGDP / 100) ?? staticFallbackgoldReserves = max(FI.RES.TOTL.CD - FI.RES.XGLD.CD, 0)distanceKm = haversine(aggressor.latlng, target.latlng)
Added Calculations
Recent live-data refinements do not replace the base model. They sit on top of the prior architecture to improve trade realism, inflation handling, commodity scaling, and target-country fragility sensitivity.
Live Bilateral Trade Override
When a Comtrade key is configured, live bilateral imports plus exports replace the static pair table. The gravity model remains the last-resort fallback.
tradeVolume = comtradeLive ?? staticPair ?? gravityEstimate
Inflation-Adjusted Military Anchors
Watson daily military anchors are expressed in 2023 USD and are inflated forward using live FRED CPI when available.
watsonDaily = scenarioAnchor x cpiScalar
Live Commodity Scaling
Oil, gas, and wheat disruption shocks scale with current FRED prices; semiconductors and lithium remain structural, non-price-scaled shocks.
commodityShock_i = baselineShock_i x (livePrice_i / 2023BaselinePrice_i)
ACLED Fragility Signal
The overlay only activates when recent violence is non-trivial. It is intentionally modest so ACLED refines baseline assumptions rather than replacing them.
eventSignal = min(events365 / 250, 1)fatalitySignal = min(fatalities365 / 2000, 1)fragility = 1 + (0.08 x eventSignal) + (0.17 x fatalitySignal)
GDP, Capital-Flight, and Displacement Overlays
Recent ACLED intensity raises target-country vulnerability and displacement pressure, but does not alter the aggressor-side military anchor directly.
targetGDPLoss = baseTargetGDPLoss x fragilitycapitalFlight = baseCapitalFlight x (1 + ((fragility - 1) x 0.6))displaced = baseDisplaced x fragility
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Live APIs
The calculator mixes live public APIs with versioned local datasets. Live APIs are used for recency; local files are used for coverage, calibration, and transparent fallback behavior.
SOURCE│World Bank World Development IndicatorsVARS│NY.GDP.MKTP.CD, MS.MIL.XPND.GD.ZS, MS.MIL.XPND.CD, SP.POP.TOTL, NE.TRD.GNFS.ZS, FI.RES.TOTL.CD, FI.RES.XGLD.CD, SH.MED.BEDS.ZS, SH.MED.NUMW.P3, SH.H2O.BASW.ZS, SH.STA.BASS.ZS, SN.ITK.DEFC.ZS, SP.POP.0014.TO.ZS, AG.LND.FRST.K2ROLE│Primary economic, population, military, trade, and reserve inputs for aggressor and target.CACHE│24 hoursFALLBACK│The app now scans the 10 most recent observations and uses the latest non-null row. GDP falls back to IMF when absent. SOURCE│IMF DataMapper APIVARS│NGDPDROLE│Secondary GDP source for countries where World Bank GDP is unavailable or stale.CACHE│24 hoursFALLBACK│Used only when World Bank GDP is null; otherwise skipped to avoid extra latency. SOURCE│Static country datasetVARS│cca2, cca3, name, flags, region, subregion, latlng, area, unMember, populationROLE│Country metadata, coordinates for distance calculations, flags, region labels, and geographic area.CACHE│Committed to the repo; regenerate with npm run build:countriesFALLBACK│Population comes from the World Bank SP.POP.TOTL latest non-null value. Taiwan, Palestine, and Kosovo are injected from a local curated dataset because the UN-member filter excludes them. SOURCE│FREDVARS│DCOILWTICO, DHHNGSP, PWHEAMTUSDM, CPIAUCSLROLE│Optional live price scaling for oil, gas, wheat, and CPI inflation adjustment for military anchors.CACHE│1 hourFALLBACK│If FRED is unavailable or no API key is configured, commodity shocks stay on 2023 baselines and CPI scalar defaults to 1.0. SOURCE│UN Comtrade APIVARS│Bilateral annual goods trade (imports + exports) by reporter/partner pairROLE│Optional live bilateral-trade replacement for the static canonical pair table used in the economic-impact module.CACHE│24 hoursFALLBACK│Requires a subscription key. When absent or unavailable, the calculator falls back to the local bilateral trade dataset and then to the gravity model. SOURCE│ACLED APIVARS│Recent political-violence events, fatalities, and event dates by countryROLE│Optional live fragility overlay for target-country GDP contraction, capital flight, and displacement estimates.CACHE│6 hoursFALLBACK│Requires ACLED credentials. When absent, the calculator uses the existing static scenario and displacement assumptions without the live fragility overlay. API Endpoint Map
These are the actual upstream endpoint patterns the code calls today. The app wraps them with cache control, graceful fallback, and input normalization before they influence any result.
World Bank WDI│Latest non-null GDP, population, trade, reserve, military-expenditure, and social-baseline indicators.ENDPOINT│GET https://api.worldbank.org/v2/country/{iso3;...}/indicator/{indicator}?format=json&mrv=10&per_page=50
IMF DataMapper│Fallback nominal GDP in current USD when World Bank GDP is absent.ENDPOINT│GET https://www.imf.org/external/datamapper/api/v1/NGDPD/{iso3,...}
Static country dataset (mledoze/countries + World Bank + flagcdn)│Country identity, map coordinates, area, population, and region metadata. Regenerated from keyless sources when needed.ENDPOINT│npm run build:countries → src/lib/data/countries.json
FRED│Live oil, gas, wheat, and CPI series used to scale commodity shocks and military anchors.ENDPOINT│GET https://api.stlouisfed.org/fred/series/observations?series_id={seriesId}&api_key={key}&limit=10&sort_order=desc&file_type=json
UN Comtrade│Live annual bilateral goods trade used to override the static trade-pair table before gravity fallback.ENDPOINT│GET https://comtradeapi.un.org/tools/v1/getBilateralData/C/A/HS?reporterCode={m49}&period={year}&partnerCode={m49}&flowCode=M,X&includeDesc=false
ACLED OAuth│Bearer-token exchange for ACLED event queries.ENDPOINT│POST https://acleddata.com/oauth/token
ACLED Events│Recent political-violence and fatality counts used to build the target fragility overlay.ENDPOINT│GET https://acleddata.com/api/acled/read?_format=json&country={name}&year={year}&event_type=Battles|Violence against civilians|Explosions/Remote violence&fields=event_date|event_type|fatalities|country&limit=5000
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Static Datasets
Versioned local datasets provide coverage, calibration anchors, and transparent fallback behavior when live APIs are unavailable or return null.
135 countries, 2010–2024│SIPRI Military Expenditure Database 2024NOTE│Military expenditure in current USD, used as offline fallback for defense budgets in the armaments module when World Bank data is unavailable.
30 NATO members│NATO Defence Expenditure 2025NOTE│Equipment spending as % of total defence budget (Table 8a), used to derive per-country procurement fraction in the armaments module. Global median 20% used for non-NATO states.
79 recipient countries│Bruegel US Foreign Military Sales 2008–2025NOTE│US arms sales by recipient, equipment category, and year in 2024 constant USD. Reference dataset for arms transfer patterns and equipment category weights.
22 weapon categories│Armaments unit cost tableNOTE│DoD-sourced unit procurement costs with low/high ranges: from 155mm artillery shells ($800–$80K) to aircraft carriers ($3–14B). Updated from DoD Program Acquisition Costs FY2024.
6 scenarios│Scenario force-package tableNOTE│Typical weapons quantities deployed per package archetype. The calculator maps five UI scenarios to these packages; naval_blockade remains a reserved, non-UI package.
26 country cases + 8 regional defaults│UNHCR-derived displacement ratiosNOTE│Pre-processed IDP and refugee ratios used by the humanitarian model for most scenarios. Sustained air campaigns use the calibrated event-level population share instead.
75 canonical country pairs│UN Comtrade bilateral trade pairsNOTE│Goods trade flows used before the gravity fallback is invoked for unlisted dyads.
32 country-commodity entries│Commodity producer exposure fileNOTE│Oil, gas, wheat, semiconductor, and lithium exposure table with modeled global GDP shock anchors.
8 aggressor regimes│Sanctions regimes fileNOTE│Literature-derived sanctions severity assumptions for countries with documented existing sanctions frameworks.
14 countries│Static fallback country fileNOTE│Last-resort GDP, population, military, and trade values for data-sparse states such as North Korea, Syria, and Taiwan.
10 unit-cost benchmarks│Opportunity cost datasetNOTE│Schools, hospital beds, nurses, vaccines, meals, food support, water access, sanitation access, solar home systems, and restoration costs shown separately from the war total.
3 records│Curated extra-country fileNOTE│Taiwan, Palestine, and Kosovo metadata added on top of the REST Countries feed.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Military Model
The military module is anchored to direct operational spending benchmarks from Watson Institute case studies and then scaled by aggressor budget, scenario class, distance, and attrition. The Watson anchor for a conventional war is ~$200M/day ≈ cost of 50 Tomahawk cruise missiles daily. Air-campaign munitions, aircraft packages, and defensive intercepts are handled in the armaments module, keeping this module focused on operations, personnel, logistics, and wear. It does not attempt to reproduce veterans care, interest on war debt, or homeland-security spillovers.
budgetScale = clamp(aggressorMilitaryBudget / 700B, 0.02, 3.0)watsonDaily = scenarioAnchor x cpiScalarlogistics = distanceKm > 10000 ? 1 + ((distanceKm - 10000) / 10000) x 0.15 : max(0.70, distanceKm / 10000)operational = watsonDaily x budgetScale x 365 x durationYears x logisticsattrition = operational x equipmentAttritionPctmilitaryTotal = operational + attrition
Notes: Operational totals are decomposed into personnel (35%), operations and logistics (40%), munitions (20%), and C3ISR (5%), with scenario-specific equipment attrition added on top.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Economic Model
The economic module combines bilateral trade disruption, target-country GDP contraction, capital flight, sanctions drag on the aggressor when justified by literature, and a commodity shock layer for globally important producers.
tradeVolume = comtradeLive ?? lookupPair(a, b) ?? 0.004 x sqrt(GDP_a x GDP_b) / max(distanceKm, 500)tradeLoss = tradeVolume x 0.70 x durationYears x 0.50baseTargetGDPLoss = targetGDP x (1 - (1 - targetGDPImpactPct)^durationYears)targetGDPLoss = baseTargetGDPLoss x fragilityMultipliercapitalFlight = baseCapitalFlight x (1 + ((fragilityMultiplier - 1) x 0.6))sanctions = aggressorGDP x additionalWarSanctionsPct x durationYearscommodityShock = sum_i(shock_i x livePriceScalar_i x sqrt(max(durationYears, 1)))
Notes: Live Comtrade trade volume overrides the static pair table when available. Oil, gas, and wheat shocks can scale with live FRED prices. ACLED can add a modest target fragility overlay to GDP loss and capital flight.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Humanitarian Model
The humanitarian module estimates displacement support, emergency healthcare, and direct casualty cost. It applies country-specific or regional UNHCR ratios for most scenarios, uses observed population-share calibration for sustained air campaigns, and prices casualties through a conservative GDP-per-capita human-capital method. The per-person-year support cost of $1,500 ≈ UNHCR average emergency response cost per displaced person covers humanitarian assistance and emergency healthcare.
displacementRatio = idpRatio + refugeeRatiopopulationAtRisk = skirmish && area > 100000 ? population x sqrt(100000 / area) : populationdisplacementShare = air_campaign ? scenarioDisplacementMultiplier : displacementRatio x scenarioDisplacementMultiplierbaseDisplaced = populationAtRisk x displacementSharedisplaced = round(baseDisplaced x fragilityMultiplier)displacementDuration = durationYears + min(durationYears x 1.5, 2)casualties = populationAtRiskMillions x durationDays x scenarioCasualtyRatehumanitarianTotal = displacementCost + casualtyCost
Notes: The module splits displaced people into IDPs and cross-border refugees according to the observed UNHCR ratio mix. ACLED can modestly scale displacement when recent target-country violence is already elevated. Direct casualty cost uses GDP per capita x 100 as a human-capital proxy, with injury cost set to 15% of VSL.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Reconstruction Model
Reconstruction is modeled as a sublinear function of GDP so that richer countries do not mechanically receive implausible rebuild bills just because their output base is larger. A 30% overlap discount is applied because part of the destruction is already expressed as lost GDP in the economic module.
effectiveGDP = 20B^(1 - 0.85) x targetGDP^0.85reconstruction = effectiveGDP x reconstructionRate x durationYears x 0.70infra = reconstruction x 0.40housing = reconstruction x 0.30services = reconstruction x 0.20economicRecovery = reconstruction x 0.10
Notes: The 20B reference point corresponds to the Afghanistan calibration point used in the code. Opportunity-cost widgets are derived from reconstruction totals but are displayed outside the main war total.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Armaments Model
The armaments module prices weapons procurement, munitions consumption, equipment attrition, and defensive intercept costs — four buckets that were absent from the original model. It uses live military expenditure from the World Bank API with SIPRI Milex as offline fallback, NATO equipment-percentage data to derive a procurement fraction, a static unit-cost table sourced from DoD annual budget documents, and scenario-based force-package tables calibrated to real conflicts.
budgetScalar = (aggressorMilBudget / $858B_US_ref) ^ 0.75forcePackageCost = Σ (qty_i × unitCost_i × budgetScalar)munitionsCost = Σ (perDayRate_i × durationDays × unitCost_i × budgetScalar)attritionCost = forcePackageCost × equipmentAttritionPctinterceptThreats = (threatsPerDay_scenario × targetMilBudget / $100B) × durationDays × 0.85interceptCost = interceptThreats × $395K_avg × budgetScalararmamentsTotal = forcePackageCost + munitionsCost + attritionCost + interceptCost
Notes: budgetScalar uses a power-law exponent of 0.75 (diminishing returns — larger budgets buy more but not linearly). Equipment fraction defaults to 20% of military spend for non-NATO states; NATO Table 8a values used when available. Unit costs cover 22 weapon categories from cruise missiles ($2M ≈ annual salary of 40 US teachers) to aircraft carriers ($13B ≈ GDP of Iceland). Intercept costs are anchored to CSIS Iran 2026 reporting: $1.7B in the first 100 hours, then checked against later reporting of roughly 700 ballistic missiles and 3,600 drones in the early campaign ($395K average per threat ≈ 5× cost of an Iron Dome Tamir intercept). Data sources: SIPRI Milex 2024 (135 countries), NATO Defence Expenditure 2025, Bruegel US Foreign Military Sales 2008–2025, DoD Program Acquisition Costs FY2024, GAO-24-106649 Ukraine Weapon Replacement Study.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Revenue Counterfactual
Revenue is not subtracted from the headline projected cost. It is shown as a deliberately optimistic counterfactual: what an aggressor might hope to extract if it wins, holds territory, and manages to keep production online despite sabotage, sanctions, and infrastructure damage.
annualResourceRevenue = worldMarketValue x targetShare x captureRategoldSeizure = targetGoldReserves x seizureRatedefenseStimulus = aggressorBudget x (intensityMultiplier - 0.5) x 0.30netPosition = revenueTotal - headlineCost
Notes: Capture rates are scenario-specific: 0% for skirmish, 15% for conventional war, and 50% for occupation. The code treats this section as best-case and low-confidence by design.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Aggregation and Uncertainty
The app does not run a Monte Carlo engine. Instead, each module defines its own conservative range. Headline cost and economic impact are aggregated separately, which keeps the accounting explicit and avoids folding macroeconomic spillovers into the top-line war bill.
headlinePoint = military + humanitarian + reconstruction + armaments
headlineMin = militaryMin + humanitarianMin + reconstructionMin + armamentsMin
headlineMax = militaryMax + humanitarianMax + reconstructionMax + armamentsMax
economicImpactPoint = economic (reported separately)
Scenario durations are normalized archetypes rather than event-specific backtests: 0.15 years for air_campaign, 0.2 years for skirmish, 1.5 years for conventional war, and 10 years for occupation at point estimate. Armaments ranges are wider than other modules due to force-package composition uncertainty.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Calibration — Operation Epic Fury (Iran, 2026)
On February 28, 2026, the United States and Israel launched a sustained air campaign against Iran. The first validation pass used Day 17 reporting; the late-April reassessment can now compare the model against a 38–39 day campaign and a ceasefire that took effect on April 8. The 17-day cost reached $14–16.5B ≈ what the US spends on Head Start for 3 years.
Conflict Profile
SORTIES│1,600+ in early reportingTARGETS│13,000+ struck over 39 daysOPENING│160+ Tomahawk cruise missilesRESPONSE│~700 ballistic missiles + ~3,600 drones (17 days)NATURE│Sustained air + naval campaign. No ground forces inside Iran.DAY 1–6│$11.3B direct cost (Pentagon, Senate briefing) ≈ annual military budget of DenmarkDAY 1–12│$16.5B direct cost (CSIS) ≈ Iran's annual education budgetDAY 20│$16.2–23.4B incremental cost (AEI via Axios)2 MONTH│$38–47B direct projection; $5B indirect excluded (PWBM) narrow federal spending onlyHUMAN│HRANA Day 39: 3,636 documented deaths; UN/HRA: ~3.2M displacedINTERCEPT│$1.7B in first 100 hrs (CSIS) ≈ 4,300 Patriot PAC-3 interceptors
Key Discovery: Cost Is Two-Sided
The CSIS breakdown of the first 100 hours revealed that defensive intercept costs ($1.7B ≈ 4 Nimitz-class refueling overhauls, 46%) exceeded offensive strike munitions ($1.5B, 40%) in the opening phase. The original model only priced what the aggressor spends attacking. The cost of neutralizing the counter-attack was entirely absent.
offensive munitions: $1.5B (40%)
defensive intercepts: $1.7B (46%)
equipment losses: $359M (10%)
operations & sustainment: $196M (5%)
Five Gaps Found — Five Fixes Applied
GAP 01│Defensive intercept costs — absent from modelFOUND│CSIS reported $1.7B in intercept costs in the first 100 hours — 46% of total direct spending. The first pass had no category for the cost of neutralizing incoming ballistic missiles and drones.FIX│Added a Defensive Intercepts line item to the armaments module. Incoming threat volume scales with target military budget × scenario threat rate. Average intercept cost $395K is calibrated from the Iran 2026 opening phase and later missile/drone reporting.
GAP 02│No air_campaign scenario — conflict fell in a gapFOUND│The four existing scenarios were precision_strike (days), skirmish (weeks), conventional (months with ground forces), occupation (years). Iran 2026 was none of these: a sustained air campaign lasting weeks to months with no ground component.FIX│Added air_campaign as a fifth scenario. Duration 18 days – 6 months (point 55 days). Operational spending remains conservative in the military module, while the air-specific aircraft, munitions, attrition, and intercept burden is priced in armaments. Displacement multiplier 4%, GDP impact 15%/year, capital flight 7%/year.
GAP 03│Humanitarian model built for slow conflicts — not air campaignsFOUND│The displacement-based model produced $14M for USA→Iran precision_strike. The real humanitarian cost by Day 17 was in the billions: 1,444 killed, 18,551 injured, 3.2 million displaced. No direct casualty cost existed in the model at all.FIX│Added a Direct Casualties line item using the WHO human-capital VSL method (GDP per capita × 100). Daily casualty rates by scenario calibrated to Iran 2026 (1.0 killed/M/day for air_campaign) and Iraq 2003 (5.0/M/day for conventional). Casualties now included in the humanitarian total.
GAP 04│Capital flight rates not calibrated for short air campaignsFOUND│CAPITAL_FLIGHT_PCT had entries for skirmish, conventional, and occupation but defaulted to 4% for precision_strike and the missing air_campaign. Iran's banking system was frozen and oil exports halted within days — a 7%+ flight rate, not 4%.FIX│Added explicit entries: air_campaign = 7%/year (banking freeze, oil export halt), precision_strike = 3%/year (short duration limits flight but investor panic is real).
GAP 05│Air-campaign displacement was double-dampedFOUND│The methodology intended air_campaign displacementMultiplier = 4% as an observed population share. The code multiplied that by Iran’s historical UNHCR displacement ratio again, yielding ~293K displaced for USA→Iran instead of the reported ~3.2M.FIX│For air_campaign only, displacementMultiplier is now treated as the calibrated population share. Other scenarios continue to use UNHCR historical ratios × scenario multiplier. USA→Iran air_campaign now produces ~3.7M displaced, close to the UN/HRA figure.
Pre / Post Results vs Late-April Data
SCENARIO│BEFORE → AFTER vs REALprecision_strike (18d)│$13.30B → $13.75B | real: $14–16.5B (Day 13–17)air_campaign (39d)│$52.26B → $53.61B | real: PWBM narrow direct: $27–28B Day 32, $38–47B Apr 30air_campaign (55d)│$58.17B → $60.06B | real: $38–47B two-month direct projection (PWBM)human toll (39d)│293K displaced → 3.7M displaced / 3.6K killed | real: ~3.2M displaced / 3.6K deathseconomic impact (39d)│$191.74B → $191.74B | real: $144B likely; $50–300B range (FDD)
Lesson: the original 18-day strike comparison still matched the early direct-cost snapshot, but late-April data makes the accounting boundary visible. Public US cost estimates are narrow federal military outlays; this calculator’s headline also includes humanitarian and reconstruction costs. The human-toll and economic-impact modules now match the updated evidence better than the direct military spending module, which remains high for the observed 39-day campaign.
Calibration Sources
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Audit Notes
This repository was checked against the shipped data files and the running model logic. The goal was not to prove truth, but to document what the current code can defensibly claim.
- Import-time JSON validation is enforced in validated.ts for bilateral trade pairs and commodity producer datasets, including schema shape, ISO alpha-3 keys, numeric bounds, and duplicate-pair normalization.
- The repository currently ships 75 bilateral trade pairs, 26 country displacement cases, 8 regional displacement defaults, 84 SIPRI entries, 14 static fallback countries, 8 sanctions regimes, and 32 commodity shock records.
- World Bank retrieval now requests the 10 most recent observations so the app can use the latest non-null value instead of defaulting to a fallback too early.
- The Iran calibration table uses reparameterized 39-day and 55-day comparisons. Other historical claims remain archetypal scenario checks rather than event-level backtests.
- When FRED is unavailable, the model remains runnable. Commodity shocks stay on 2023 baselines and the CPI scalar remains 1.0, which preserves deterministic behavior instead of fabricating live prices.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Scope Limits
Exclusions are a methodological choice rather than an omission. The model only prices what the code can currently source, parameterize, and explain line by line.
- Nuclear escalation, WMD use, and strategic deterrence failure.
- Cyber operations, satellite warfare, or electromagnetic-spectrum disruption costs.
- Population-scale trauma, long-run disability, and demographic scarring.
- Alliance activation, extended coalition war finance, and treaty spillovers.
- Environmental destruction, landmine clearance, and remediation of contaminated land or water.
- Brain drain, educational loss, and long-run human-capital depreciation.
- Shadow-economy disruption and illicit finance networks in already-sanctioned states.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Open Calculator → Start with the calculator for the result, then inspect each category line item, then return here for the underlying model assumptions and data pipeline.