73 Commits

Author SHA1 Message Date
Marc Shade 4528a6ed69 Fix dashboard startup and space weather parsing 2026-06-04 11:18:09 -04:00
Marc Shade 625788a830 Progressive SSE loading + Starlette 1.0 fix
Dashboard changes:
- SSE stream now emits per-source events as each API completes instead of
  waiting for all 47 sources to finish before rendering anything
- Map and UI appear within seconds; each data layer populates progressively
- Loading indicator shows feed progress (LOADING FEEDS 12/47)
- Spinner hidden after first 3 sources arrive

Backend (app.py):
- Replaced monolithic _fetch_overview gather with asyncio.Queue-based
  progressive emission — each source fires as a task, results stream
  to the client as they complete
- Fixed Starlette 1.0 incompatibility: replaced removed on_startup kwarg
  with asynccontextmanager lifespan pattern
- Added proper vector store shutdown in lifespan teardown

Frontend (index.html):
- SSE handler now accumulates partial events into _accumulatedData
- Each incoming source merges and triggers updateAll() progressively
- Backwards compatible with legacy full-payload mode
2026-04-06 19:07:42 -04:00
Marc Shade bfe89f4f7a Harden fetcher + add live smoke tests
- Exponential backoff: retry waits are now 1s, 2s, 4s (was linear 1s, 2s, 3s)
- Cache poisoning prevention: validate Content-Type is not HTML before JSON parse,
  reject non-dict/list responses before caching
- Add 18 live smoke tests against real public APIs (USGS, CoinGecko, Yahoo Finance,
  SEC EDGAR, FAA, NOAA SWPC, Hacker News, NASA EONET, etc.)
- Smoke tests excluded from default pytest run; opt-in with: pytest -m smoke
- All 220 unit tests + 18 smoke tests pass
2026-04-06 18:53:03 -04:00
Marc Shade 29ebccf80b Tighten pyproject.toml deps to match requirements.txt pins (mcp >=1.8, pydantic >=2.10, httpx with socks) 2026-04-06 14:39:38 -04:00
Marc Shade 2e2e94c11f Add .gitignore 2026-04-06 14:28:46 -04:00
Marc Shade 26571cfac2 feat: add daily gas prices (AAA), electricity rates, natgas + dashboard deltas
- Replace EIA weekly gasoline with AAA daily scraper (gasprices.aaa.com)
  - urllib-based fetch (Cloudflare blocks httpx), cached 30min
  - 5 grades: regular, mid-grade, premium, diesel, E85
  - Day-over-day, week, month, year-over-year deltas
  - 51 state-level regular prices
- Add EIA electricity retail rates (residential/commercial/industrial)
- Add EIA residential natural gas prices (monthly)
- Dashboard: all energy sections show change indicators (DoD/WoW/MoM)
- Dashboard: vector panel moved to right:360px (was covering zoom controls)
- Dashboard: fix pre-existing num() → fmtNum() bug in BTC technicals
- 3 new tools: intel_gas_prices, intel_residential_natgas, intel_electricity_rates
- CLI: gas-prices, natgas, electricity commands
- Collector: 3 new source entries
- Tests: 8 new tests (AAA parse, electricity, natgas, edge cases)
2026-03-08 21:05:24 -04:00
Marc Shade 4b08dda62a fix: add missing _withinTimeWindow function (broke earthquakes + news layers) 2026-03-08 13:51:01 -04:00
Marc Shade b5b83a58d0 fix: connection pool saturation causing dashboard all-zeros
- Increase httpx pool from 50 to 200 connections (140+ concurrent requests)
- Add semaphore(25) to RSS feed fetcher (119 feeds no longer flood the pool)
- Give slow sources (news, alerts, posture) 90s timeout instead of 45s
- Result: 56/58 sources OK, 0 timeouts (was: everything timing out)
2026-03-08 13:42:05 -04:00
Marc Shade 75d29d2ae7 docs: fix ROADMAP tool inventory (110/110) and test count (344) 2026-03-08 13:17:06 -04:00
Marc Shade 346e26deb1 feat: Phase 18 — PDF/HTML intelligence reports (110 tools, 344 tests) 2026-03-08 11:11:21 -04:00
Marc Shade 1a2630381c refactor: top-level qdrant imports with fallback stubs, error handling wrappers, roadmap sync 2026-03-08 10:45:45 -04:00
Marc Shade bb3217bfea feat: add Vector Intelligence panel to dashboard
- SSE endpoint /sse/vector-analytics: pushes stats, domain summary,
  trend detection every 30s via asyncio.gather()
