Remove sampling, viewport bbox truncation, and buffer ceilings that were cherry-picking ships, flights, and related layers.
Co-authored-by: Cursor <cursoragent@cursor.com>
Expose observed aircraft/vessel paths, route enrichment, VIP metadata, datalink, and nearby context so agents can reconstruct movement without full telemetry dumps.
Co-authored-by: Cursor <cursoragent@cursor.com>
Pre-fix the emissions tooltip only showed the per-hour *rate* — what most
users actually want is the cumulative *amount* burned. This adds running
totals computed by multiplying the model-based rate by the elapsed
observation time since we first saw the airframe.
New module ``flight_observations.py``:
* Tracks first_seen_at + last_seen_at per icao24 hex.
* Re-opens a fresh session when an aircraft is unseen for > 15 min
(treated as a new flight — landed and took off, or transited a dead
zone). Prevents the cumulative counter from resetting mid-flight if
the trail-rendering cache prunes the trail.
* Clamps elapsed time to 24h max so clock skew can't produce comically
large numbers.
* Pruned every 5 min via a new scheduler job (mirrors ais_prune cadence).
flights.py + military.py emission enrichment now also attaches:
* observed_seconds — how long we've been tracking this airframe.
* fuel_gallons_burned — rate * elapsed_h.
* co2_kg_emitted — rate * elapsed_h.
The existing per-hour rate fields stay in the dict for backward compat
and are shown as small secondary context in the tooltip.
Frontend EmissionsEstimateBlock (NewsFeed.tsx) now prominently shows
the cumulative totals with the rate as smaller context underneath plus
"Observed in flight for Xh Ym". When observed_seconds is 0 (first refresh)
it renders "Just observed · totals will appear on next refresh" instead
of a misleading "0 gal".
12 backend tests cover record/accumulate/reset, the 24h clamp, prune,
case-insensitive key normalization, and end-to-end emission integration
in _classify_and_publish.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pre-fix, adsb.lol records (the primary source for most flights) carried
no source marker. OpenSky records got is_opensky: True and supplementals
got supplemental_source, so any UI inspecting source labels saw
OpenSky/airplanes.live records as explicitly tagged and adsb.lol records
as "unlabeled" — making it look like adsb.lol wasn't being used at all
even though it's the primary source.
Changes:
* _fetch_adsb_lol_regions stamps source="adsb.lol" on each aircraft
before returning, so the tag survives the OpenSky dedupe-by-hex merge.
* OpenSky records get source="OpenSky" (alongside is_opensky=True for
back-compat).
* military fetcher tags source on both adsb.lol and airplanes.live
records before they're merged, and propagates source into the
military_flights and uavs output dicts.
* _classify_and_publish promotes the explicit source field into the
published flight dict. Falls back to legacy supplemental_source if
source is absent. Final fallback "adsb.lol" preserves prior behavior
for any caller synthesizing records without going through a fetcher.
8 new tests cover the published-dict propagation, OpenSky tagging,
supplemental fallback, explicit-wins precedence, default behavior, the
adsb.lol regional fetcher tagging, and the military output dict.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three stacked filters meant the gps_jamming layer almost never lit up:
1. nac_p == 0 aircraft were dropped on the theory that "0 = old transponder."
That's only half right — modern Mode-S Enhanced Surveillance transponders
also fall back to nac_p=0 when they lose GPS lock entirely, which IS the
jamming signature we want to catch. Discarding them was discarding the
strongest signal. None (no field at all — typical for OpenSky-sourced
records) is still skipped because absence-of-data isn't evidence.
2. GPS_JAMMING_MIN_AIRCRAFT was 5 per 1°x1° cell. Jamming hotspots
(eastern Med, Russia/Ukraine border, Iran/Iraq) tend to have sparser
traffic because pilots avoid them. Lowered to 3.
3. GPS_JAMMING_MIN_RATIO was 0.30. Combined with the (preserved) -1 noise
cushion that made the effective bar high. Lowered to 0.20.
The 1-aircraft noise cushion is intact so a single quirky transponder
still can't flag a zone alone.
Also extracted the detector loop into a pure ``detect_gps_jamming_zones()``
function at module scope so it's testable in isolation (was previously
inlined inside ``_classify_and_publish``). The public signature accepts
threshold overrides for ad-hoc re-tuning without code edits.
16 new tests cover nac_p=0 inclusion, None-skip preservation, MIN_AIRCRAFT
lowering, MIN_RATIO lowering, noise cushion preservation, constant pinning,
override behavior, lon/lng key compatibility, and robustness to empty/None
inputs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Gate messages now propagate via the Infonet hashchain as encrypted blobs — every node syncs them
through normal chain sync while only Gate members with MLS keys can decrypt. Added mesh reputation
system, peer push workers, voluntary Wormhole opt-in for node participation, fork recovery,
killwormhole scripts, obfuscated terminology, and hardened the self-updater to protect encryption
keys and chain state during updates.
New features: Shodan search, train tracking, Sentinel Hub imagery, 8 new intelligence layers,
CCTV expansion to 11,000+ cameras across 6 countries, Mesh Terminal CLI, prediction markets,
desktop-shell scaffold, and comprehensive mesh test suite (215 frontend + backend tests passing).
Community contributors: @wa1id, @AlborzNazari, @adust09, @Xpirix, @imqdcr, @csysp, @suranyami,
@chr0n1x, @johan-martensson, @singularfailure, @smithbh, @OrfeoTerkuci, @deuza, @tm-const,
@Elhard1, @ttulttul