cjc0013 commited on
Commit
69a223f
·
verified ·
1 Parent(s): 665aed7

Update mystery drone sensitive-site Space

Browse files

Replace the old small point-map preview with a sanitized release-grade review Space using 149 public-source report cases, evidence tiers, filters, charts, and source-detail panels.

README.md CHANGED
@@ -9,12 +9,8 @@ app_file: app.py
9
  python_version: 3.11
10
  ---
11
 
12
- # Drone Sightings Near Covered U.S. Military and Civilian Areas
13
 
14
- # Drone Sightings Near Covered U.S. Military and Civilian Areas
15
 
16
- This private preview maps public-source news stories and FAA-reported drone sightings over official covered military and civilian areas.
17
-
18
- Use the time slider plus the Play and Pause controls to watch red dots appear across time, then match the `event_id` on the map to the row data directly below it.
19
-
20
- Each point is tied to one public event row and a linked source list. This release tracks reported drone sightings and preliminary FAA UAS sighting rows; it does not prove intent, threat, wrongdoing, or a verified security breach.
 
9
  python_version: 3.11
10
  ---
11
 
12
+ # Mystery Drone Reports Around Sensitive Sites
13
 
14
+ Interactive review surface for public-source reports about mystery, unidentified, suspicious, or unauthorized drone activity around sensitive sites.
15
 
16
+ This Space presents evidence tiers, source links, date signals, country/site filters, and row-level claim boundaries. It does not claim that any row proves threat, attribution, anomalous origin, or hostile intent.
 
 
 
 
__pycache__/public_space_app.cpython-311.pyc ADDED
Binary file (16.1 kB). View file
 
app.py CHANGED
@@ -2,7 +2,7 @@ from pathlib import Path
2
 
3
  from public_space_app import build_app
4
 
5
- app = build_app(Path(__file__).with_name("public_copy.json"))
6
 
7
  if __name__ == "__main__":
8
  app.launch()
 
2
 
3
  from public_space_app import build_app
4
 
5
+ app = build_app(Path(__file__).parent / "data")
6
 
7
  if __name__ == "__main__":
8
  app.launch()