- POST /api/vector-search: semantic search with query, hours, category filters
- Glassmorphic Vector Intelligence panel (bottom-left):
  - Total vector points + collection status
  - Per-category data point counts (top 12)
  - Trend tags: SURGE (red), ELEVATED (orange), NORMAL (green), DROP (blue)
  - Inline semantic search with score-ranked results
- Graceful degradation when Qdrant unavailable (panel stays hidden)
- All innerHTML uses safe() wrapper (DOMPurify)
2026-03-08 10:34:31 -04:00
Marc Shade caa681e78f feat: add collector launchd service and 98 vector store tests
- com.agentic.intel-collector.plist: launchd config for 24/7 data collection
- scripts/collector-daemon.sh: start/stop/restart/status/logs control script
- test_vector_store.py: 49 tests (98 with trio) covering all vector methods
  - store, semantic_search, find_similar, timeline, collection_stats
  - cross_domain_correlate, domain_summary, trend_detection
  - data_to_text, content_hash, domain_categories, extract_geo
  - All mocked (no Qdrant/FastEmbed runtime dependency)
- Total: 284 tests passing
2026-03-08 10:34:10 -04:00
Marc Shade c8e344f3f5 docs: reorganize README — proper tool categorization, add LICENSE, fix table rendering
- Replaced catch-all 'Other Domains' (26 tools) with 15 proper sections
- Added missing intel_climate_anomalies to documentation
- Fixed 'What You Get' summary table (blank row broke GitHub rendering)
- All 109 tools verified: no duplicates, no gaps
- Added MIT LICENSE file (was referenced by badge but missing)
- Fixed architecture diagram alignment
2026-03-08 10:22:19 -04:00
Marc Shade 306173c0ec feat: add cross-domain analytics — correlation, domain summary, trend detection (109 tools)
- intel_cross_correlate: finds related signals across all domains for a topic,
  groups by category, shows how events ripple across intelligence streams
- intel_domain_summary: per-category aggregate of stored intelligence with
  data point counts, unique sources, latest/earliest timestamps
- intel_trend_detection: compares recent vs baseline activity rates per
  category, identifies SURGE/ELEVATED/DECLINING/DROP patterns for early warning
- All three leverage accumulated Qdrant vector store data
- 109 tools total across 30+ domains
2026-03-08 10:15:53 -04:00
Marc Shade 094f37d443 feat: add collector daemon and 5 vector search tools (106 total)
- collector.py: standalone daemon for 24/7 vector store population
  - 43 sources organized by domain with parallel fetching
  - --daemon, --interval, --sources CLI args
  - Dynamic import via _import_fetch_fn()
  - Entry point: intel-collector
- server.py: 5 new MCP tools (intel_semantic_search, intel_similar_events,
  intel_timeline, intel_vector_stats, intel_collect)
- pyproject.toml: vector optional dependency (qdrant-client + fastembed)
- README.md: updated architecture, vector store section, tool reference
- CLAUDE.md: updated tool count and architecture docs
2026-03-08 10:05:06 -04:00
Marc Shade 8b2aa3fd64 fix: add granular source name mappings to vector store categories 2026-03-08 09:35:12 -04:00
Marc Shade bc75cf46f7 feat: add Qdrant vector store for enterprise-grade semantic intelligence
Phase 16: Vector intelligence (+3 tools = 104 total)

New tools:
- intel_semantic_search: Natural language search across all stored intelligence
- intel_similar_events: Find historically similar events for pattern matching
- intel_timeline: Chronological timeline of stored data with domain filtering

