Open Python pipeline, static dashboard and read only API for GNSS jamming-like and spoofing-like anomalies in public ADS-B data over the Gulf.
Status: release candidate, study snapshot of 2026-02-07 to 2026-03-13. Research and monitoring tool, not for navigation or safety of life. It reports evidence of degraded position quality and attributes nothing to any state or actor. No organisation has reviewed, endorsed or partnered with the project.
- Dashboard (study snapshot of fixed days, not live data): https://tashwish.onrender.com
- API (read only, free tier, may take about a minute to wake): https://tashwish-api.onrender.com
- Repository: https://github.com/hudasol/tashwish
- Downloads daily adsb.lol
globe_historyarchives, keeps the Gulf box (22 to 31 N, 46 to 62 E) and discards the raw bytes. - Counts unique aircraft per H3 cell (resolution 4), 3 hour UTC bucket and altitude stratum, and the share that report degraded NIC or NACp, with Wilson intervals.
- Flags jamming-like cells against each cell's own baseline with false discovery control, and spoofing-like clusters of impossible position jumps.
- Models receiver coverage so that cells nobody can see are marked as insufficient data, never as quiet.
- Validates with labelled synthetic injections and a preregistered set of held out days, then publishes a versioned dataset, a dashboard and an API.
Python 3.11 or later.
pip install -e . # pipeline and command line tool
pip install -e ".[api]" # adds FastAPI and uvicorn for the API
pip install -e ".[dev]" # adds pytest, hypothesis and ruff
tashwish doctor # check Python, packages, state/ and processed/
tashwish build --mode study_snapshot # build release/ and web/data from processed/
tashwish api --release-dir release/ --port 8000 # serve the read only API
(cd web && python -m http.server 8080) # serve the dashboard
The incremental command scores the next missing archive day against the frozen baseline in state/. It needs the secret
TASHWISH_STATE_KEY (at least 16 characters, never committed) and refuses days inside the study window.
tashwish incremental --state state --processed processed --spool /tmp/spool --max-days 1
tashwish ingest, tashwish validate and tashwish --help list the remaining commands. Operation is described in
docs/OPERATIONS.md and the API in docs/API.md.
The aggregates are released as release/cell_buckets.parquet, release/events.parquet and release/coverage.parquet (CSV copies
for the first two), with manifest.json, validation.json, checksums.sha256, a data card and the ODbL text. They hold no raw
traces, no aircraft identifiers and no per point positions. A Zenodo record is prepared but not yet published
(docs/ZENODO.md). Raw archives are never stored or redistributed.
Source: adsb.lol globe_history, ODbL 1.0. Attribution:
Contains information from adsb.lol, which is made available here under the Open Database License (ODbL). This derived database (Tashwish aggregates) is also made available under the ODbL 1.0.
See docs/DATA_CARD.md, docs/DATA_SOURCES.md and docs/LICENSING.md.
What this repository shows (study snapshot, not a live feed)
- Study window: 2026-02-07 to 2026-03-13, 35 UTC days of public ADS-B, released as a release candidate (dataset version
observed-2026-03-13-73ebe3c6, built at code commit5fb5195). - Split rule
tashwish-heldout-v1: 21 development days and 14 held out days. The held out days were fixed and listed before any held out result was computed, and scored once at commit94eafcd(frozen 2026-10-12 06:27:49 UTC). - OBSERVED, regime change: tested degraded share was 0.008 to 0.018 on days up to 2026-02-27 and 0.088 to 0.336 from 2026-03-01. The median daily total of en route aircraft counts over cell buckets (traffic units) fell from 48605 to 3864. The reduced traffic regime starts on 2026-02-28 and the elevated degraded regime on 2026-03-01; the development analysis places the sharp change at about 2026-03-02. 14 of 35 study days (6 of 14 held out days) are in the reduced traffic regime. No cause is identified and none is asserted.
Held out results (8 normal traffic days and 6 reduced traffic days). Intervals are day bootstrap intervals. The pooled column mixes two regimes and describes neither; read the regime columns.
| Measure | Data class | Pooled | Traffic normal | Traffic reduced |
|---|---|---|---|---|
| Injected jamming like, easy tier, recall | SYNTHETIC | 0.917 (0.859 to 0.966; n 84, 14 days) | 1.000 (1.000 to 1.000; n 51, 8 days) | 0.788 (0.750 to 0.824; n 33, 6 days) |
| Injected jamming like, medium tier, recall | SYNTHETIC | 0.821 (0.647 to 0.954; n 84, 14 days) | 1.000 (1.000 to 1.000; n 50, 8 days) | 0.559 (0.297 to 0.812; n 34, 6 days) |
| Injected jamming like, hard tier, recall | SYNTHETIC | 0.095 (0.024 to 0.179; n 84, 14 days) | 0.133 (0.000 to 0.271; n 45, 8 days) | 0.051 (0.000 to 0.116; n 39, 6 days) |
| Injected spoofing like, 3 or more aircraft, recall | SYNTHETIC | 0.516 (0.409 to 0.622; n 126, 14 days) | 0.432 (0.305 to 0.557; n 81, 8 days) | 0.667 (0.561 to 0.766; n 45, 6 days) |
| Covered cells with too few aircraft (false coverage) | OBSERVED | 0.091 (0.069 to 0.141; n 16410, 14 days) | 0.058 (0.052 to 0.064; n 14952, 8 days) | 0.425 (0.357 to 0.486; n 1458, 6 days) |
SYNTHETIC rows measure whether the detector finds scenarios that were injected into real traffic. They are not accuracy against real interference. Precision and detection delay are not measured on real data.
Preregistered predictions: 19 HIT, 8 MISS, 1 not evaluable, out of 28 scored. Misses: D2, C3, S1, S4, R3, R4, X1, A2. Details in docs/research/PREDICTIONS_RESULTS.md and docs/research/VALIDATION.md.
The table is generated by scripts/make_readme_status.py from the result files. Method details are in
docs/METHODOLOGY.md.
- There is no ground truth for GNSS interference in public ADS-B data. Real events are candidates for review: most spoofing-like events involve the minimum of 3 aircraft and can be data errors. Precision and detection delay are not measured on real data.
- Recall is measured on synthetic scenarios injected into real traffic. Jamming-like recall is low for weak, small or short scenarios and lower on reduced traffic days.
- The data change sharply from about 2026-03-02. Baselines and coverage are fitted per regime, rates pooled across the change describe neither side, and no cause is identified.
- The study window is 35 days in one season. Held out days are not independent samples and are not later in time than the days used for fitting.
- Coverage follows volunteer receivers and changes over time. NIC and NACp can degrade for reasons unrelated to interference, so a degraded share is evidence and not proof.
- The forward evaluation on days after the study window is preregistered in docs/PREDICTIONS_FORWARD.md and has not been run.
src/tashwish/
config.py region box, grid and thresholds
schema.py point table schema and data class rules
split.py development and held out day split
regime.py day level traffic and degraded regime labels
pipeline.py stage orchestration from points to detections
attribution.py attribution wording, single source
cli.py the tashwish command
ingest/ archive download, trace parsing, quality report
metrics/ aggregation and statistics
coverage/ receiver coverage model
detect/ jamming-like and spoofing-like detectors
validate/ synthetic injection, harness, sensitivity
operate/ incremental run, scoring, state, refit
release/ dataset and dashboard data build
api/ read only FastAPI service
interop/ file formats for Marsad and Sirb
web/ static dashboard
tests/ unit, property and integration tests
scripts/ document generators and checks
docs/ documentation
docs/README.md indexes every document. Start with docs/METHODOLOGY.md, docs/DATA_CARD.md and docs/research/VALIDATION.md. Open work is in docs/ROADMAP.md. File formats for Marsad and Sirb, two separate projects by the same author, are in docs/MARSAD_INTERFACE.md and docs/SIRB_INTERFACE.md.
See CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md. Before opening a
pull request run python -m pytest -p no:warnings, ruff check . and ruff format --check ..
Code: Apache License 2.0 (LICENSE). Data: Open Database License 1.0 (licenses/ODbL-1.0.txt, NOTICE).
See CITATION.cff. Author: Huda Mueen.