data/limitations.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Limitations
2
+
3
+ - This is a public-source report index, not a verified incident database.
4
+ - A row does not prove intent, threat, wrongdoing, hostile attribution, or anomalous origin.
5
+ - Some dates are publication/report dates rather than observed event dates.
6
+ - Some locations are named-site or country-level signals, not precise geocodes.
7
+ - Source-discovered rows are intentionally broad so reviewers can find more cases quickly; they should be checked before analytic use.
data/methodology.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Methodology
2
+
3
+ The release starts from public-source article discovery and a stricter sensitive-site event view. Rows are ranked into evidence tiers rather than flattened into one confidence level.
4
+
5
+ The public table removes local file paths, runtime details, and internal run metadata. It keeps only source-facing fields: headline, publisher, URL, report date, site signal, country/region, evidence tier, cluster id, and a row hash.
6
+
7
+ Evidence tiers:
8
+
9
+ - `resolved_sensitive_site_report`: the stricter event view matched the source to a sensitive site candidate.
10
+ - `named_sensitive_site_report`: the source names a sensitive site, but the row is still a candidate that needs follow-up.
11
+ - `source_discovered_report`: public source title or URL language indicates a relevant drone report around a sensitive context; use as a lead for review.
data/mystery_drone_sensitive_site_cases.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/mystery_drone_sensitive_site_cases.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/quality_report.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "quality_report_version": "mystery_drone_public_release_quality_v1",
3
+ "release_grade": true,
4
+ "failed_checks": [],
5
+ "min_cases_required": 100,
6
+ "case_count": 149,
7
+ "missing_source_url_count": 0,
8
+ "duplicate_source_url_count": 0,
9
+ "generic_headline_count": 0,
10
+ "forbidden_public_term_hits": [],
11
+ "drone_signal_count": 149,
12
+ "sensitive_signal_count": 148,
13
+ "counts_by_evidence_tier": {
14
+ "resolved_sensitive_site_report": 9,
15
+ "named_sensitive_site_report": 11,
16
+ "source_discovered_report": 129
17
+ },
18
+ "counts_by_country": {
19
+ "United States": 82,
20
+ "Germany": 15,
21
+ "Denmark": 16,
22
+ "Belgium": 8,
23
+ "Netherlands": 1,
24
+ "United Kingdom": 4,
25
+ "Ireland": 2,
26
+ "Italy": 1,
27
+ "Singapore": 1,
28
+ "Spain": 2,
29
+ "Sweden": 1,
30
+ "unknown": 16
31
+ },
32
+ "counts_by_case_scope": {
33
+ "event_candidate": 9,
34
+ "named_site_case": 11,
35
+ "source_report_case": 129
36
+ }
37
+ }
data/release_manifest.json ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "release_version": "mystery-drone-sensitive-site-cases-2026-05-v1",
3
+ "title": "Mystery Drone Reports Around Sensitive Sites",
4
+ "generated_utc": "2026-05-01T20:32:52-04:00",
5
+ "source_lead_count": 150,
6
+ "case_count": 149,
7
+ "resolved_sensitive_site_report_count": 9,
8
+ "named_sensitive_site_report_count": 11,
9
+ "source_discovered_report_count": 129,
10
+ "probable_cluster_count": 97,
11
+ "counts_by_country": {
12
+ "United States": 82,
13
+ "Germany": 15,
14
+ "Denmark": 16,
15
+ "Belgium": 8,
16
+ "Netherlands": 1,
17
+ "United Kingdom": 4,
18
+ "Ireland": 2,
19
+ "Italy": 1,
20
+ "Singapore": 1,
21
+ "Spain": 2,
22
+ "Sweden": 1,
23
+ "unknown": 16
24
+ },
25
+ "counts_by_evidence_tier": {
26
+ "resolved_sensitive_site_report": 9,
27
+ "named_sensitive_site_report": 11,
28
+ "source_discovered_report": 129
29
+ },
30
+ "claim_boundary": "Public-source report index; not a verified finding of threat, attribution, or anomalous origin.",
31
+ "summary_hash": "5285f25aeaff138958731d3eda485b925682ed50a2742c3c319cb5349cd92c47",
32
+ "release_grade": true,
33
+ "quality_failed_checks": [],
34
+ "artifacts": [
35
+ {
36
+ "artifact_role": "cases_csv",
37
+ "artifact_path": "data/mystery_drone_sensitive_site_cases.csv",
38
+ "content_sha256": "62c2aba1b5708d7223ac6c6b3dcb94a777d4289dab73f521f93fa6baa6480aa6",
39
+ "byte_count": 105504
40
+ },
41
+ {
42
+ "artifact_role": "cases_jsonl",
43
+ "artifact_path": "data/mystery_drone_sensitive_site_cases.jsonl",
44
+ "content_sha256": "53546245b4b553861f30d9565a20645d7828a348b8e6e9280d26c327432f024d",
45
+ "byte_count": 164513
46
+ },
47
+ {
48
+ "artifact_role": "readme",
49
+ "artifact_path": "README.md",
50
+ "content_sha256": "2831cd22ae776109a5a51c81a89f2ae0cb62514c7e6f1a6982214f518717f9fc",
51
+ "byte_count": 1796
52
+ },
53
+ {
54
+ "artifact_role": "methodology",
55
+ "artifact_path": "methodology.md",
56
+ "content_sha256": "100c9de512e26882f9c0e6001d26183be6e50d7cee8b2a5ca743598a4ec79294",
57
+ "byte_count": 849
58
+ },
59
+ {
60
+ "artifact_role": "limitations",
61
+ "artifact_path": "limitations.md",
62
+ "content_sha256": "83d733664e52125c1bba57fada6ea92dace2c9d2acb596d12bf1c6230b2def87",
63
+ "byte_count": 480
64
+ },
65
+ {
66
+ "artifact_role": "schema_notes",
67
+ "artifact_path": "schema_notes.md",
68
+ "content_sha256": "2224b44ab8d589e661a5ad9d89328d2efcca3a8e98c488a29f094c98dabf71a7",
69
+ "byte_count": 574
70
+ },
71
+ {
72
+ "artifact_role": "quality_report",
73
+ "artifact_path": "quality_report.json",
74
+ "content_sha256": "a8f2e692f08bd8d5fef88d00691d018f6fa0b28b2f550da995d3b2eb1f9072b3",
75
+ "byte_count": 935
76
+ }
77
+ ],
78
+ "manifest_hash": "cd861520adba5e1ead213fd6389208eeea2d5d1041c1590bbdd7ddca1525cfbb"
79
+ }
data/schema_notes.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Schema Notes
2
+
3
+ - `case_id`: stable public id derived from public-facing row content.
4
+ - `case_scope`: whether the row is an event candidate, named-site case, or source-report case.
5
+ - `evidence_tier`: strength of the row's current source/site support.
6
+ - `followup_status`: what a reviewer should do next.
7
+ - `source_language_signal`: why the row was retained.
8
+ - `probable_cluster_id`: stable grouping key for likely related rows.
9
+ - `claim_boundary`: plain-language warning against overclaiming.
10
+ - `public_row_sha256`: hash of public row fields for integrity checks.
dataset_bundle/README.md DELETED
@@ -1,28 +0,0 @@
1
- # Drone Sightings Near Covered U.S. Military and Civilian Areas
2
-
3
- A small, review-oriented slice of U.S. public-source and FAA-reported drone sightings mapped against official covered-area registries.
4
-
5
- This release tracks reported drone sightings from public-source news stories and FAA preliminary UAS sighting reports; it does not prove intent, wrongdoing, threat, or a verified security breach.
6
- It also includes a conservative UAP/drone language overlay so readers can distinguish official UAS records from ordinary drone language and sources that explicitly use mystery-drone, UFO, or UAP wording.
7
-
8
- ## Included Files
9
-
10
- - `events.csv`
11
- - `monitored_areas.csv`
12
- - `event_sources.csv`
13
- - `daily_area_rollup.csv`
14
- - `uap_language_overlay_report.json`
15
- - `public_release_manifest.json`
16
- - `methodology.md`
17
- - `limitations_and_blind_spots.md`
18
- - `quality_checks.md`
19
- - `schema_notes.md`
20
-
21
- ## Caveats
22
-
23
- - This release tracks reported drone sightings from public-source news stories and official FAA UAS sighting reports; FAA reports are still preliminary sighting records, not verified federal incident findings.
24
- - UAP-adjacent labels are source-language overlap labels only; they do not verify that an object was a UAP, anomalous, or non-human.
25
- - A reported sighting does not by itself prove intent, threat, wrongdoing, or the presence of a hostile actor.
26
- - Events are plotted at the covered-area point or centroid, not at a freehand geocoded story location.
27
- - Some event dates use article publication dates as bounded proxies when an observed date is not extractable from the story.
28
- - Ambiguous multi-area stories stay in the internal review queue and are not plotted in the public dataset.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/daily_area_rollup.csv DELETED
@@ -1,11 +0,0 @@
1
- "event_date","area_id","area_name","area_type","civ_mil_class","state","event_count","source_count"
2
- "2024-09-15","dod:joint-base-mcguire-dix-lakehurst:nj","Joint Base McGuire-Dix-Lakehurst","military_installation","military","NJ","1","1"
3
- "2024-10-13","dod:joint-base-langley-eustis:va","Joint Base Langley-Eustis","military_installation","military","VA","1","5"
4
- "2024-11-18","dod:picatinny-arsenal:nj","Picatinny Arsenal","military_installation","military","NJ","1","2"
5
- "2024-11-30","dod:vandenberg-space-force-base:ca","Vandenberg Space Force Base","military_installation","military","CA","1","2"
6
- "2024-12-09","dod:marine-corps-base-camp-pendleton:ca","Marine Corps Base Camp Pendleton","military_installation","military","CA","1","2"
7
- "2024-12-09","dod:naval-weapons-station-earle-nj:nj","Naval Weapons Station Earle NJ","military_installation","military","NJ","1","3"
8
- "2024-12-16","dod:wright-patterson-air-force-base:oh","Wright-Patterson Air Force Base","military_installation","military","OH","1","5"
9
- "2024-12-18","dod:hill-air-force-base:ut","Hill Air Force Base","military_installation","military","UT","1","2"
10
- "2026-03-09","dod:barksdale-air-force-base:la","Barksdale Air Force Base","military_installation","military","LA","1","8"
11
- "2026-03-19","dod:joint-base-myer-henderson-hall:va","Joint Base Myer-Henderson Hall","military_installation","military","VA","1","2"
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/event_sources.csv DELETED
@@ -1,33 +0,0 @@
1
- "event_id","canonical_url","publisher","title","published_at","article_date","date_quality","content_sha256","phenomenon_terms","language_family","uap_overlap_label","ambiguity_score"
2
- "event:dod:joint-base-langley-eustis:va:2024-10-13:0001","https://dronexl.co/2024/10/13/pentagon-drone-swarm-us-military-base/","dronexl.co","Pentagon Baffled By 17-Day Drone Swarm At US Military Base","2024-10-13T14:02:54+00:00","2024-10-13","report_date_proxy","32089bc31df3e3f2f2b846569ced73ce213bb5e0122cdbfeda4ddf648c12d97e","['aircraft', 'commercial drone', 'drone', 'drones', 'mysterious', 'unidentified', 'unmanned aerial']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
3
- "event:dod:joint-base-langley-eustis:va:2024-10-13:0001","https://www.foxnews.com/politics/unknown-drone-fleet-breached-us-military-base-airspace-virginia-17-straight-days-report","foxnews.com","Unknown drone fleet breached US military base airspace in Virginia for 17 straight days: report","2024-10-13T18:03:19+00:00","2024-03-31","observed_date","cc6fbd796420a44dc91fd3885d05ddfa57b20d0f7efccf5870b68f936e25b856","['aircraft', 'drone', 'drones', 'mysterious', 'ufo', 'unknown', 'unmanned aircraft']","explicit_ufo_uap_language","explicit_ufo_uap_language","5"
4
- "event:dod:joint-base-langley-eustis:va:2024-10-13:0001","https://www.whro.org/military-veterans/2024-10-15/the-pentagon-confirmed-a-swarm-of-drones-violated-langley-airspace","whro.org","The Pentagon confirmed a swarm of drones violated Langley airspace","2024-10-16T01:10:18.929000+00:00","2024-10-16","report_date_proxy","040b597574a999a4467b15c3e5d32767e05e00d296b3b47e58bf08f9cdf19d19","['balloon', 'drone', 'drones', 'uas', 'unmanned aerial']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
5
- "event:dod:joint-base-langley-eustis:va:2024-10-13:0001","https://www.foxnews.com/politics/drone-incursions-us-bases-come-under-intense-scrutiny-devices-prove-lethality-overseas","foxnews.com","Drone incursions on US bases come under intense scrutiny as devices prove lethality overseas","2025-06-26T16:00:33+00:00","2025-07-10","observed_date","6638c2c3abbbc182dbddf0cfd8ca413e39c1b8995df70cda3dfe347c708397a1","['aircraft', 'drone', 'drones', 'uas', 'unmanned aerial']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
6
- "event:dod:joint-base-langley-eustis:va:2024-10-13:0001","https://globalnews.ca/news/10812987/mysterious-drones-langley-air-force-base/","globalnews.ca","Mystery drones swarm air force base for 17 days, leaving Pentagon baffled - National | Globalnews.ca","","","unknown","7be0d3b1a5434202228e5e5d9b1e4011e1e9f6d2e3a8a505b817daff040298f9","['aircraft', 'drone', 'drones', 'mysterious', 'mystery', 'uas', 'ufo', 'unknown', 'unmanned aircraft']","explicit_ufo_uap_language","explicit_ufo_uap_language","5"
7
- "event:dod:hill-air-force-base:ut:2024-12-18:0002","https://dronexl.co/2024/12/17/multiple-drone-sightings-reported-near-hill-air-force-base/","dronexl.co","Multiple Drone Sightings Reported Near Hill Air Force Base Amid Nationwide Military Installation Incidents","2024-12-18T01:38:23+00:00","2024-12-18","report_date_proxy","e2728f70ebdffa3f0d3539e9135bdfd8278ae49d017e1b2d4a844801cf0b82e5","['aircraft', 'commercial drone', 'drone', 'drones', 'unidentified', 'unmanned aerial', 'unmanned aerial system', 'unmanned aircraft']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
8
- "event:dod:hill-air-force-base:ut:2024-12-18:0002","https://hebervalleyradio.com/news/local-news/drones-spotted-near-hill-air-force-base/","hebervalleyradio.com","Drones Spotted Near Hill Air Force Base in Utah","","","unknown","20a29b4a86ca5c80562c354e11158550ead39622133cdf3eb3a288511965856f","['drone', 'drones', 'mysterious']","mystery_drone_language","uap_adjacent_drone_language","3"
9
- "event:dod:wright-patterson-air-force-base:oh:2024-12-16:0003","https://dronexl.co/2024/12/15/drone-incursions-ohio-wright-patterson-air-force-base/","dronexl.co","Multiple Drone Incursions Force Temporary Shutdown At Ohio's Wright-Patterson Air Force Base","2024-12-16T02:52:55+00:00","2024-12-16","report_date_proxy","f9993bafe090ef48581e9823817070df74f52126bae15aa474e868304e585bdc","['aircraft', 'commercial drone', 'drone', 'drones', 'unidentified', 'unmanned aerial', 'unmanned aircraft']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
10
- "event:dod:wright-patterson-air-force-base:oh:2024-12-16:0003","https://www.whio.com/news/local/mysterious-drone-sightings-shut-down-airspace-over-critical-ohio-air-force-base/MP37ILTNJFD4PAYKUEYELOXLXY/?outputType=amp","whio.com","Mysterious drone sightings shut down airspace over critical Ohio air force base","2024-12-16T17:18:07.321000+00:00","2024-12-16","report_date_proxy","803b9d81da4c225c76eb496f831a8311ca0b06b86b192a8bb88074b48260bee4","['drone', 'drones', 'mysterious', 'mystery', 'unmanned aerial']","mystery_drone_language","uap_adjacent_drone_language","3"
11
- "event:dod:wright-patterson-air-force-base:oh:2024-12-16:0003","https://www.fox19.com/2024/12/17/more-drones-spotted-around-wright-patterson-air-force-base/","fox19.com","More drones spotted around Wright-Patterson Air Force Base","2024-12-17T16:46:32.726000+00:00","2024-12-16","observed_date","629126fa23ab2b59c2f92c4b9ac1e1402cd89cb66bf2bbeb4921d444f4193adb","['aircraft', 'drone', 'drones', 'helicopter', 'mysterious', 'mystery', 'uas', 'unknown', 'unmanned aircraft', 'unmanned aircraft system']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
12
- "event:dod:wright-patterson-air-force-base:oh:2024-12-16:0003","https://spectrumnews1.com/oh/columbus/news/2024/12/17/wright-patterson-air-force-experiences-more-drone-sightings","spectrumnews1.com","Wright-Patterson Air Force experiences more drone sightings","","","unknown","fbaa2fb89485368c1e8604b8b7b25e0609d383cad711de428971697f105b1d54","['drone', 'drones', 'unmanned aerial']","drone_or_uas_report","drone_or_uas_report","0"
13
- "event:dod:wright-patterson-air-force-base:oh:2024-12-16:0003","https://www.asisonline.org/security-management-magazine/latest-news/today-in-security/2025/march/drone-corporate-espionage/","asisonline.org","A Rising Threat: Using Drones to Conduct Corporate Espionage","","","unknown","2d9ce5575130c5234aa17a622a2efda4cd9271391fec4c4a2bebb60381f32ddd","['commercial drone', 'drone', 'drones', 'military drone', 'uas', 'unmanned aerial']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
14
- "event:dod:naval-weapons-station-earle-nj:nj:2024-12-09:0004","https://patch.com/new-jersey/middletown-nj/6-drones-flew-over-naval-weapons-station-earle-friday-night","patch.com","Nearly 12 Drones Flew Over Naval Weapons Station Earle In Middletown","2024-12-09T14:59:30+00:00","2024-12-09","report_date_proxy","9dcf7fbb21f1da35d0c9e0743fbf139da1a16d663c198ca951b128be9506fc64","['drone', 'drones', 'helicopter']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
15
- "event:dod:naval-weapons-station-earle-nj:nj:2024-12-09:0004","https://abc7chicago.com/15651392/","abc7chicago.com","'Multiple' drones entered airspace at New Jersey naval station: Official","2024-12-13T16:15:27+00:00","2024-11-18","observed_date","ff6d80243360742b40c5b7de43ed5acddcf6f8598eb148764d14e37111222429","['aircraft', 'drone', 'drones', 'uas', 'unexplained', 'unidentified', 'unmanned aerial', 'unmanned aerial system', 'unmanned aircraft']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
16
- "event:dod:naval-weapons-station-earle-nj:nj:2024-12-09:0004","https://www.kabc.com/2024/12/13/report-new-jersey-naval-station-confirms-drones-entered-airspace/","kabc.com","Report: New Jersey Naval Station Confirms Drones Entered Airspace","","","unknown","a4b2a1e344d794ab3effa0b1a928dc0fba302b0c1299ae025f46437324f47b63","['drone', 'drones', 'mysterious', 'unidentified']","mystery_drone_language","uap_adjacent_drone_language","3"
17
- "event:dod:picatinny-arsenal:nj:2024-11-18:0005","https://apnews.com/article/cd8866c9c2568216759007716990decf","apnews.com","FBI investigating reports of large drones flying in New Jersey, seeks public's help","2024-12-05T02:22:55+00:00","2024-11-18","observed_date","d8eb95ffd2621fe87216122e7bb7212ffe4c7a99f4bd2095db1e70f455ce1858","['aircraft', 'drone', 'drones', 'mysterious']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
18
- "event:dod:picatinny-arsenal:nj:2024-11-18:0005","https://time.com/7202191/new-jersey-drone-sightings/","time.com","What to Know About the ‘Drone’ Sightings in New Jersey","2024-12-13T19:33:25+00:00","2024-12-03","observed_date","3e343f3aeb3ce67699a74becfa8110d6488f5bfff1a4d20d3cf3059d559e7a8b","['aircraft', 'drone', 'drones', 'helicopter', 'mysterious']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
19
- "event:dod:vandenberg-space-force-base:ca:2024-11-30:0006","https://www.independent.com/2024/12/12/chinese-citizen-arrested-for-allegedly-flying-drone-over-and-photographing-vandenberg-space-force-base/","independent.com","Chinese Citizen Arrested for Allegedly Flying Drone over and Photographing Vandenberg Space Force Base","2024-12-13T00:23:31+00:00","2024-11-30","observed_date","27bd9ff06c0c05a6b4a166ef30e2171434d6fbe1f37657a94285378f67c9e561","['drone', 'drones']","drone_or_uas_report","drone_or_uas_report","0"
20
- "event:dod:vandenberg-space-force-base:ca:2024-11-30:0006","https://www.edhat.com/news/chinese-citizen-sentenced-for-unauthorized-drone-flight-over-vandenberg-space-force-base/","edhat.com","Chinese Citizen Sentenced for Unauthorized Drone Flight over Vandenberg Space Force Base - edhat","2025-04-01T15:14:52+00:00","2025-03-10","observed_date","a2b488ec89e4ca65b8bb6ffb8b916154959219ea94c2c906a2d8e5c77ac53511","['aircraft', 'drone', 'drones']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
21
- "event:dod:marine-corps-base-camp-pendleton:ca:2024-12-09:0007","https://www.yahoo.com/news/multiple-drone-incursions-confirmed-over-180614982.html","yahoo.com","Multiple Drone Incursions Confirmed Over Marine Corps Base Camp Pendleton (Updated)","2024-12-17T18:06:14+00:00","2024-12-09","observed_date","e4957f334787ea47005e68fea78d3834752dfaa8ffce07a36f4f80af28c26670","['aircraft', 'anomalous', 'drone', 'drones', 'not identified', 'uas', 'unknown', 'unmanned aerial', 'unmanned aerial system']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
22
- "event:dod:marine-corps-base-camp-pendleton:ca:2024-12-09:0007","https://www.foxnews.com/us/drones-spotted-over-camp-pendleton-california-posed-no-threat-operations-report","foxnews.com","Drones spotted over Camp Pendleton in California posed no threat to operations: report","2024-12-18T02:31:05+00:00","2024-12-09","observed_date","b284ec5e48f1ef8af379ce9a4e4f33a83eee8c922e4b184483b1a44942c3a927","['aircraft', 'drone', 'drones', 'mysterious', 'uas', 'unmanned aerial', 'unmanned aircraft']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
23
- "event:dod:joint-base-mcguire-dix-lakehurst:nj:2024-09-15:0008","https://www.foxnews.com/us/new-jersey-military-base-confirms-multiple-drone-contraband-smuggling-incursions-year","foxnews.com","New Jersey military base confirms multiple drone contraband-smuggling incursions this year","2024-12-19T01:13:36+00:00","2024-09-15","observed_date","eb01db2a1cd83b1553f854b88dbc3f6915da62b8b0e96caf1398459e6451b71b","['aircraft', 'drone', 'drones', 'mysterious', 'uaps', 'uas', 'unmanned aircraft']","explicit_ufo_uap_language","explicit_ufo_uap_language","5"
24
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://www.thedailybeast.com/leak-reveals-major-drone-incident-at-louisiana-air-force-base-in-trumps-war/","thedailybeast.com","Leak Reveals Major Drone Incident at Air Force Base in Trump’s War","","2026-03-09","observed_date","c1d844d46ae6add34233b2d16d6d3735ae2e78a34d7b015ded1ff1e088ea6468","['drone', 'drones', 'unidentified', 'unmanned aerial', 'unmanned aerial system']","mystery_drone_language","uap_adjacent_drone_language","3"
25
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://www.wafb.com/2026/03/20/barksdale-confirms-multiple-drones-entered-its-airspace-week-march-9/","wafb.com","Barksdale confirms multiple drones entered its airspace week of March 9","2026-03-09T14:27:25.136000+00:00","2026-03-09","observed_date","41380949ab50adb7c80c9f50e8d855a172b0456768cc80a41c2ebe2f626a64c1","['drone', 'drones', 'unmanned aerial', 'unmanned aerial system']","drone_or_uas_report","drone_or_uas_report","0"
26
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://thedebrief.org/u-s-officials-investigating-mystery-drone-incident-over-barksdale-air-force-base-that-prompted-security-alert/","thedebrief.org","U.S. Officials Investigating ""Mystery Drone"" Incident Over Barksdale Air Force Base That Prompted Security Alert","2026-03-09T18:54:47+00:00","2026-03-09","report_date_proxy","72f67ca9f0e48637f7d4c2b83a13936cdd3be52708c75f19978c25ad59b390a8","['aircraft', 'anomalous', 'drone', 'drones', 'mystery', 'not identified', 'unknown', 'unmanned aerial', 'unmanned aerial system']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
27
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://www.foxnews.com/us/unauthorized-drones-detected-over-u-s-air-force-base-housing-nuclear-capable-b-52-bombers-military","foxnews.com","Unauthorized drones detected over US Air Force base housing nuclear-capable B-52 bombers: military","2026-03-20T22:18:46+00:00","2026-03-09","observed_date","50de9d9f1b2468efb48e9892a8e85503a2b57d2582e15e424e93f361fde52655","['drone', 'drones', 'mystery']","mystery_drone_language","uap_adjacent_drone_language","3"
28
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://www.washingtonexaminer.com/policy/defense/4506427/barksdale-base-drone-incursion-military/","washingtonexaminer.com","Air base drone incursion: What to know about incident over B-52 bombers","2026-03-27T17:34:42+00:00","2026-03-09","observed_date","b8d4d5fa2893df6013069659e9942cb819e3dd78619e42ee0edc9eda6233f7a5","['aircraft', 'drone', 'drones']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
29
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://www.ksla.com/2026/03/28/senator-cassidy-reveals-new-details-barksdale-air-force-base-drone-incidents/","ksla.com","Senator Cassidy reveals new details on Barksdale Air Force Base drone incidents","2026-03-28T02:42:32.728000+00:00","2026-03-09","observed_date","ae56a60fbfc8c88eb2577c1700e9279c5b15f0f84d2770b42e6f6c19123c7a48","['drone', 'drones']","drone_or_uas_report","drone_or_uas_report","0"
30
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://dronelife.com/2026/03/30/barksdale-air-force-base-drone-incident/","dronelife.com","Barksdale Drone Incursions Highlight Real Security Risks","2026-03-30T15:53:26+00:00","2026-03-09","observed_date","49520e3d58b26b9c736f62eb35dac340b0e948da7f3f652f6c3c4c7149000cea","['aircraft', 'commercial drone', 'drone', 'drones', 'not identified', 'uas', 'unmanned aircraft']","known_operator_or_mundane_drone","known_non_uap_drone_language","-3"
31
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","https://www.foxnews.com/opinion/brett-velicovich-mystery-drones-no-mystery-dangerous-threat-national-security/","foxnews.com","BRETT VELICOVICH: ‘Mystery’ drones are no mystery, they are a dangerous threat to national security","2026-04-03T09:00:10+00:00","2026-03-04","observed_date","54b8eb6bd19ea7f170fdfa9ed9abd65d48555e6a26dd7b23ab22c7043b15c8e2","['balloon', 'drone', 'drones', 'mystery']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
32
- "event:dod:joint-base-myer-henderson-hall:va:2026-03-19:0010","https://ktul.com/news/nation-world/unidentified-drones-fly-over-fort-mcnair-expert-calls-it-security-concern","ktul.com","Unidentified drones reported flying over Fort McNair; expert calls it security concern","2026-03-19T17:53:19+00:00","2026-03-19","report_date_proxy","a7692558243bf8686d095f5a97075d35c12ba16fbfaa6fe42c4235f1c3fd4bd5","['drone', 'drones', 'unidentified']","mystery_drone_language","uap_adjacent_drone_language","3"
33
- "event:dod:joint-base-myer-henderson-hall:va:2026-03-19:0010","https://www.mediaite.com/media/news/alarming-number-of-unauthorized-drones-spotted-over-us-air-base/","mediaite.com","Alarming Number of ‘Unauthorized Drones’ Spotted Over US Air Base","2026-03-20T16:22:01+00:00","2026-03-09","observed_date","9d5d5d7e5e5101a3e0fdd6e34288f362bdafe4474d5b3b0588bcee42c55ed625","['aircraft', 'drone', 'drones', 'unidentified', 'unknown', 'unmanned aircraft']","known_operator_or_mundane_drone","known_non_uap_drone_language","0"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/events.csv DELETED
@@ -1,11 +0,0 @@
1
- "event_id","event_date","date_quality","area_id","area_name","area_type","civ_mil_class","state","lat","lon","primary_source_url","source_count","confidence_label","area_match_confidence","area_match_reasons","event_relevance_label","review_status","dedupe_cluster_id","dedupe_cluster_key","dedupe_reason","phenomenon_terms","language_family","uap_overlap_label","ambiguity_score","ambiguity_reasons","known_operator_claimed","headline","summary"
2
- "event:dod:joint-base-langley-eustis:va:2024-10-13:0001","2024-10-13","report_date_proxy","dod:joint-base-langley-eustis:va","Joint Base Langley-Eustis","military_installation","military","VA","37.122903","-76.472062","https://dronexl.co/2024/10/13/pentagon-drone-swarm-us-military-base/","5","medium","high","['alias', 'local_event_window', 'state_name']","event_relevant","auto_included","cluster:0001","cluster:dod:joint-base-langley-eustis:va:2024-10-13:0001","same_area_incident_followup","['aircraft', 'balloon', 'commercial drone', 'drone', 'drones', 'mysterious', 'mystery', 'uas', 'ufo', 'unidentified', 'unknown', 'unmanned aerial', 'unmanned aircraft']","explicit_ufo_uap_language","explicit_ufo_uap_language","5","['drone_term_plus_unknown_language', 'explicit_ufo_uap_terms', 'known_operator_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","Pentagon Baffled By 17-Day Drone Swarm At US Military Base","Check out the Best Deals on Amazon for DJI Drones today!"
3
- "event:dod:hill-air-force-base:ut:2024-12-18:0002","2024-12-18","report_date_proxy","dod:hill-air-force-base:ut","Hill Air Force Base","military_installation","military","UT","41.131726","-111.983398","https://dronexl.co/2024/12/17/multiple-drone-sightings-reported-near-hill-air-force-base/","2","medium","high","['alias', 'full_area_name', 'headline_area_context', 'local_event_window']","event_relevant","auto_included","cluster:0002","cluster:dod:hill-air-force-base:ut:2024-12-18:0002","same_area_incident_followup","['aircraft', 'commercial drone', 'drone', 'drones', 'mysterious', 'unidentified', 'unmanned aerial', 'unmanned aerial system', 'unmanned aircraft']","mystery_drone_language","uap_adjacent_drone_language","3","['drone_term_plus_unknown_language', 'known_operator_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","Multiple Drone Sightings Reported Near Hill Air Force Base Amid Nationwide Military Installation Incidents","Check out the Best Deals on Amazon for DJI Drones today!"
4
- "event:dod:wright-patterson-air-force-base:oh:2024-12-16:0003","2024-12-16","report_date_proxy","dod:wright-patterson-air-force-base:oh","Wright-Patterson Air Force Base","military_installation","military","OH","39.815255","-84.068151","https://dronexl.co/2024/12/15/drone-incursions-ohio-wright-patterson-air-force-base/","5","medium","high","['alias', 'full_area_name', 'headline_area_context', 'headline_state_name', 'local_event_window', 'state_name']","event_relevant","auto_included","cluster:0003","cluster:dod:wright-patterson-air-force-base:oh:2024-12-16:0003","same_area_incident_followup","['aircraft', 'commercial drone', 'drone', 'drones', 'helicopter', 'military drone', 'mysterious', 'mystery', 'uas', 'unidentified', 'unknown', 'unmanned aerial', 'unmanned aircraft', 'unmanned aircraft system']","mystery_drone_language","uap_adjacent_drone_language","3","['drone_term_plus_unknown_language', 'known_operator_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","Multiple Drone Incursions Force Temporary Shutdown At Ohio's Wright-Patterson Air Force Base","Check out the Best Deals on Amazon for DJI Drones today!"
5
- "event:dod:naval-weapons-station-earle-nj:nj:2024-12-09:0004","2024-12-09","report_date_proxy","dod:naval-weapons-station-earle-nj:nj","Naval Weapons Station Earle NJ","military_installation","military","NJ","40.253661","-74.157958","https://patch.com/new-jersey/middletown-nj/6-drones-flew-over-naval-weapons-station-earle-friday-night","3","medium","high","['alias', 'headline_area_context', 'local_event_window', 'state_code', 'state_name']","event_relevant","auto_included","cluster:0004","cluster:dod:naval-weapons-station-earle-nj:nj:2024-12-09:0004","same_area_incident_followup","['aircraft', 'drone', 'drones', 'helicopter', 'mysterious', 'uas', 'unexplained', 'unidentified', 'unmanned aerial', 'unmanned aerial system', 'unmanned aircraft']","mystery_drone_language","uap_adjacent_drone_language","3","['drone_term_plus_unknown_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","Nearly 12 Drones Flew Over Naval Weapons Station Earle In Middletown","Nearly 12 Drones Flew Over Naval Weapons Station Earle In Middletown"
6
- "event:dod:picatinny-arsenal:nj:2024-11-18:0005","2024-11-18","observed_date","dod:picatinny-arsenal:nj","Picatinny Arsenal","military_installation","military","NJ","40.954842","-74.542397","https://apnews.com/article/cd8866c9c2568216759007716990decf","2","high","high","['alias', 'full_area_name', 'headline_state_name', 'state_name']","event_relevant","auto_included","cluster:0005","cluster:dod:picatinny-arsenal:nj:2024-11-18:0005","same_area_incident_followup","['aircraft', 'drone', 'drones', 'helicopter', 'mysterious']","known_operator_or_mundane_drone","known_non_uap_drone_language","0","['drone_term_plus_unknown_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","FBI investigating reports of large drones flying in New Jersey, seeks public's help","Witnesses have spotted a cluster of what appear to be drones — larger than those typically used by hobbyists — as well as a possible fixed-wing aircraft flying in several areas along the Raritan River in New Jersey since Nov. 18. The FBI is investigating."
7
- "event:dod:vandenberg-space-force-base:ca:2024-11-30:0006","2024-11-30","observed_date","dod:vandenberg-space-force-base:ca","Vandenberg Space Force Base","military_installation","military","CA","34.708885","-120.542805","https://www.independent.com/2024/12/12/chinese-citizen-arrested-for-allegedly-flying-drone-over-and-photographing-vandenberg-space-force-base/","2","high","high","['alias', 'full_area_name', 'headline_area_context', 'local_event_window']","event_relevant","auto_included","cluster:0006","cluster:dod:vandenberg-space-force-base:ca:2024-11-30:0006","same_area_incident_followup","['aircraft', 'drone', 'drones']","drone_or_uas_report","drone_or_uas_report","0","['mundane_object_or_aircraft_language']","True","Chinese Citizen Arrested for Allegedly Flying Drone over and Photographing Vandenberg Space Force Base","A Chinese citizen was arrested at San Francisco Airport on Monday on criminal charges that he illegally flew an unregistered drone above Vandenberg Space Force Base while allegedly taking video and photos of SpaceX launch facilities. His arrest was preceded by a warrant affidavit"
8
- "event:dod:marine-corps-base-camp-pendleton:ca:2024-12-09:0007","2024-12-09","observed_date","dod:marine-corps-base-camp-pendleton:ca","Marine Corps Base Camp Pendleton","military_installation","military","CA","33.35459","-117.423089","https://www.yahoo.com/news/multiple-drone-incursions-confirmed-over-180614982.html","2","high","high","['alias', 'full_area_name', 'headline_area_context', 'headline_state_name', 'local_event_window', 'state_name']","event_relevant","auto_included","cluster:0007","cluster:dod:marine-corps-base-camp-pendleton:ca:2024-12-09:0007","same_area_incident_followup","['aircraft', 'anomalous', 'drone', 'drones', 'mysterious', 'not identified', 'uas', 'unknown', 'unmanned aerial', 'unmanned aerial system', 'unmanned aircraft']","known_operator_or_mundane_drone","known_non_uap_drone_language","0","['drone_term_plus_unknown_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","Multiple Drone Incursions Confirmed Over Marine Corps Base Camp Pendleton (Updated)","Marine Corps Base Camp Pendleton in southern California experienced multiple drone incursions over its airspace the past several days, a facility spokesman told The War Zone on Tuesday morning."
9
- "event:dod:joint-base-mcguire-dix-lakehurst:nj:2024-09-15:0008","2024-09-15","observed_date","dod:joint-base-mcguire-dix-lakehurst:nj","Joint Base McGuire-Dix-Lakehurst","military_installation","military","NJ","40.001498","-74.48298","https://www.foxnews.com/us/new-jersey-military-base-confirms-multiple-drone-contraband-smuggling-incursions-year","1","medium","high","['alias', 'full_area_name', 'headline_state_name', 'local_event_window', 'state_code', 'state_name']","event_relevant","auto_included","cluster:0008","cluster:dod:joint-base-mcguire-dix-lakehurst:nj:2024-09-15:0008","single_source","['aircraft', 'drone', 'drones', 'mysterious', 'uaps', 'uas', 'unmanned aircraft']","explicit_ufo_uap_language","explicit_ufo_uap_language","5","['drone_term_plus_unknown_language', 'explicit_ufo_uap_terms', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","New Jersey military base confirms multiple drone contraband-smuggling incursions this year","'Fox & Friends First' host Carley Shimkus discusses the Fox Flight Team joining the search for UAPs in the Northeast and a classified briefing for lawmakers stating nothing 'nefarious' is happening in New Jersey skies."
10
- "event:dod:barksdale-air-force-base:la:2026-03-09:0009","2026-03-09","observed_date","dod:barksdale-air-force-base:la","Barksdale Air Force Base","military_installation","military","LA","32.497199","-93.611988","https://www.thedailybeast.com/leak-reveals-major-drone-incident-at-louisiana-air-force-base-in-trumps-war/","8","high","high","['alias', 'full_area_name', 'local_event_window', 'state_name']","event_relevant","auto_included","cluster:0009","cluster:dod:barksdale-air-force-base:la:2026-03-09:0009","same_area_incident_followup","['aircraft', 'anomalous', 'balloon', 'commercial drone', 'drone', 'drones', 'mystery', 'not identified', 'uas', 'unidentified', 'unknown', 'unmanned aerial', 'unmanned aerial system', 'unmanned aircraft']","mystery_drone_language","uap_adjacent_drone_language","3","['drone_term_plus_unknown_language', 'known_operator_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","Leak Reveals Major Drone Incident at Air Force Base in Trump’s War","A drone sighting at one of America’s most important military bases was more serious than previously reported, according to a leaked document."
11
- "event:dod:joint-base-myer-henderson-hall:va:2026-03-19:0010","2026-03-19","report_date_proxy","dod:joint-base-myer-henderson-hall:va","Joint Base Myer-Henderson Hall","military_installation","military","VA","38.874585","-77.049155","https://ktul.com/news/nation-world/unidentified-drones-fly-over-fort-mcnair-expert-calls-it-security-concern","2","medium","high","['alias', 'headline_area_context', 'local_event_window', 'state_name']","event_relevant","auto_included","cluster:0010","cluster:dod:joint-base-myer-henderson-hall:va:2026-03-19:0010","same_area_incident_followup","['aircraft', 'drone', 'drones', 'unidentified', 'unknown', 'unmanned aircraft']","mystery_drone_language","uap_adjacent_drone_language","3","['drone_term_plus_unknown_language', 'mundane_object_or_aircraft_language', 'mystery_or_unknown_language']","True","Unidentified drones reported flying over Fort McNair; expert calls it security concern","Unidentified drones reported flying over Fort McNair; expert calls it security concern"
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/limitations_and_blind_spots.md DELETED
@@ -1,12 +0,0 @@
1
- # Limitations And Blind Spots
2
-
3
- - This release tracks reported drone sightings from public-source news stories and FAA preliminary UAS sighting reports; it does not prove intent, wrongdoing, threat, or a verified security breach.
4
- - UAP-adjacent labels mean the source language overlaps with mystery-drone or UFO/UAP wording; they are not UAP determinations.
5
- - This is a public-source and preliminary-reporting dataset, not a verified government incident ledger.
6
- - Stories behind paywalls, JavaScript-heavy pages, or blocked fetches can fall out of the slice.
7
- - Event points are covered-area centroids or official point locations, not narrative story coordinates.
8
- - Publication dates are used as bounded proxies when a direct observation date is not extractable.
9
- - Ambiguous multi-area stories stay in the internal review queue and are excluded from the public map.
10
- - Current gap: `airport` has `19407` monitored areas but no public events in this slice.
11
- - Current gap: `port` has `370` monitored areas but no public events in this slice.
12
- - Current gap: `power_plant` has `16104` monitored areas but no public events in this slice.
 
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/methodology.md DELETED
@@ -1,20 +0,0 @@
1
- # Drone Sightings Near Covered U.S. Military and Civilian Areas
2
-
3
- ## What This Shows
4
- This release shows a bounded set of U.S. public-source and FAA-reported drone sightings mapped to official military and civilian covered-area registries.
5
-
6
- ## How The Slice Was Built
7
- - Covered areas come from official U.S. government sources for military installations, airports, power plants, and ports.
8
- - News candidates are harvested through a bounded search layer and then fetched as raw article HTML for deterministic parsing.
9
- - Official FAA UAS sighting report rows are included only when a strict airport-code match resolves to one monitored airport.
10
- - Source records are matched only to covered-area registry entries and deduped into area-scoped events.
11
- - Each event also gets a deterministic source-language overlay that separates official UAS reports, ordinary drone-language reports, mystery-drone language, and explicit UFO/UAP language.
12
- - When a source mentions more than one plausible area and a single primary area cannot be resolved deterministically, the source is kept out of the public map.
13
-
14
- ## Source Window
15
- - Start: `2023-01-01`
16
- - End: `2026-04-24`
17
-
18
- ## What This Does Not Prove
19
- This release tracks reported drone sightings from public sources and FAA preliminary sighting reports; it does not prove intent, threat, wrongdoing, illegality, or the identity of any aircraft operator.
20
- The UAP-adjacent overlay is a language classifier only; it does not verify that a reported object was anomalous or a UAP.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/monitored_areas.csv DELETED
The diff for this file is too large to render. See raw diff
 