Architecture:
- vector_store.py: Qdrant client with FastEmbed (ONNX, bge-small-en-v1.5)
- Background worker queue (asyncio) for non-blocking storage
- Auto-populates from every Fetcher.get_json() call
- 40+ domain categories mapped for filtered search
- Graceful degradation: vector store is optional, all 101 existing tools work without it

Integration:
- Fetcher: new vector_store parameter, stores data after each successful fetch
- server.py: vector store init + worker lifecycle + 3 dispatch cases
- dashboard/app.py: vector store worker starts on dashboard boot
- intel_status: now includes vector store statistics
- pyproject.toml: [vector] optional dependency (qdrant-client, fastembed)

186/186 tests passing.
2026-03-08 09:29:43 -04:00
Marc Shade a43d07cb3e fix: enrich conflict zone fallback with country names, actors, and dates
When both ACLED and UCDP fail, the dashboard falls back to static
INTEL_HOTSPOTS data. Previously the fallback events had empty fields
(country, location, actors, date, source, notes). Now maps ISO codes
to country names via TIER1_COUNTRIES, populates all fields the
frontend modal expects, and includes escalation severity labels.
2026-03-08 09:02:32 -04:00
Marc Shade b01a77721b docs(world-intel): update README and CLAUDE.md for 101 tools 2026-03-08 08:24:45 -04:00
Marc Shade baba564b84 feat(world-intel): Phase 15 — business intelligence tools (101 total)
Add 12 new tools across 6 domains:
- Forex: intel_forex_rates, intel_forex_timeseries, intel_major_crosses (ECB/Frankfurter)
- Bonds: intel_yield_curve, intel_bond_indices (FRED + Yahoo Finance fallback)
- Earnings: intel_earnings_calendar, intel_earnings_surprise (Yahoo Finance)
- SEC: intel_sec_filings, intel_company_filings, intel_recent_8k (SEC EDGAR)
- Company: intel_company_profile (composite: Yahoo + GDELT + SEC + GitHub)
- Macro: intel_macro_composite (weighted score from 6 signals)

New source modules: forex.py, bonds.py, earnings.py, sec_edgar.py
New analysis modules: company.py, macro_composite.py
66 new tests (186 total, all passing)
All free public APIs, no API keys required.
2026-03-08 08:22:41 -04:00
Marc Shade d075bbaf1a feat: phase 16 — country dossier, 89 tools, 119 RSS feeds, 53 tests
- Add intel_country_dossier: comprehensive 6-source country analysis
  (economy, markets, elections, sanctions, news, security) in parallel
- Expose 4 hidden sources as MCP tools: intel_traffic_flow,
  intel_traffic_incidents, intel_aviation_domestic, intel_webcams
- RSS feeds expanded from 100 to 119 across 24 categories (+6 new:
  central_asia, arctic, maritime, space, nuclear, climate)
- CLI expanded from 44 to 49 commands (dossier, traffic, incidents,
  air-traffic, webcams)
- Tests expanded from 45 to 53 covering all new Phase 16 tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:55:47 -05:00
Marc Shade a5a1e207a7 feat: phase 15 — 100 RSS feeds, 45 tests, 44 CLI commands, keyboard shortcuts
- Tests: 14 new tests for Phase 13-14 tools (BTC technicals, central
  banks, USNI fleet, trade routes, cloud regions, financial centers)
- RSS feeds: 70→100 across 18 categories (added Europe, South Asia,
  Health, expanded Africa, think tanks, science, energy, security)
- Dashboard: 16 keyboard shortcuts with help overlay (?), layer toggles
  (1-9,0), zoom (+/-), fullscreen (f), toggle all (a), layer panel (l)
- CLI: 25→44 commands covering all major tool domains (btc, central-banks,
  shipping, social, disease, elections, nuclear, space, sanctions,
  ai-watch, fleet, hn, gh-trending, arxiv, spending, bases, exchanges)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:40:49 -05:00
