|
1 | | -# Release - v1.0.6 - Thermal Watch |
| 1 | +# Release — v1.0.7 — Security Hardening & Intelligence Accuracy |
| 2 | + |
| 3 | +**Released:** 2026-04-18 |
| 4 | +**Type:** Patch |
| 5 | +**Previous:** v1.0.6 |
| 6 | + |
| 7 | +--- |
2 | 8 |
|
3 | 9 | ## Summary |
4 | 10 |
|
5 | | -v1.0.6 delivers the FIRMS thermal intelligence layer and dark-vessel anomaly engine to operators, resolves the two hold items that blocked the v1.0.6 candidate, and closes out a sweep of backend ingestion reliability fixes. The ISS ground-track now updates live in the animation loop and renders cleanly after container restarts. Fire hotspot data is now sourced globally by design, while the thermal layer starts off by default to reduce initial map noise. |
| 11 | +v1.0.7 ships a high-priority security patch alongside a set of runtime stability fixes and a significant accuracy improvement to the Active Conflict Zone intelligence engine. Operators on HTTPS deployments will also see mixed-content WebSocket and WebSDR iframe errors resolved. |
| 12 | + |
| 13 | +--- |
| 14 | + |
| 15 | +## Key Changes |
| 16 | + |
| 17 | +### 🛡️ Security |
| 18 | + |
| 19 | +- **SSRF Fix — News Article Reader** *(HIGH)* |
| 20 | + The `/api/news/article` reader endpoint now blocks requests to private/loopback addresses (`127.0.0.1`, `192.168.x.x`, `169.254.x.x`, etc.) and non-HTTP schemes before making any outbound connection. This closes a Server-Side Request Forgery vector that could have allowed authenticated operators to probe internal services. |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +### 🎯 Active Conflict Zone Accuracy |
| 25 | + |
| 26 | +The ACTIVE CONFLICT ZONES panel previously showed `[0]` almost always, even with active warzones (Ukraine, Israel, Sudan) appearing in the actor feed. Root cause: the old Goldstein thresholds were calibrated against an idealised model rather than real GDELT data distributions. |
6 | 27 |
|
7 | | -## Key Features |
| 28 | +**What changed:** |
| 29 | +- CRITICAL threshold: `≤ −6.0` → **`≤ −4.5`** (Ukraine/Gaza cluster at −3 to −5) |
| 30 | +- ELEVATED threshold: `≤ −3.0` → **`≤ −2.0`** |
| 31 | +- New **material-conflict volume shortcut**: actors with >150 kinetic events → CRITICAL; >50 → at least ELEVATED (prevents dilution by high diplomatic-media volume) |
| 32 | +- **MONITORING-level actors** now appear in the conflict zone panel with a yellow `WATCH` badge, so operators see the full threat spectrum instead of just the top tier |
8 | 33 |
|
9 | | -- **NRT NASA FIRMS Thermal Layer** — VIIRS/MODIS thermal infrared hotspots on the tactical map with FRP-scaled radii and confidence-coded colors. |
10 | | -- **Dark Vessel Anomaly Detection** — Backend engine cross-references FIRMS heat signatures against AIS vessel positions. Vessel-scale hotspots with no AIS broadcast within 5nm/2h are surfaced as anomaly candidates. |
11 | | -- **FIRMS Source Health Visibility** — Operations surfaces now show compact per-source FIRMS ingest summaries so NOAA-20, NOAA-21, and SNPP drift can be diagnosed without container log inspection. |
12 | | -- **Live ISS Ground Track** — WebSocket-delivered positions now normalise Unix integer timestamps to ISO-8601 on arrival, keeping the orbital trail current in the animation loop. |
13 | | -- **ISS Track Gap Detection** — Consecutive positions separated by >10 minutes start a new path segment, eliminating the distorted line artifact after container restarts. |
| 34 | +--- |
14 | 35 |
|
15 | | -## Bug Fixes |
| 36 | +### 🔧 Runtime Stability |
16 | 37 |
|
17 | | -- FIRMS thermal visibility now defaults to `false`, while dark-vessel anomalies remain enabled and FIRMS coverage stays global. |
18 | | -- FIRMS poller health now distinguishes healthy, empty, and failed upstream source responses instead of silently reporting partial upstream degradation as healthy. |
19 | | -- ISS live-track timestamps normalised at the hook boundary (`useISSTracker`) so all sources (WebSocket, REST, DB) produce trail points that pass the `buildISSLayer` filter. |
20 | | -- ISS track gap rendering fixed in `splitTrackAtAntimeridian`. |
21 | | -- SatNOGS pagination loop indentation corrected; PeeringDB IXP coordinates recovered from facility centroids; IODA Nominatim geocoder restored. |
| 38 | +- **AI Model Overload Advisory** — Analyst Panel now shows an amber "Model Overloaded" notice instead of silently presenting heuristic fallback text when the LLM provider returns `503 / high demand`. |
| 39 | +- **SatNOGS Timeout Resilience** — One retry added for transient station fetch timeouts; timeout vs. network failures now distinguished in response metadata. |
| 40 | +- **HTTPS WebSocket Fix** — Shared URL resolver promotes `ws://`/`http://` build-time endpoints to same-origin secure paths when the app is served behind TLS. Eliminates mixed-content failures on HTTPS deployments. |
| 41 | +- **WebSDR HTTPS Iframe** — WebSDR receiver iframes are now HTTPS-upgraded on secure pages; original HTTP URL preserved as an external link fallback. |
| 42 | +- **FIRMS Poller** — Normalized legacy `VIIRS_SNPP_NR` alias; fixed empty-cache cooldown guard that caused tight re-poll loops. |
| 43 | +- **News Feed** — DefenseNews removed from the default feed set (intermittent non-standard HTTP status). |
22 | 44 |
|
23 | | -## Technical Details |
| 45 | +--- |
24 | 46 |
|
25 | | -- TimescaleDB migration **V004** adds `firms_hotspots` hypertable and `dark_vessel_candidates` table. |
26 | | -- `space_pulse` cadence policy: daily TLE refresh gated on UTC hour, FIRMS/space-weather cadence persisted in Redis across restarts. |
27 | | -- FIRMS no longer supports a mission-vs-global ingest mode; the poller always uses the NASA world endpoint and `FIRMS_BBOX_MODE` is no longer part of the runtime configuration. |
28 | | -- FIRMS source-cycle snapshots are now published to Redis under `firms:source_status` and surfaced through `/api/config/poller-health`. |
29 | | -- No breaking API or schema changes, no new required environment variables. |
| 47 | +### ⚙️ Configuration |
| 48 | + |
| 49 | +- **GDELT Conflict Keywords** — Now configurable via `GDELT_CONFLICT_KEYWORDS` env var without a code change. |
| 50 | +- **ReliefWeb App Name** — Now configurable via `RELIEFWEB_APPNAME` env var. |
| 51 | +- **nginx-spa.conf** — `index.html` is no longer cached, reducing stale-bundle issues after deploys behind CDNs. |
| 52 | + |
| 53 | +--- |
| 54 | + |
| 55 | +## Technical Notes |
| 56 | + |
| 57 | +- No database migrations — no schema changes in this release. |
| 58 | +- No new environment variables are mandatory; all new vars have sensible defaults matching previous behaviour. |
| 59 | +- The `sovereign-backend` container should be rebuilt to pick up AI overload handling, SatNOGS, and news changes. |
| 60 | +- The `sovereign-gdelt-pulse` container should be rebuilt to pick up the conflict-filter and ReliefWeb config changes. |
| 61 | +- The `sovereign-space-pulse` container should be rebuilt to pick up the FIRMS poller alias fix. |
| 62 | +- Frontend: no rebuild required for already-deployed prod builds if served via nginx (nginx-spa.conf change only affects cache headers, not functionality). |
| 63 | + |
| 64 | +--- |
30 | 65 |
|
31 | 66 | ## Verification |
32 | 67 |
|
33 | | -- Frontend: `pnpm run lint` ✅ · `pnpm run typecheck` ✅ · `pnpm run test` ✅ (18/18 files, 268/268 tests) |
34 | | -- Backend API: `uv tool run ruff check . && uv run python -m pytest tests/test_firms_router.py tests/test_system_router.py` ✅ (7 targeted tests) |
35 | | -- Targeted poller verification: `space_pulse` lint ✅; host `space_pulse` pytest remains blocked by the known Windows/Python 3.14 `asyncpg==0.30.0` build issue. |
| 68 | +| Suite | Result | |
| 69 | +|-------|--------| |
| 70 | +| Frontend lint | ✅ Clean | |
| 71 | +| Frontend typecheck | ✅ Clean | |
| 72 | +| Frontend tests | ✅ 272/272 | |
| 73 | +| Backend API lint | ✅ Clean | |
| 74 | +| Backend API tests | ✅ 152/152 | |
| 75 | +| GDELT threshold tests | ✅ 11/11 (6 new) | |
| 76 | + |
| 77 | +--- |
36 | 78 |
|
37 | 79 | ## Upgrade Instructions |
38 | 80 |
|
39 | 81 | ```bash |
40 | | -git pull origin main |
41 | | -docker compose pull |
42 | | -docker compose up -d --build |
43 | | -``` |
| 82 | +git pull origin dev |
44 | 83 |
|
45 | | -TimescaleDB migration V004 runs automatically on backend startup. |
| 84 | +# Rebuild affected services |
| 85 | +docker compose up -d --build sovereign-backend sovereign-gdelt-pulse sovereign-space-pulse |
| 86 | + |
| 87 | +# Frontend (if running prod static build) |
| 88 | +docker compose up -d --build sovereign-frontend |
| 89 | +``` |
46 | 90 |
|
47 | | -**SITREP Status: [GO]** |
| 91 | +No `docker compose down` required. No migrations to run. |
0 commit comments