dataset_bundle/public_release_manifest.json DELETED
@@ -1,88 +0,0 @@
1
- {
2
- "public_version": "drone-sightings-base-events-uap-20260425-r1",
3
- "title": "Drone Sightings Near Covered U.S. Military and Civilian Areas",
4
- "release_date": "2026-04-25T15:17:58.986193+00:00",
5
- "source_run_name": "drone_sightings_curated_base_events_20260425_r6",
6
- "slice_description": "A small, review-oriented slice of U.S. public-source and FAA-reported drone sightings mapped against official covered-area registries.",
7
- "source_window": {
8
- "start_date": "2023-01-01",
9
- "end_date": "2026-04-24",
10
- "window_days": 1209
11
- },
12
- "counts": {
13
- "events": 10,
14
- "monitored_areas": 36702,
15
- "event_sources": 32,
16
- "daily_area_rollup_rows": 10,
17
- "article_candidates": 44,
18
- "article_fetch_failed": 2
19
- },
20
- "covered_area_counts_by_type": {
21
- "airport": 19407,
22
- "military_installation": 821,
23
- "port": 370,
24
- "power_plant": 16104
25
- },
26
- "event_counts_by_type": {
27
- "military_installation": 10
28
- },
29
- "event_counts_by_class": {
30
- "military": 10
31
- },
32
- "quality_summary": {
33
- "unresolved_area_share": 0.272727,
34
- "review_article_count": 12,
35
- "weak_area_review_count": 2,
36
- "weak_area_context_review_count": 0,
37
- "weak_event_context_review_count": 2,
38
- "off_scope_review_count": 1,
39
- "false_match_canary_review_count": 0,
40
- "article_fetch_failure_share": 0.045455,
41
- "article_fetch_failure_count": 2,
42
- "news_search_failure_count": 0,
43
- "official_source_failure_count": 0,
44
- "source_unavailable_count": 0,
45
- "duplicate_cluster_share": 0.9,
46
- "conflicting_area_cluster_count": 0,
47
- "review_conflicting_area_cluster_count": 0,
48
- "report_date_proxy_share": 0.5
49
- },
50
- "uap_language_overlay": {
51
- "interpretation": "This is a source-language overlay. It labels whether sources use drone/UAS, mystery-drone, or explicit UFO/UAP language; it does not verify that a reported object was a drone or a UAP.",
52
- "event_counts_by_uap_overlap_label": {
53
- "drone_or_uas_report": 1,
54
- "explicit_ufo_uap_language": 2,
55
- "known_non_uap_drone_language": 2,
56
- "uap_adjacent_drone_language": 5
57
- },
58
- "event_counts_by_language_family": {
59
- "drone_or_uas_report": 1,
60
- "explicit_ufo_uap_language": 2,
61
- "known_operator_or_mundane_drone": 2,
62
- "mystery_drone_language": 5
63
- },
64
- "uap_adjacent_event_count": 5,
65
- "explicit_ufo_uap_event_count": 2,
66
- "official_uas_event_count": 0
67
- },
68
- "included_tables": [
69
- "events.csv",
70
- "monitored_areas.csv",
71
- "event_sources.csv",
72
- "daily_area_rollup.csv",
73
- "uap_language_overlay_report.json",
74
- "public_release_manifest.json",
75
- "methodology.md",
76
- "limitations_and_blind_spots.md",
77
- "quality_checks.md",
78
- "schema_notes.md"
79
- ],
80
- "caveats": [
81
- "This release tracks reported drone sightings from public-source news stories and official FAA UAS sighting reports; FAA reports are still preliminary sighting records, not verified federal incident findings.",
82
- "UAP-adjacent labels are source-language overlap labels only; they do not verify that an object was a UAP, anomalous, or non-human.",
83
- "A reported sighting does not by itself prove intent, threat, wrongdoing, or the presence of a hostile actor.",
84
- "Events are plotted at the covered-area point or centroid, not at a freehand geocoded story location.",
85
- "Some event dates use article publication dates as bounded proxies when an observed date is not extractable from the story.",
86
- "Ambiguous multi-area stories stay in the internal review queue and are not plotted in the public dataset."
87
- ]
88
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/quality_checks.md DELETED
@@ -1,18 +0,0 @@
1
- # Quality Checks
2
-
3
- - Event rows: `10`
4
- - Monitored areas: `36702`
5
- - Event source rows: `32`
6
- - Article fetch failure share: `0.045455`
7
- - Source unavailable count: `0`
8
- - Review article count: `12`
9
- - False-match canary review count: `0`
10
- - Duplicate cluster share: `0.9`
11
- - Conflicting area clusters: `0`
12
- - Review-suppressed conflicting area clusters: `0`
13
- - Unresolved area share: `0.272727`
14
-
15
- ## Public Integrity Language
16
-
17
- - This release tracks reported drone sightings and preliminary FAA UAS sighting rows; it does not assign guilt, threat level, or motive.
18
- - Raw article HTML and long text excerpts are not included in the public bundle.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/schema_notes.md DELETED
@@ -1,15 +0,0 @@
1
- # Schema Notes
2
-
3
- ## events.csv
4
- - `event_date`: observed date when extractable, otherwise a publication-date proxy.
5
- - `review_status`: public rows are auto-included deterministic event rows only.
6
- - `source_count`: number of supporting stories retained in the dedupe cluster.
7
- - `language_family`: deterministic source-language bucket such as official UAS report, ordinary drone report, mystery-drone language, or explicit UFO/UAP language.
8
- - `uap_overlap_label`: conservative language-overlap label; it is not a verification that the object was a UAP.
9
- - `ambiguity_score`: deterministic language score, not a confidence score or factual finding.
10
-
11
- ## monitored_areas.csv
12
- - Rows represent official covered-area points or centroids used for event plotting.
13
-
14
- ## event_sources.csv
15
- - Lists supporting story URLs and titles retained for each public event.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dataset_bundle/uap_language_overlay_report.json DELETED
@@ -1,91 +0,0 @@
1
- {
2
- "report_kind": "drone_uap_language_overlay_v1",
3
- "interpretation": "This is a source-language overlay. It labels whether sources use drone/UAS, mystery-drone, or explicit UFO/UAP language; it does not verify that a reported object was a drone or a UAP.",
4
- "event_count": 10,
5
- "review_article_count": 12,
6
- "normalized_article_count": 43,
7
- "event_counts_by_uap_overlap_label": {
8
- "drone_or_uas_report": 1,
9
- "explicit_ufo_uap_language": 2,
10
- "known_non_uap_drone_language": 2,
11
- "uap_adjacent_drone_language": 5
12
- },
13
- "event_counts_by_language_family": {
14
- "drone_or_uas_report": 1,
15
- "explicit_ufo_uap_language": 2,
16
- "known_operator_or_mundane_drone": 2,
17
- "mystery_drone_language": 5
18
- },
19
- "review_counts_by_uap_overlap_label": {
20
- "drone_or_uas_report": 5,
21
- "known_non_uap_drone_language": 3,
22
- "uap_adjacent_drone_language": 4
23
- },
24
- "article_counts_by_uap_overlap_label": {
25
- "drone_or_uas_report": 9,
26
- "explicit_ufo_uap_language": 3,
27
- "known_non_uap_drone_language": 21,
28
- "uap_adjacent_drone_language": 10
29
- },
30
- "uap_adjacent_event_count": 5,
31
- "explicit_ufo_uap_event_count": 2,
32
- "official_uas_event_count": 0,
33
- "sample_uap_adjacent_events": [
34
- {
35
- "event_id": "event:dod:joint-base-langley-eustis:va:2024-10-13:0001",
36
- "event_date": "2024-10-13",
37
- "area_name": "Joint Base Langley-Eustis",
38
- "uap_overlap_label": "explicit_ufo_uap_language",
39
- "headline": "Pentagon Baffled By 17-Day Drone Swarm At US Military Base",
40
- "primary_source_url": "https://dronexl.co/2024/10/13/pentagon-drone-swarm-us-military-base/"
41
- },
42
- {
43
- "event_id": "event:dod:hill-air-force-base:ut:2024-12-18:0002",
44
- "event_date": "2024-12-18",
45
- "area_name": "Hill Air Force Base",
46
- "uap_overlap_label": "uap_adjacent_drone_language",
47
- "headline": "Multiple Drone Sightings Reported Near Hill Air Force Base Amid Nationwide Military Installation Incidents",
48
- "primary_source_url": "https://dronexl.co/2024/12/17/multiple-drone-sightings-reported-near-hill-air-force-base/"
49
- },
50
- {
51
- "event_id": "event:dod:wright-patterson-air-force-base:oh:2024-12-16:0003",
52
- "event_date": "2024-12-16",
53
- "area_name": "Wright-Patterson Air Force Base",
54
- "uap_overlap_label": "uap_adjacent_drone_language",
55
- "headline": "Multiple Drone Incursions Force Temporary Shutdown At Ohio's Wright-Patterson Air Force Base",
56
- "primary_source_url": "https://dronexl.co/2024/12/15/drone-incursions-ohio-wright-patterson-air-force-base/"
57
- },
58
- {
59
- "event_id": "event:dod:naval-weapons-station-earle-nj:nj:2024-12-09:0004",
60
- "event_date": "2024-12-09",
61
- "area_name": "Naval Weapons Station Earle NJ",
62
- "uap_overlap_label": "uap_adjacent_drone_language",
63
- "headline": "Nearly 12 Drones Flew Over Naval Weapons Station Earle In Middletown",
64
- "primary_source_url": "https://patch.com/new-jersey/middletown-nj/6-drones-flew-over-naval-weapons-station-earle-friday-night"
65
- },
66
- {
67
- "event_id": "event:dod:joint-base-mcguire-dix-lakehurst:nj:2024-09-15:0008",
68
- "event_date": "2024-09-15",
69
- "area_name": "Joint Base McGuire-Dix-Lakehurst",
70
- "uap_overlap_label": "explicit_ufo_uap_language",
71
- "headline": "New Jersey military base confirms multiple drone contraband-smuggling incursions this year",
72
- "primary_source_url": "https://www.foxnews.com/us/new-jersey-military-base-confirms-multiple-drone-contraband-smuggling-incursions-year"
73
- },
74
- {
75
- "event_id": "event:dod:barksdale-air-force-base:la:2026-03-09:0009",
76
- "event_date": "2026-03-09",
77
- "area_name": "Barksdale Air Force Base",
78
- "uap_overlap_label": "uap_adjacent_drone_language",
79
- "headline": "Leak Reveals Major Drone Incident at Air Force Base in Trump’s War",
80
- "primary_source_url": "https://www.thedailybeast.com/leak-reveals-major-drone-incident-at-louisiana-air-force-base-in-trumps-war/"
81
- },
82
- {
83
- "event_id": "event:dod:joint-base-myer-henderson-hall:va:2026-03-19:0010",
84
- "event_date": "2026-03-19",
85
- "area_name": "Joint Base Myer-Henderson Hall",
86
- "uap_overlap_label": "uap_adjacent_drone_language",
87
- "headline": "Unidentified drones reported flying over Fort McNair; expert calls it security concern",
88
- "primary_source_url": "https://ktul.com/news/nation-world/unidentified-drones-fly-over-fort-mcnair-expert-calls-it-security-concern"
89
- }
90
- ]
91
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public_copy.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "title": "Drone Sightings Near Covered U.S. Military and Civilian Areas",
3
- "dataset_bundle_prefix": "dataset_bundle",
4
- "landing_markdown": "# Drone Sightings Near Covered U.S. Military and Civilian Areas\n\nThis private preview maps public-source news stories and FAA-reported drone sightings over official covered military and civilian areas.\n\nUse the time slider plus the Play and Pause controls to watch red dots appear across time, then match the `event_id` on the map to the row data directly below it.\n\nEach point is tied to one public event row and a linked source list. This release tracks reported drone sightings and preliminary FAA UAS sighting rows; it does not prove intent, threat, wrongdoing, or a verified security breach."
5
- }
 
 
 
 
 
 
public_space_app.py CHANGED
@@ -1,7 +1,6 @@
1
  from __future__ import annotations
2
 
3
  import json
4
- import os
5
  from pathlib import Path
6
 
7
  import gradio as gr
@@ -9,307 +8,207 @@ import pandas as pd
9
  import plotly.express as px
10
 
11
 
12
- def _dataset_root(public_copy_path: Path) -> Path:
13
- payload = json.loads(public_copy_path.read_text(encoding="utf-8"))
14
- local_root = os.environ.get("PUBLIC_RELEASE_LOCAL_ROOT")
15
- if local_root:
16
- return Path(local_root) / payload["dataset_bundle_prefix"]
17
- return public_copy_path.parent / payload["dataset_bundle_prefix"]
18
-
19
-
20
- def load_release_data(public_copy_path: Path) -> dict:
21
- dataset_root = _dataset_root(public_copy_path)
22
- events = pd.read_csv(dataset_root / "events.csv")
23
- event_sources = pd.read_csv(dataset_root / "event_sources.csv")
24
- manifest = json.loads((dataset_root / "public_release_manifest.json").read_text(encoding="utf-8"))
25
- return {
26
- "events": events.fillna(""),
27
- "event_sources": event_sources.fillna(""),
28
- "manifest": manifest,
29
- }
30
-
31
-
32
- def _frame_dates(events: pd.DataFrame) -> list[str]:
33
- if events.empty:
34
- return []
35
- return sorted(str(value) for value in events["event_date"].astype(str).unique())
36
-
37
-
38
- def _frame_index(value, max_index: int) -> int:
39
- if max_index <= 0:
40
- return 0
41
- try:
42
- numeric = int(float(value))
43
- except (TypeError, ValueError):
44
- numeric = 0
45
- return max(0, min(max_index, numeric))
46
-
47
-
48
- def _visible_events(events: pd.DataFrame, frame_dates: list[str], frame_index: int) -> pd.DataFrame:
49
- if events.empty or not frame_dates:
50
- return events.iloc[0:0].copy()
51
- frame_value = frame_dates[_frame_index(frame_index, len(frame_dates) - 1)]
52
- visible = events[events["event_date"].astype(str) <= frame_value].copy()
53
- return visible.sort_values(["event_date", "event_id", "headline"], ascending=[True, True, True]).reset_index(drop=True)
54
-
55
-
56
- def _point_table(events: pd.DataFrame) -> pd.DataFrame:
57
- ordered = events.copy()
58
- ordered["event_date"] = ordered["event_date"].astype(str)
59
- for column in ["uap_overlap_label", "language_family", "ambiguity_score", "phenomenon_terms"]:
60
- if column not in ordered.columns:
61
- ordered[column] = ""
62
- ordered = ordered.sort_values(["event_date", "event_id", "headline"], ascending=[True, True, True]).reset_index(drop=True)
63
- return ordered[
64
- [
65
- "event_id",
66
- "event_date",
67
- "headline",
68
- "area_name",
69
- "area_type",
70
- "civ_mil_class",
71
- "state",
72
- "lat",
73
- "lon",
74
- "source_count",
75
- "confidence_label",
76
- "uap_overlap_label",
77
- "language_family",
78
- "ambiguity_score",
79
- "review_status",
80
- "primary_source_url",
81
- ]
82
- ]
83
-
84
-
85
- def _build_map(events: pd.DataFrame, frame_label: str):
86
- if events.empty:
87
- return px.scatter_mapbox(pd.DataFrame({"lat": [], "lon": []}), lat="lat", lon="lon", zoom=3, height=560)
88
- events = events.copy()
89
- for column in ["uap_overlap_label", "language_family"]:
90
- if column not in events.columns:
91
- events[column] = ""
92
- fig = px.scatter_mapbox(
93
- events,
94
- lat="lat",
95
- lon="lon",
96
- color_discrete_sequence=["#d62728"],
97
- hover_name="headline",
98
- hover_data={
99
- "event_id": True,
100
- "area_name": True,
101
- "state": True,
102
- "event_date": True,
103
- "source_count": True,
104
- "confidence_label": True,
105
- "uap_overlap_label": True,
106
- "language_family": True,
107
- "primary_source_url": True,
108
- "lat": False,
109
- "lon": False,
110
- },
111
- custom_data=["event_id"],
112
- zoom=3,
113
- height=560,
114
  )
115
- fig.update_layout(
116
- mapbox_style="open-street-map",
117
- margin={"l": 0, "r": 0, "t": 40, "b": 0},
118
- title=f"Reported drone sightings through {frame_label}",
119
- showlegend=False,
 
 
120
  )
121
- fig.update_traces(marker={"size": 12, "opacity": 0.85})
122
  return fig
123
 
124
 
125
- def _detail_markdown(event_sources: pd.DataFrame, events: pd.DataFrame, event_id: str) -> str:
126
- if not event_id:
127
- return "Select a row in the point-data table to inspect the exact public data and source URLs used for that plotted point."
128
- matched = events[events["event_id"] == event_id]
129
- if matched.empty:
130
- return "No event details available."
131
- event_row = matched.iloc[0]
132
- sources = event_sources[event_sources["event_id"] == event_id]
133
- lines = [
134
- f"### {event_row['headline']}",
135
- "",
136
- "This is the exact public row used to draw the point on the map.",
137
- "",
138
- f"- `event_id`: `{event_row['event_id']}`",
139
- f"- `event_date`: `{event_row['event_date']}`",
140
- f"- `date_quality`: `{event_row['date_quality']}`",
141
- f"- `area_name`: `{event_row['area_name']}`",
142
- f"- `area_type`: `{event_row['area_type']}`",
143
- f"- `civ_mil_class`: `{event_row['civ_mil_class']}`",
144
- f"- `state`: `{event_row['state']}`",
145
- f"- `lat`: `{event_row['lat']}`",
146
- f"- `lon`: `{event_row['lon']}`",
147
- f"- `source_count`: `{event_row['source_count']}`",
148
- f"- `confidence_label`: `{event_row['confidence_label']}`",
149
- f"- `uap_overlap_label`: `{event_row.get('uap_overlap_label', '')}`",
150
- f"- `language_family`: `{event_row.get('language_family', '')}`",
151
- f"- `ambiguity_score`: `{event_row.get('ambiguity_score', '')}`",
152
- f"- `phenomenon_terms`: `{event_row.get('phenomenon_terms', '')}`",
153
- f"- `review_status`: `{event_row['review_status']}`",
154
- f"- `primary_source_url`: {event_row['primary_source_url']}",
155
- "",
156
- "#### Summary",
157
- "",
158
- event_row.get("summary", ""),
159
- "",
160
- "#### Source stories behind this point",
161
- ]
162
- for _, source_row in sources.iterrows():
163
- lines.append(
164
- f"- [{source_row['publisher']} | {source_row['title']}]({source_row['canonical_url']})"
165
- f" | `published_at={source_row['published_at']}`"
166
- )
167
- return "\n".join(lines)
168
-
169
-
170
- def _detail_placeholder(frame_label: str) -> str:
171
- return (
172
- "Select a row in the point-data table to inspect the exact public data and source URLs used for a plotted point. "
173
- f"The map and table currently show all events through `{frame_label}`."
174
  )
 
 
175
 
176
 
177
- def _frame_payload(events: pd.DataFrame, event_sources: pd.DataFrame, frame_dates: list[str], frame_index: int):
178
- if not frame_dates:
179
- empty_table = _point_table(events.iloc[0:0].copy())
180
- return (
181
- _build_map(events.iloc[0:0].copy(), "no data"),
182
- empty_table,
183
- "No dated events available.",
184
- "## Point data",
185
- "Time slider unavailable because there are no dated events in this release.",
186
- empty_table.to_dict("records"),
187
- "No event details available.",
188
- )
189
- visible = _visible_events(events, frame_dates, frame_index)
190
- point_table = _point_table(visible)
191
- frame_label = frame_dates[_frame_index(frame_index, len(frame_dates) - 1)]
192
- return (
193
- _build_map(visible, frame_label),
194
- point_table,
195
- f"### Showing events through `{frame_label}`",
196
- "## Point data",
197
- "Every row below is a point currently visible on the map. The `event_id` shown on hover matches the `event_id` in the table and detail panel.",
198
- point_table.to_dict("records"),
199
- _detail_placeholder(frame_label),
200
- )
201
 
 
 
 
202
 
203
- def build_app(public_copy_path: str | Path):
204
- public_copy_path = Path(public_copy_path)
205
- payload = json.loads(public_copy_path.read_text(encoding="utf-8"))
206
- data = load_release_data(public_copy_path)
207
- events = data["events"]
208
- event_sources = data["event_sources"]
209
- frame_dates = _frame_dates(events)
210
- max_frame_index = max(0, len(frame_dates) - 1)
211
 
212
- with gr.Blocks(title=payload["title"]) as app:
213
- gr.Markdown(payload["landing_markdown"])
214
- date_markdown = gr.Markdown()
215
- plot = gr.Plot(label="Drone sightings over time")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  with gr.Row():
217
- play_button = gr.Button("Play")
218
- pause_button = gr.Button("Pause")
219
- slider = gr.Slider(
220
- minimum=0,
221
- maximum=max_frame_index,
222
- step=1,
223
- value=max_frame_index,
224
- label="Time slider",
225
- )
226
- point_heading = gr.Markdown("## Point data")
227
- point_caption = gr.Markdown("Every row below is a point currently visible on the map.")
228
- table = gr.Dataframe(label="Point data used to draw the map", interactive=False)
229
- table_rows = gr.State([])
230
- detail = gr.Markdown("Select a row in the point-data table to inspect the exact public data and source URLs used for a plotted point.")
231
- timer = gr.Timer(value=1.0, active=False)
232
-
233
- def _render_frame(frame_value):
234
- return _frame_payload(events, event_sources, frame_dates, _frame_index(frame_value, max_frame_index))
235
-
236
- def _start_playback(frame_value):
237
- next_index = _frame_index(frame_value, max_frame_index)
238
- if next_index >= max_frame_index and frame_dates:
239
- next_index = 0
240
- plot_value, table_value, date_value, heading_value, caption_value, rows_value, detail_value = _render_frame(next_index)
241
- return (
242
- gr.Timer(active=True),
243
- next_index,
244
- plot_value,
245
- table_value,
246
- date_value,
247
- heading_value,
248
- caption_value,
249
- rows_value,
250
- detail_value,
251
  )
252
-
253
- def _pause_playback():
254
- return gr.Timer(active=False)
255
-
256
- def _advance_frame(frame_value):
257
- if not frame_dates:
258
- plot_value, table_value, date_value, heading_value, caption_value, rows_value, detail_value = _render_frame(0)
259
- return (
260
- gr.Timer(active=False),
261
- 0,
262
- plot_value,
263
- table_value,
264
- date_value,
265
- heading_value,
266
- caption_value,
267
- rows_value,
268
- detail_value,
269
- )
270
- current_index = _frame_index(frame_value, max_frame_index)
271
- next_index = min(max_frame_index, current_index + 1)
272
- plot_value, table_value, date_value, heading_value, caption_value, rows_value, detail_value = _render_frame(next_index)
273
- return (
274
- gr.Timer(active=(next_index < max_frame_index)),
275
- next_index,
276
- plot_value,
277
- table_value,
278
- date_value,
279
- heading_value,
280
- caption_value,
281
- rows_value,
282
- detail_value,
283
  )
284
 
285
- def _table_detail(current_rows, evt: gr.SelectData):
286
  if not evt or evt.index is None:
287
- return "Select a row in the point-data table to inspect the exact public data and source URLs used for a plotted point."
288
  row_index = evt.index[0] if isinstance(evt.index, (list, tuple)) else evt.index
289
- if row_index >= len(current_rows):
290
- return "No event details available."
291
- event_id = str(current_rows[row_index]["event_id"])
292
- return _detail_markdown(event_sources, events, event_id)
293
-
294
- slider.change(
295
- _render_frame,
296
- inputs=slider,
297
- outputs=[plot, table, date_markdown, point_heading, point_caption, table_rows, detail],
298
- )
299
- play_button.click(
300
- _start_playback,
301
- inputs=slider,
302
- outputs=[timer, slider, plot, table, date_markdown, point_heading, point_caption, table_rows, detail],
303
- )
304
- pause_button.click(_pause_playback, outputs=timer)
305
- timer.tick(
306
- _advance_frame,
307
- inputs=slider,
308
- outputs=[timer, slider, plot, table, date_markdown, point_heading, point_caption, table_rows, detail],
309
- )
310
- table.select(_table_detail, inputs=table_rows, outputs=detail)
311
  app.load(
312
- lambda: _render_frame(max_frame_index),
313
- outputs=[plot, table, date_markdown, point_heading, point_caption, table_rows, detail],
 
314
  )
315
  return app
 
1
  from __future__ import annotations
2
 
3
  import json
 
4
  from pathlib import Path
5
 
6
  import gradio as gr
 
8
  import plotly.express as px
9
 
10
 
11
+ DISPLAY_COLUMNS = [
12
+ "case_rank",
13
+ "evidence_tier",
14
+ "report_date",
15
+ "country",
16
+ "site_name",
17
+ "site_type",
18
+ "headline",
19
+ "source_domain",
20
+ "followup_status",
21
+ ]
22
+
23
+
24
+ def _load_data(data_dir: Path) -> tuple[pd.DataFrame, dict, dict]:
25
+ cases = pd.read_csv(data_dir / "mystery_drone_sensitive_site_cases.csv").fillna("")
26
+ manifest = json.loads((data_dir / "release_manifest.json").read_text(encoding="utf-8"))
27
+ quality = json.loads((data_dir / "quality_report.json").read_text(encoding="utf-8"))
28
+ cases["report_year"] = cases["report_date"].astype(str).str.slice(0, 4).replace("", "unknown")
29
+ return cases, manifest, quality
30
+
31
+
32
+ def _markdown_header(manifest: dict, quality: dict) -> str:
33
+ tiers = manifest.get("counts_by_evidence_tier", {})
34
+ countries = manifest.get("counts_by_country", {})
35
+ top_countries = ", ".join(f"{key}: {value}" for key, value in list(countries.items())[:7])
36
+ return f"""# Mystery Drone Reports Around Sensitive Sites
37
+
38
+ Public-source review surface for mystery, unidentified, suspicious, or unauthorized drone reports around military, airport, maritime, emergency-service, and critical-infrastructure contexts.
39
+
40
+ **{manifest.get("case_count", 0)} cases** | **{manifest.get("probable_cluster_count", 0)} probable clusters** | **release gate: {"pass" if quality.get("release_grade") else "review"}**
41
+
42
+ Evidence tiers: resolved sensitive-site reports `{tiers.get("resolved_sensitive_site_report", 0)}`, named-site cases `{tiers.get("named_sensitive_site_report", 0)}`, source-discovered reports `{tiers.get("source_discovered_report", 0)}`.
43
+
44
+ Country coverage: {top_countries}
45
+
46
+ Rows are source-indexed report cases, not verified findings of threat, attribution, anomalous origin, or hostile intent.
47
+ """
48
+
49
+
50
+ def _options(values: pd.Series) -> list[str]:
51
+ return sorted(str(value) for value in values.dropna().astype(str).unique() if str(value))
52
+
53
+
54
+ def _filter_cases(
55
+ cases: pd.DataFrame,
56
+ evidence_tiers: list[str] | None,
57
+ countries: list[str] | None,
58
+ site_types: list[str] | None,
59
+ query: str,
60
+ ) -> pd.DataFrame:
61
+ filtered = cases.copy()
62
+ if evidence_tiers:
63
+ filtered = filtered[filtered["evidence_tier"].isin(evidence_tiers)]
64
+ if countries:
65
+ filtered = filtered[filtered["country"].isin(countries)]
66
+ if site_types:
67
+ filtered = filtered[filtered["site_type"].isin(site_types)]
68
+ query = str(query or "").strip().lower()
69
+ if query:
70
+ haystack = (
71
+ filtered["headline"].astype(str)
72
+ + " "
73
+ + filtered["site_name"].astype(str)
74
+ + " "
75
+ + filtered["country"].astype(str)
76
+ + " "
77
+ + filtered["source_domain"].astype(str)
78
+ ).str.lower()
79
+ filtered = filtered[haystack.str.contains(query, regex=False)]
80
+ return filtered.sort_values(["case_rank"]).reset_index(drop=True)
81
+
82
+
83
+ def _summary_text(filtered: pd.DataFrame) -> str:
84
+ if filtered.empty:
85
+ return "No rows match the current filters."
86
+ tier_counts = filtered["evidence_tier"].value_counts().to_dict()
87
+ country_counts = filtered["country"].value_counts().head(8).to_dict()
88
+ tiers = ", ".join(f"{key}: {value}" for key, value in tier_counts.items())
89
+ countries = ", ".join(f"{key}: {value}" for key, value in country_counts.items())
90
+ return f"Showing {len(filtered)} cases. Evidence tiers: {tiers}. Top countries: {countries}."
91
+
92
+
93
+ def _timeline(filtered: pd.DataFrame):
94
+ if filtered.empty:
95
+ return px.bar(pd.DataFrame({"report_year": [], "count": []}), x="report_year", y="count", height=320)
96
+ chart_data = (
97
+ filtered.groupby(["report_year", "evidence_tier"], dropna=False)
98
+ .size()
99
+ .reset_index(name="count")
100
+ .sort_values(["report_year", "evidence_tier"])
 
 
 
 
 
 
 
 
 
 
 
 
101
  )
102
+ fig = px.bar(
103
+ chart_data,
104
+ x="report_year",
105
+ y="count",
106
+ color="evidence_tier",
107
+ height=320,
108
+ labels={"report_year": "Report year", "count": "Cases", "evidence_tier": "Evidence tier"},
109
  )
110
+ fig.update_layout(margin={"l": 10, "r": 10, "t": 24, "b": 10}, legend_orientation="h")
111
  return fig
112
 
113
 
114
+ def _country_chart(filtered: pd.DataFrame):
115
+ if filtered.empty:
116
+ return px.bar(pd.DataFrame({"country": [], "count": []}), x="count", y="country", height=320)
117
+ chart_data = filtered["country"].replace("", "unknown").value_counts().head(15).reset_index()
118
+ chart_data.columns = ["country", "count"]
119
+ fig = px.bar(
120
+ chart_data,
121
+ x="count",
122
+ y="country",
123
+ orientation="h",
124
+ height=320,
125
+ labels={"country": "Country", "count": "Cases"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  )
127
+ fig.update_layout(margin={"l": 10, "r": 10, "t": 24, "b": 10}, yaxis={"categoryorder": "total ascending"})
128
+ return fig
129
 
130
 
131
+ def _table(filtered: pd.DataFrame) -> pd.DataFrame:
132
+ return filtered[DISPLAY_COLUMNS].copy()
133
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
+ def _render(cases: pd.DataFrame, evidence_tiers, countries, site_types, query):
136
+ filtered = _filter_cases(cases, evidence_tiers, countries, site_types, query)
137
+ return _summary_text(filtered), _timeline(filtered), _country_chart(filtered), _table(filtered), filtered.to_dict("records"), _detail(filtered.to_dict("records"), 0)
138
 
 
 
 
 
 
 
 
 
139
 
140
+ def _detail(rows: list[dict], index: int | None) -> str:
141
+ if not rows:
142
+ return "No case selected."
143
+ try:
144
+ row = rows[int(index or 0)]
145
+ except (IndexError, TypeError, ValueError):
146
+ row = rows[0]
147
+ return f"""### {row.get("headline", "")}
148
+
149
+ - Evidence tier: `{row.get("evidence_tier", "")}`
150
+ - Follow-up status: `{row.get("followup_status", "")}`
151
+ - Report date: `{row.get("report_date", "")}` (`{row.get("date_quality", "")}`)
152
+ - Site signal: `{row.get("site_name", "")}` / `{row.get("site_type", "")}`
153
+ - Location signal: `{row.get("country", "")}` `{row.get("state_region", "")}`
154
+ - Source: [{row.get("publisher", "") or row.get("source_domain", "")}]({row.get("source_url", "")})
155
+ - Boundary: {row.get("claim_boundary", "")}
156
+ - Row hash: `{row.get("public_row_sha256", "")}`
157
+ """
158
+
159
+
160
+ def build_app(data_dir: str | Path):
161
+ data_dir = Path(data_dir)
162
+ cases, manifest, quality = _load_data(data_dir)
163
+ with gr.Blocks(title="Mystery Drone Reports Around Sensitive Sites") as app:
164
+ gr.Markdown(_markdown_header(manifest, quality))
165
  with gr.Row():
166
+ evidence_filter = gr.CheckboxGroup(
167
+ choices=_options(cases["evidence_tier"]),
168
+ value=_options(cases["evidence_tier"]),
169
+ label="Evidence tier",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  )
171
+ country_filter = gr.Dropdown(
172
+ choices=_options(cases["country"]),
173
+ value=[],
174
+ multiselect=True,
175
+ label="Country",
176
+ )
177
+ site_filter = gr.Dropdown(
178
+ choices=_options(cases["site_type"]),
179
+ value=[],
180
+ multiselect=True,
181
+ label="Site type",
182
+ )
183
+ query = gr.Textbox(label="Search", placeholder="Try Langley, Copenhagen, airport, military base")
184
+ summary = gr.Markdown()
185
+ with gr.Row():
186
+ timeline = gr.Plot(label="Cases by report year")
187
+ country_chart = gr.Plot(label="Cases by country")
188
+ table = gr.Dataframe(label="Filtered cases", interactive=False)
189
+ rows_state = gr.State([])
190
+ detail = gr.Markdown()
191
+
192
+ def render(evidence_tiers, countries, site_types, search_query):
193
+ return _render(cases, evidence_tiers, countries, site_types, search_query)
194
+
195
+ for control in (evidence_filter, country_filter, site_filter, query):
196
+ control.change(
197
+ render,
198
+ inputs=[evidence_filter, country_filter, site_filter, query],
199
+ outputs=[summary, timeline, country_chart, table, rows_state, detail],
 
 
200
  )
201
 
202
+ def select_detail(rows, evt: gr.SelectData):
203
  if not evt or evt.index is None:
204
+ return _detail(rows, 0)
205
  row_index = evt.index[0] if isinstance(evt.index, (list, tuple)) else evt.index
206
+ return _detail(rows, row_index)
207
+
208
+ table.select(select_detail, inputs=rows_state, outputs=detail)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  app.load(
210
+ render,
211
+ inputs=[evidence_filter, country_filter, site_filter, query],
212
+ outputs=[summary, timeline, country_chart, table, rows_state, detail],
213
  )
214
  return app
requirements.txt CHANGED
@@ -1,2 +1,3 @@
1
- pandas>=2.2.0
2
- plotly>=5.24.0
 
 
1
+ gradio==5.23.1
2
+ pandas
3
+ plotly
space_manifest.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "space_bundle_version": "mystery_drone_sensitive_site_space_v1",
3
+ "source_release_version": "mystery-drone-sensitive-site-cases-2026-05-v1",
4
+ "case_count": 149,
5
+ "release_grade": true,
6
+ "artifacts": [
7
+ {
8
+ "artifact_role": "space_app",
9
+ "artifact_path": "app.py",
10
+ "content_sha256": "b1ddf49085707ffbe0bbcbe5bf16d092b6220caf0411db456fb797d7fce1db7c",
11
+ "byte_count": 167
12
+ },
13
+ {
14
+ "artifact_role": "space_public_app",
15
+ "artifact_path": "public_space_app.py",
16
+ "content_sha256": "7e3e75670d058329a171ad3c8a5e94a7f16180648ff42a14fc2fdae73db0d44c",
17
+ "byte_count": 8719
18
+ },
19
+ {
20
+ "artifact_role": "readme",
21
+ "artifact_path": "README.md",
22
+ "content_sha256": "7b777472f3186a1897a48733a178809b4b7c31bc3c7232ed485beef2322a893b",
23
+ "byte_count": 575
24
+ },
25
+ {
26
+ "artifact_role": "requirements",
27
+ "artifact_path": "requirements.txt",
28
+ "content_sha256": "ccf7886b6a189db0861827a841813e47ac71e33663dffd31eb62bf23d1bb73ec",
29
+ "byte_count": 32
30
+ },
31
+ {
32
+ "artifact_role": "cases_csv",
33
+ "artifact_path": "data/mystery_drone_sensitive_site_cases.csv",
34
+ "content_sha256": "62c2aba1b5708d7223ac6c6b3dcb94a777d4289dab73f521f93fa6baa6480aa6",
35
+ "byte_count": 105504
36
+ },
37
+ {
38
+ "artifact_role": "release_manifest",
39
+ "artifact_path": "data/release_manifest.json",
40
+ "content_sha256": "7949299f4fc596f268adcf4f97834c0aa8f2ef90c00342b2b2c8d28143aff276",
41
+ "byte_count": 2772
42
+ },
43
+ {
44
+ "artifact_role": "quality_report",
45
+ "artifact_path": "data/quality_report.json",
46
+ "content_sha256": "a8f2e692f08bd8d5fef88d00691d018f6fa0b28b2f550da995d3b2eb1f9072b3",
47
+ "byte_count": 935
48
+ }
49
+ ],
50
+ "bundle_hash": "7643bacb21b3784e4117c48f4858374d174e480e416569c7913a9553af226619"
51
+ }