- infrastructure.py: Add IODA (Georgia Tech) as fallback when Cloudflare
Radar returns 403 (no API token). Internet outage data now available
without CLOUDFLARE_API_TOKEN.
- conflict.py: Increase UCDP GED API timeout from 15s to 30s to handle
slow responses from ucdpapi.pcr.uu.se.
- dashboard/app.py: Add /api/report/pdf endpoint for PDF daily brief
export via weasyprint (optional dependency).
- pyproject.toml: Add dashboard + pdf optional deps, intel-dashboard
script entry point, update description for 55 tools.
- tests: Add 11 new tests covering health, sanctions, elections, shipping,
social, nuclear, infrastructure (IODA fallback + cable health), and
UCDP conflict. Fix cross-loop asyncio lock issue in conftest.
- Total: 50 tests passing, 55 tools verified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Alert banner moved right (left: 220px) to clear layers panel,
reduced strip size (0.58rem, 3px padding), text-overflow ellipsis.
Zoom controls pushed up 50px margin-bottom to clear bottom ticker.
Responsive rule for alert banner on small screens.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When both ACLED (no API key) and UCDP (timeout/empty) fail, the
dashboard now falls back to 22 pre-coded conflict hotspots from
INTEL_HOTSPOTS with severity levels (critical/high/moderate/low).
Frontend updated with 3-tier fallback: ACLED → UCDP → conflict_zones.
Marker sizing uses escalation level for hotspots, tooltips show severity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OpenSky anonymous access returns 429 consistently. Added adsb.lol
free community API (/v2/mil endpoint) as primary source with OpenSky
as fallback.
- _fetch_adsblol_military: dedicated military endpoint, no filtering needed
- _fetch_opensky_military: original OpenSky logic as fallback
- _icao_to_country: derives country from ICAO hex prefix (US, UK, FR, etc.)
- adsblol rate limit: 5s between calls (community API, be polite)
- Cache TTL increased to 300s for both sources
- bbox filtering applied client-side for adsb.lol data
Result: 127 military aircraft from multiple nations now visible on map.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- updateMapConflict supports both ACLED and UCDP data fields
(fatalities/best, event_type/type_of_violence_label)
- updateAll passes UCDP events when ACLED errors (no API key)
- HUD conflict pill also falls back to UCDP source
- Increased conflict marker limit from 100 to 200
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cache: add get_stale() for last-known-good fallback when APIs fail.
Fetcher: on API failure or tripped circuit breaker, serve stale cached
data instead of returning None — dashboards never go blank after first
successful fetch. Add per-source rate limits (11 sources configured).
Fix Yahoo Finance: compute change_pct from previousClose when
regularMarketChangePercent is absent (Yahoo v8 API change).
Fix health RSS: replace dead WHO DON/ProMED/CIDRAP URLs with working
WHO news, CDC outbreaks, and Outbreak News Today feeds.
Fix wildfires: extend FIRMS query from 1-day to 2-day (NRT data lag),
include nominal-confidence fires (was filtering to high-only).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: add 7 new data feeds to _fetch_overview() (33 total SSE streams).
Frontend: alert banner (critical/high/medium), health outbreak tracker,
election calendar with risk bars, shipping stress gauge, social signals
from Reddit, nuclear test site map layer with concern scoring, weekly
trends with anomaly tracking. New HUD pills for alerts, shipping stress,
outbreaks, nuclear flags.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New source modules: disease outbreaks (WHO/ProMED/CIDRAP), OFAC sanctions
search, election calendar with risk scoring, shipping stress index,
Reddit social signals, nuclear test site seismic monitor. Cross-domain
alert digest and weekly trend analysis. Registers orphaned space_weather
and ai_watch modules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 5 of world-intel-mcp: intelligence synthesis layer that makes raw
data actionable.
New modules:
- config/countries.py: 22 tier-1 countries with event multipliers, 22
intel hotspots, 9 strategic waterways, 6 conflict zones
- analysis/focal_points.py: detect convergence of signals on entities
using signal count, type diversity, and recency weighting
- analysis/temporal.py: Welford's algorithm + SQLite for streaming
anomaly detection with seasonal baselines (weekday+month)
Upgraded modules:
- analysis/instability.py: CII v2 with 4 weighted domains (unrest 0.25,
conflict 0.30, security 0.20, information 0.25), UCDP floors, event
multipliers. Full v1 backward compat preserved.
- analysis/signals.py: v2 aggregator accepts 7 data sources (added
outages, military, protests) with convergence scoring
- sources/intelligence.py: 3 new fetch functions (focal_points,
signal_summary, temporal_anomalies), instability upgraded to CII v2
3 new MCP tools: intel_focal_points, intel_signal_summary,
intel_temporal_anomalies. Total: 39 tools.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete v3 rewrite: full-viewport Leaflet map as primary interface
with glassmorphic floating panels. All geolocated events (earthquakes,
military aircraft, ACLED conflict, wildfire clusters, signal convergence)
are clickable map markers with detailed slide-in modals.
Design: Chakra Petch + Share Tech Mono typography, vignette overlay,
CSS custom properties, animated markers with pulse/glow on critical
events. Data drawer with sticky section headers for non-geospatial
data (markets, crypto, cyber, predictions, displacement). Scrolling
news ticker, HUD stat pills, layer toggle switches.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: wire stablecoin_status, etf_flows, acled_events, ucdp_events,
displacement, risk_scores, and signal_convergence into the SSE overview
endpoint (23 total feeds, up from 16).
Frontend: complete rewrite with 7-tab navigation (Overview, Markets,
Security, Conflict & Humanitarian, Natural & Climate, Geospatial Map,
Trend Charts), Leaflet dark-tile map with toggleable layers, Chart.js
rolling time-series, feed health counter, and DOMPurify sanitization.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Climate API may return zones as {zone_name: data} object instead of
array. Added Object.values() fallback to normalize both shapes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jinja2's |default(0) only replaces undefined, not None values from API
data. When used with comparison operators (>=) or format(), None causes
TypeError crashes. Replaced with Python `or` operator which handles
None correctly across market_overview.html (7 patterns) and
country_dossier.html (1 pattern).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
hexdb.io provides ICAO hex aircraft details with no API key required,
eliminating the 30-day trial limitation of Wingbits.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Parse FIRMS CSV column indices from header row instead of hardcoded
offsets. FIRMS added 'instrument' column, shifting confidence/frp.
- Fix cache key collision: _fetch_region and fetch_wildfires both used
'wildfire:fires:{region}' — now CSV uses 'wildfire:csv:{region}'.
- Add type guard for non-string input to _parse_fires_csv.
- Remove unused _CSV_COLUMNS constant.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>