Marc Shade 4dda867968 feat: phase 14 — BTC technicals, central bank rates, 3 datasets, dashboard UX (+5 = 84 tools)
New tools:
- intel_btc_technicals: SMA-50/200, Mayer Multiple, golden/death cross, ATH distance
- intel_central_bank_rates: 15 banks (Fed/ECB/BoE via FRED, 12 curated fallback)
- intel_trade_routes: 19 maritime chokepoints with oil flow and vessel transit data
- intel_cloud_regions: 28 AWS/Azure/GCP regions with coordinates
- intel_financial_centers: GFCI top 20 with rankings and specializations

Dashboard additions:
- BTC Technicals drawer section (price, SMA, Mayer, cross signal)
- Central Bank Rates drawer section (15 banks, sorted by rate)
- Trade route markers on infrastructure map layer (chokepoint/canal/route icons)
- Regional presets (Globe/Americas/Europe/MENA/Asia-Pac/Africa) with localStorage persistence
- Time window filter (1h/6h/24h/7d/All) filtering earthquakes and news by timestamp
- Static datasets served via /api/static for instant boot

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:04:17 -05:00
Marc Shade 39e687b054 feat: phase 13 — USNI fleet tracker, RSS expansion, remove static reports
- Add intel_usni_fleet tool: parses USNI News Fleet Tracker RSS for
  Navy fleet disposition (ships, hull numbers, strike groups, regions)
- Expand RSS to 90+ feeds across 16 categories: +3 Latin America
  (InSight Crime, Brazil Reports, Mexico News Daily), +7 multilingual
  (BBC Mundo, DW ES/DE, France24 FR, RFI, UN News ES/FR)
- Add data freshness monitoring: per-source staleness in dashboard
  drawer via cache.freshness() and SSE stream
- Add USNI Fleet Tracker drawer section to dashboard
- Remove static HTML report system (reports/ dir, 3 MCP tools,
  4 CLI commands, PDF endpoint) — live dashboard replaces all
- Update ROADMAP.md: phases 1-11 complete, 80 tools, 15 datasets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:41:38 -05:00
Marc Shade 6075910505 feat: phase 12 — 68→81 tools, 5 geospatial datasets, 5 new sources, news ticker fix
New static datasets (config/):
- cables.py: 34 undersea fiber-optic cables with landing points, capacity, owners
- datacenters.py: 48 AI datacenter clusters with power capacity (MW)
- spaceports.py: 27 launch facilities worldwide
- minerals.py: 27 critical mineral deposits (lithium, cobalt, rare earths, etc.)
- exchanges.py: 82 stock exchanges across 4 tiers with country→ticker mapping

New source modules (sources/):
- hacker_news.py: HN Firebase API top stories
- github_trending.py: GitHub search API trending repos
- arxiv_papers.py: arXiv Atom API with regex XML parsing
- usa_spending.py: USAspending.gov federal agency budgets
- environmental.py: NASA EONET natural events + GDACS disaster alerts

Extended existing modules:
- markets.py: fetch_country_stocks() — any country by ISO-3 code
- military.py: fetch_aircraft_details_batch() — parallel batch lookup (max 20)
- geospatial.py: 5 new fetch functions for cables, datacenters, spaceports, minerals, exchanges
- circuit_breaker.py: per-source configurable thresholds
- cache.py: freshness() method for per-source staleness tracking

Fixed news ticker (News 0 → News 17+):
- Root cause: RSS feeds fetched sequentially by category (14 categories × slow feeds = timeout)
- Fix: single asyncio.gather() for all 80+ feeds with 12s per-feed hard timeout
- Reduced per-request HTTP timeout from 15s to 8s for RSS feeds

13 new tools wired in server.py, 14 new tests (76 total, all passing).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:05:44 -05:00
Marc Shade 986f79fb8f docs: update README hero image with live 14-layer dashboard screenshot
Captured via Playwright with live SSE data showing all 14 map layers,
HUD stats, alert banner, drawer with posture/markets/crypto, and
the full layer panel including new Climate and News layers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:33:12 -05:00
Marc Shade fc915be90a feat: news geolocation map layer with 75-country centroid lookup
Client-side geolocation scans article titles/summaries for country
mentions and plots them at country centroids with jitter. Integrated
into layer toggles, search, HUD click-to-zoom, and detail panel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:26:04 -05:00
Marc Shade b9eb85bb64 fix: layer panel + alert banner positioning below dynamic topbar
_syncLayersTop() now measures both topbar height and alert banner,
positioning layers panel below both. Alert banner also uses
--layers-top CSS var so it tracks topbar height changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:22:35 -05:00
Marc Shade a65a84523f feat: climate overlay layer, adaptive topbar, mobile layer panel
- Climate map layer: 15 zones with temp-anomaly colored markers (hot/warm/cool/cold)
  with significance animation and full detail panel
- Topbar: flex-wrap with max-height cap on HUD pills, dynamic --layers-top CSS var
  ensures layer panel never overlaps topbar regardless of row count
- Mobile: collapsible layer panel (tap title to expand/collapse)
- Search and HUD pill click-to-zoom extended for climate layer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:11:41 -05:00
Marc Shade e68bef3104 feat: search, layer persistence, drawer collapse, HUD click-to-zoom, webcam auto-refresh
- Search: type country/city/keyword to zoom map to matching markers
  - ISO3→name mapping for 40+ countries (search "ukraine" matches UKR)
  - Searches all data sources: earthquakes, military, conflict, fires, webcams, bases, etc.
  - / keyboard shortcut to focus search, Esc to clear
  - Visual feedback: cyan border on match, red on no match
- Layer persistence: toggle states saved to localStorage, restored on reload
- Drawer section collapse: click any section header to collapse/expand
  - Collapsed state persists across SSE updates and page reloads via localStorage
  - 19 collapsible sections with rotate indicator
- HUD pill click-to-zoom: click any stat pill to zoom map to that layer's markers
  - Auto-enables layer if toggled off
- Webcam auto-refresh: preview image refreshes every 15s while detail panel is open
  - Interval properly cleared on panel close (no memory leak)
- Webcam drawer items now clickable (opens detail panel with preview)
- Loading state: spinner + "LOADING LIVE FEEDS" shown until first SSE data arrives
- Fixed keyboard shortcuts: D toggle now properly uses drawer 'closed' class
- Fixed drawer event delegation: attached once at boot instead of re-adding every 30s SSE update

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:11:08 -05:00
Marc Shade a6427dfe08 feat: marker clustering, cable corridor click-through fix, keyboard shortcuts
- Marker clustering (leaflet.markercluster) for air traffic, military,
  conflict, wildfires, and nav warnings — clusters expand on click
- Cable corridor rectangles set to interactive:false so clicks pass
  through to markers underneath (fixes blocked clicks in Med/Middle East)
- Batch addLayers() for air traffic performance with 9500+ markers
- Keyboard shortcuts: Esc closes panels, D toggles drawer, R resets view
- Custom dark-theme cluster styles with per-layer color coding

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:51:58 -05:00
Marc Shade 907351ed30 feat: webcam preview images in detail panel + unique layer indicator colors
- Webcam clicks now show the live camera feed image from Windy API
- Added img to DOMPurify allowed tags for preview rendering
- Road Traffic layer dot → white (#e0e0e0), Webcams → grey (#909090)
- All 12 layers now have visually distinct indicator colors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:13:06 -05:00
Marc Shade 54e4f5935e fix: detail panel for new map layer markers (air traffic, traffic, webcams, nav warnings)
Map marker clicks were showing headers but empty bodies because the type
handlers were only in showDrawerDetail, not the primary showDetail function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:56:25 -05:00
Marc Shade 966ce83eae fix: auto-load .env via python-dotenv for dashboard API keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:42:15 -05:00
Marc Shade 994d1d4c91 feat: add 4 new map layers — air traffic, road traffic, nav warnings, webcams
- Air Traffic: sample every 10th aircraft from OpenSky for ~950 map markers
- Nav Warnings: parse DD-MM.mmN DDD-MM.mmW coordinates from NGA warning text
- Road Traffic: TomTom city congestion circles (when API key set)
- Webcams: Windy camera positions (when API key set)
- 12 toggleable layers total (up from 8)
- Detail panels for all new marker types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:01:21 -05:00
Marc Shade fcc702b093 feat: domestic flights, road traffic, CCTV webcams, AI situation brief
Four new intelligence domains for the dashboard:

1. Domestic flights (OpenSky) — global airborne aircraft count by
   region with commercial/general breakdown. No API key needed.

2. Road traffic (TomTom) — real-time congestion % for 20 major world
   cities + traffic incidents in 5 strategic regions. Needs
   TOMTOM_API_KEY (free 2500 req/day at developer.tomtom.com).

3. CCTV webcams (Windy) — public traffic camera locations worldwide.
   Needs WINDY_API_KEY (free 100 req/day at api.windy.com).

4. AI situation brief (Ollama) — LLM-generated 3-paragraph
   intelligence brief synthesizing all dashboard data. Uses local
   Ollama (llama3.2). Falls back to structured metrics summary.

New files: sources/traffic.py, sources/webcams.py, analysis/situation.py
Modified: sources/aviation.py (+fetch_domestic_flights), dashboard/app.py,
dashboard/index.html (drawer sections + HUD pills for all 4 domains).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 11:46:19 -05:00
Marc Shade fc105872e2 fix: update UCDP GED API to v25.1 + add token auth support
UCDP now requires x-ucdp-access-token header (previously open access).
Updated from v24.1 to v25.1 (latest stable). Token passed via
UCDP_ACCESS_TOKEN env var; gracefully degrades to 0 events without it
(conflict zone fallback uses static INTEL_HOTSPOTS).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 11:36:26 -05:00
Marc Shade 0775102ed3 feat: migrate ACLED API from deprecated key/email to OAuth2 Bearer tokens
ACLED retired api.acleddata.com and moved to acleddata.com/api/ with
OAuth2 password-grant authentication. New flow:
- POST to /oauth/token with email+password → Bearer token (24h TTL)
- Automatic refresh via refresh_token (14-day TTL)
- Module-level token cache with async lock

Shared acled_query() helper in conflict.py used by all 9 call sites
in intelligence.py. Env vars: ACLED_EMAIL + ACLED_PASSWORD (replaces
ACLED_ACCESS_TOKEN).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 11:11:06 -05:00
Marc Shade 59451ce9f6 fix: header bar fire count shows cluster count instead of raw 74k detections
Matches the sidebar fix — computes cluster count from fires_by_region
top_clusters rather than displaying total_fires (raw FIRMS detections).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:51:13 -05:00
Marc Shade be452eb7d9 fix: wildfire counter shows cluster count, cable corridor antimeridian split
Wildfire sidebar counter now shows rendered cluster markers (180) instead
of raw FIRMS detections (74,901); raw total preserved in tooltip.

Transpacific cable corridor rectangle split into two halves at the
antimeridian so it renders over the Pacific instead of across landmasses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:44:08 -05:00
Marc Shade 71fbb1cda4 feat: waterway diamonds, cable corridor zones, cache resilience
- Render 9 strategic waterway chokepoints as cyan diamond markers
  (Hormuz, Malacca, Suez, Panama, Bab-el-Mandeb, Taiwan, Gibraltar,
  GIUK Gap, Bosphorus) with throughput tooltips
- Render 6 submarine cable corridors as dashed blue rectangles
  (transatlantic N/S, transpacific, asia-europe, red sea, med)
- Add waterways + cable_corridors to /api/static and SSE payloads
- Make cache.set() and evict_expired() swallow sqlite3 write errors
  instead of crashing callers (fixes "readonly database" in dashboard)
- Infrastructure layer: 134 → 173 items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:37:03 -05:00
Marc Shade 95b149ad55 fix: replace 22 dead/blocked RSS feeds with working alternatives
Tested all 80+ RSS feeds — 22 returned 403/404/timeout. Changes:
- AP Top News: rsshub → feedx.net (working wire proxy)
- Reuters World: reutersagency.com → Google News RSS filter
- Defense One: /rss/ → /rss/all/ (correct endpoint)
- Military Times replaces Stars and Stripes (404, no RSS found)
- The National UAE: /rss → Arc outbound feed (working)
- Nikkei Asia: /rss → /rss/feed/nar (working)
- Lowy Interpreter replaces East Asia Forum (403 WAF block)
- Dialogo Americas replaces Americas Quarterly + Brazil Wire
- Remove 13 dead feeds with no working replacement:
  Threatpost, CSIS, CFR, Chatham House, Atlantic Council, IISS,
  Al Monitor, ACAPS, EU External Action, NATO News,
  Energy Intelligence, The Africa Report, African Arguments

Reduces feed count from 80 to 62, eliminating wasted timeout cycles
that were blocking the dashboard SSE first frame.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:26:47 -05:00
Marc Shade a72fdc50f7 fix: dashboard instant boot, pipeline map layer, theater data bugs
- Add /api/static endpoint for instant geospatial data on boot (158 items)
- Add per-coroutine 45s timeout to prevent SSE first-frame blocking
- Dismiss loading overlay after static fetch instead of waiting for SSE
- Render 24 oil/gas/hydrogen pipelines as colored polylines on map
- Fix theaters dict-vs-list bug in posture.py and fleet.py
- Add exposure detail modal and color/label entries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:09:14 -05:00
Marc Shade 2d1c95389a fix: wildfire data parsing + dashboard cascade failure protection
Population exposure was showing 0 because exposure.py parsed wildfire
data using wrong keys ("regions" instead of "fires_by_region", "detections"
instead of "top_clusters"). Now correctly matches NASA FIRMS response format.

Dashboard updateAll() now wraps each map/UI update in try/catch to prevent
a single failed layer from blocking all subsequent layer renders.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 09:36:29 -05:00
Marc Shade de2cbeaa1a feat: add strategic synthesis to dashboard map + drawer
- Strategic Posture section (top of drawer): composite score, 9 domain
  grid with color-coded scores, top 5 threats
- Fleet Report section: readiness score/level, waterway status table,
  aircraft count, active surges
- Population Exposure map layer: circle markers sized by population,
  colored by threat type (red=conflict, orange=quake, yellow=fire)
- Population Exposure drawer section: total exposed, by event type,
  city table with distance
- HUD pills: Posture score + Exposed population
- Layer toggle for Pop Exposure (purple, default on)
- Backend: exposure API now includes lat/lon for map rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 09:21:03 -05:00
Marc Shade 2969dfc950 feat: add strategic synthesis layer — Phase 11 (+4 = 68 tools)
- intel_strategic_posture: composite risk from 9 weighted domains
  (military, political, conflict, infrastructure, economic, cyber,
  health, climate, space) with per-domain scoring and top threats
- intel_world_brief: structured daily intelligence summary aggregating
  posture, focal points, news clusters, anomalies, trending threats
- intel_fleet_report: naval fleet activity combining theater posture,
  waterway status, military surge, and readiness scoring
- intel_population_exposure: population at risk near active events
  (earthquakes, wildfires, conflict) using 105-city dataset (1B pop)

New files: analysis/posture.py, analysis/world_brief.py,
analysis/exposure.py, sources/fleet.py, config/population.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 09:02:14 -05:00
Marc Shade 7359c03275 docs: update all docs for 64 tools, Phase 9 NLP complete
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 08:44:28 -05:00
Marc Shade 69f1a6d44f feat: NLP intelligence — entity extraction, classification, clustering, spikes (+4 = 64 tools)
Phase 10: News Intelligence & NLP
- intel_extract_entities: Regex-based NER for countries, leaders, orgs,
  companies, CVEs, APT groups (28 leaders, 41 orgs, 25 companies, 36 APTs)
- intel_classify_event: Keyword-based threat classification into 14
  categories with severity scoring (1-10)
- intel_news_clusters: Jaccard similarity topic clustering for news
  articles with keyword extraction
- intel_keyword_spikes: Welford's algorithm baseline comparison with
  CVE/APT pattern extraction from headlines

No new dependencies — all pure Python with regex and SQLite.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 08:41:40 -05:00
Marc Shade 2aa5fd1425 fix: replace iframe modal with window.open for external links
Iframes blocked by most sites (X-Frame-Options/CSP). External links
now open in a new tab via window.open with noopener,noreferrer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 08:17:54 -05:00