v1.2.2 | Research Platform | Phase 24: bug fixes, input validation, endpoint wiring | 2026-03-11
aNEOS is an open-source Python research platform with two independent missions:
- Artificial NEO Detection -- statistical screening of Near Earth Objects for signatures inconsistent with natural dynamics, using a Bayesian multi-modal framework calibrated against confirmed artificial heliocentric objects.
- Planetary Defense Assessment -- comprehensive Earth and Moon impact probability calculation with energy, crater, and risk-period estimation.
Honest scope statement: aNEOS is a research tool, not an operational space-surveillance system. All results require independent verification through peer review, telescope follow-up, or comparison with authoritative catalogues (JPL Scout, ESA NEOCC). See Capabilities and Limitations before citing results.
The Fermi Paradox asks a deceptively simple question: given the age and scale of the galaxy, where is everybody? If intelligent civilisations arise at even a modest rate across billions of stars over billions of years, our solar system should statistically have been visited, observed, or contacted by now. The absence of any confirmed evidence is the paradox.
Most proposed resolutions fall into two camps: either civilisations are rare or short-lived (the "rare Earth" and "great filter" families), or the universe is populated but we are not looking in the right places or with the right instruments (the "dark forest", "zoo", and "artefact" families).
aNEOS is built on a specific, testable version of the second camp.
The core argument:
The solar system's Near Earth Object catalogue contains tens of thousands of rocky bodies whose orbits have been measured with high precision. We know, with certainty, that at least four human-made spacecraft currently orbit the Sun disguised as asteroids -- they were classified as natural objects by automated surveys before their artificial origin was recognised through anomaly detection. If human technology from the 1960s and 2018 can produce heliocentric objects indistinguishable from asteroids, then any sufficiently advanced technology could do the same. And if it did, those objects would already be in our catalogues, waiting to be identified.
The Fermi Paradox is partly an argument from silence: "we see no engineered objects, therefore none exist." But until aNEOS, no systematic, statistically rigorous tool existed to check whether the NEO catalogue already contains such objects. The silence has not been tested -- it has been assumed.
What falsification looks like:
- If aNEOS screens the entire known NEO population and every single object is consistent with natural dynamics at a credible confidence level, that is a genuine, quantified data point supporting the "rare Earth" resolutions.
- If even one object survives the full validation pipeline (sigma >= 5, Bayesian posterior above threshold, all known natural explanations ruled out by follow-up observation), that is a direct counterexample to the observational premise of the Fermi Paradox -- and the first physical evidence of extraterrestrial technology.
Neither outcome is assumed. The goal is to make the question answerable with existing data.
aNEOS is the first open-source implementation of this programme. See docs/scientific/theory.md for the full scientific framing and docs/scientific/VALIDATION_INTEGRITY.md for an honest account of current limitations.
Part 1: Introduction
Part 2: Getting Started
Part 3: Features
Part 4: Examples
- Screen a single NEO
- Classify a known artificial object
- Multi-evidence verbose breakdown
- Batch-screen a list
- Impact probability
- 10-year orbital history
- 200-year historical pipeline
- Population clustering and harmonics
- REST API quick tour
- Python library usage
Part 5: Use Cases by Profession
- Planetary Defense Scientists
- Astronomers
- Astrophysicists
- Astrodynamicists and Mission Planners
- SETI and Technosignature Researchers
- Software Developers and API Integrators
Part 6: Accuracy and Limitations
Part 7: Technical Reference
Part 8: Scientific Foundation
Part 9: Contributing and License
Space agencies and astronomers track tens of thousands of Near Earth Objects (NEOs), asteroids and comets whose orbits bring them close to Earth. Most are natural rocks following paths governed entirely by gravity. A small number of confirmed objects are actually human-made spacecraft, such as the Tesla Roadster launched by SpaceX in 2018 or rocket upper stages left over from Apollo-era missions, that orbit the Sun just like asteroids do.
aNEOS asks two questions about any object in those catalogues:
Question 1: Does this object behave like a natural rock?
The software downloads publicly available orbital data from NASA's JPL database, measures six different properties of the object's path around the Sun, and compares each against the known population of natural NEOs. If the object's orbit, size, brightness, or approach pattern is statistically unusual, it receives a higher "sigma score". The three confirmed artificial objects in our test set all score above sigma 5, the same threshold astronomers use to claim a scientific discovery. All natural asteroids tested score below sigma 3.
This does not mean aNEOS can detect alien spacecraft. It means it can flag objects whose behaviour is inconsistent with what we expect from rocks shaped only by gravity. Human-made spacecraft are the only known cause of such anomalies, and even then the software assigns only a 3 to 4% probability of being artificial, the realistic ceiling given what orbital data alone can tell us. Confirming artificial origin requires telescope or radar follow-up.
Question 2: Could this object hit the Earth or Moon?
For any named object, aNEOS calculates the probability of a collision with Earth and with the Moon, estimates how much energy the impact would release (in megatons of TNT), how large a crater it would leave, and which decade carries the highest risk. It also identifies "gravitational keyholes" (narrow windows in space where a close approach could nudge an object onto a future impact trajectory).
How deep does it go?
- Data is fetched live from four NASA/ESA sources (JPL SBDB, JPL Horizons, NEODyS, MPC).
- The detection framework has been validated against 4 confirmed artificial objects (2020 SO, J002E3, WT1190F, Tesla Roadster-type) and 6+ natural NEOs.
- A Kardashev synthetic training corpus generates 2 100+ labelled artificial signatures across 14 scenarios from K0.5 (rocket stages, ion probes) to K2.0 (megastructure fragments), training a RandomForest classifier that achieves AUC=1.000 on the ground-truth test set.
- The primary discriminating feature is density (hollow vs rocky), followed by albedo and non-gravitational acceleration magnitude.
- A full REST API lets other software query aNEOS programmatically.
- 360 automated tests verify the system works correctly end to end.
aNEOS is a research platform built by an independent developer. It is not affiliated with NASA, ESA, or any space agency. It does not have access to classified data, telescope feeds, or radar measurements. Its impact probability numbers are research-grade estimates, useful for screening and prioritisation, but not a replacement for the authoritative calculations produced by JPL Sentry or ESA NEOCC.
git clone https://github.com/RobLe3/aneos-suite.git
cd aneos-suite
pip install -r requirements.txt # install dependencies
python aneos.py # launch 15-option interactive menupython aneos.py api --dev
# API available at http://localhost:8000
# Interactive docs at http://localhost:8000/docspython aneos.py --legacy-menuAll items below are implemented, tested (360 unit + integration tests pass / 0 fail), and verified against real data.
| Capability | Status | Notes |
|---|---|---|
| Fetch orbital elements from JPL SBDB | Working | Apophis, Bennu, Ceres confirmed live |
| Fetch orbital elements from JPL Horizons | Working | Element tables parsed via regex |
| Fetch orbital elements from NEODyS, MPC | Working (fallback) | Graceful; fails without blocking pipeline |
| Fetch close-approach data from SBDB CAD API | Working | date-min=now, dist-max=0.2 AU |
| Fetch orbital history time-series from Horizons | Working | 10-year Keplerian element series |
| Cache with full round-trip fidelity | Working | physical_properties + fetched_at preserved across cache hits |
| Sigma-5 multi-modal detector | Working | 6 evidence types: orbital, physical, trajectory, temporal, statistical, behavioral |
| Bayesian probability calibration | Working | 0.1% base rate prior; posterior 1-4% from orbital+physical |
| Known-spacecraft catalog veto | Working | Tesla Roadster, 2020 SO, J002E3 instantly classified without statistical analysis |
| Batch detection (concurrent) | Working | POST /analyze/batch with ThreadPoolExecutor |
| Orbital history course-correction analysis | Working | _analyze_course_corrections() fired from API |
REST GET /detect endpoint |
Working | Returns DetectionResponse with sigma, tier, evidence, p-values |
REST POST /detect endpoint |
Working | Accepts user-supplied orbital elements + optional history |
REST GET /history endpoint |
Working | Returns Horizons 10-year Keplerian time-series |
| Physical indicators: diameter + albedo anomaly | Working (Phase 21) | DiameterAnomalyIndicator + AlbedoAnomalyIndicator active in detection path |
| OrbitalInput Pydantic bounds | Working (Phase 24) | a 0.1-1000 AU; e 0-2; i 0-180 deg -- invalid inputs rejected with HTTP 422 |
| NEODyS provisional designation fix | Working (Phase 24) | "1998 KY26" and "2004 MN4" no longer misparsed as year integers |
| Capability | Status | Notes |
|---|---|---|
| Earth collision probability | Working | Gravitational focusing, orbital integration |
| Moon collision probability | Working | Lunar cross-section, Earth vs Moon ratio |
| Impact energy (megatons TNT) | Working | Kinetic energy from velocity + mass |
| Crater diameter (km) | Working | Pi-scaling relations |
| Damage radius (km) | Working | Simplified energy-scaling |
| Gravitational keyhole analysis | Working | Close-approach resonance detection |
| Peak risk period (decade) | Working | Time-resolved probability evolution |
| Probability uncertainty bounds | Working | [lower, upper] confidence interval |
| Primary risk factors list | Working | Human-readable scientific rationale |
| Real arc days from SBDB observation dates | Working (Phase 17) | first_obs/last_obs parsed from SBDB orbit block |
GET /impact REST endpoint |
Working | 16-field ImpactResponse |
| Capability | Status | Notes |
|---|---|---|
| 200-year historical close-approach poll | Working | 40 x 5-year chunks via SBDB CAD API |
| DBSCAN/HDBSCAN orbital clustering | Working (Phase 11) | PA-1; density sigma-gate, background estimation |
| Synodic harmonic analysis | Working (Phase 11) | PA-3; Lomb-Scargle on binary time grid |
| Non-gravitational correlation | Working (Phase 11) | PA-5; A2 Pearson r within clusters |
| Network-level sigma combining | Working (Phase 11) | Fisher's method + Bonferroni correction; Stouffer weighted z-score optional |
POST /analyze/network REST endpoint |
Working (Phase 11) | Async job with GET .../status polling |
| Capability | Status | Notes |
|---|---|---|
| 15-option Rich terminal menu | Working | python aneos.py; 4 groups: Detection, Impact, Polling, System |
| Rich progress bars on all batch operations | Working | ANEOSMenuBase.track_progress() generator |
| File browser for designation files | Working | ANEOSMenuBase.browse_files() numbered table picker |
| Interactive results browser | Working | Pick # to see full verbose detection detail |
| API server launch from menu (Option 12) | Working | uvicorn subprocess, PID shown |
| Session detection analytics (Option 13) | Working | sigma-tier breakdown + JSON export |
| Scientific help viewer (Option 14) | Working | Reads docs/scientific/ in-terminal |
| JWT bearer token endpoint | Working (Phase 21) | POST /api/v1/auth/token exchanges API key for signed JWT |
| Gaia stdout suppression | Working (Phase 24) | Gaia import warnings redirected to debug log, not terminal |
python aneos.py
-> Choice: 1 (Detect NEO)
-> Designation: 99942 # Apophis
Output:
sigma = 1.82 INCONCLUSIVE (sigma<2)
P(artificial) = 0.1%
Combined p-value = 0.18
Evidence: orbital OK physical OK trajectory OK temporal OK statistical OK behavioral OK
python aneos.py
-> Choice: 1
-> Designation: 2020 SO # Centaur upper stage
Output:
SPACECRAFT VETO -- Known catalog match
Classification: ARTIFICIAL VALIDATED (sigma>=5)
sigma = 6.97 P(artificial) = 3.7%
Reason: Object matches SpaceX/NASA spacecraft catalog
python aneos.py
-> Choice: 2 (Multi-Evidence Analysis)
-> Designation: J002E3 # Apollo 12 S-IVB stage
Output:
sigma = 5.76 ARTIFICIAL VALIDATED
Evidence breakdown:
orbital_anomaly p=0.00094 effect=1.23 quality=0.88 analyzed
physical_properties p=0.00011 effect=2.41 quality=0.91 analyzed
trajectory_analysis p=0.00430 effect=0.87 quality=0.85 analyzed
temporal_patterns p=0.01200 effect=0.61 quality=0.79 analyzed
statistical_anomaly p=0.00320 effect=1.05 quality=0.82 analyzed
behavioral_pattern p=0.02100 effect=0.54 quality=0.75 analyzed
Create targets.txt:
99942
433
3200
25143
2020 SO
J002E3
python aneos.py
-> Choice: 3 (Batch Detection)
-> Browse files -> select targets.txt
Output (Rich progress bar):
Detecting 6 NEOs ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 6/6
┌─────────────────┬──────┬──────────────┬────────────────────────────┐
│ Designation │ σ │ P(artificial)│ Classification │
├─────────────────┼──────┼──────────────┼────────────────────────────┤
│ 99942 │ 1.82 │ 0.0010 │ ❔ INCONCLUSIVE (σ<2) │
│ 433 │ 0.94 │ 0.0010 │ ❔ INCONCLUSIVE (σ<2) │
│ 3200 │ 2.31 │ 0.0012 │ ⚠️ EDGE CASE (σ≥2) │
│ 25143 │ 1.56 │ 0.0010 │ ❔ INCONCLUSIVE (σ<2) │
│ 2020 SO │ 6.97 │ 0.0367 │ 🤖 ARTIFICIAL VALIDATED │
│ J002E3 │ 5.76 │ 0.0367 │ 🤖 ARTIFICIAL VALIDATED │
└─────────────────┴──────┴──────────────┴────────────────────────────┘
python aneos.py
-> Choice: 5 (Impact Probability)
-> Designation: 99942
Output:
P(Earth impact) = 2.31e-05
P(Moon impact) = 1.84e-06
Impact energy = 1,200 MT TNT
Crater diameter = 4.2 km
Damage radius = 38.0 km
Peak risk period : 2029-2036
Keyholes : 2
Risk factors:
* High eccentricity increases velocity at perihelion
* 2029 close approach within 32,000 km (sub-lunar)
* Resonant return opportunity 2036
python aneos.py
-> Choice: 4 (Orbital History Analysis)
-> Designation: 433 # Eros
Output (table of Keplerian elements by epoch):
┌──────────────┬────────┬────────┬────────┬────────┬──────────────┐
│ Epoch │ a(AU) │ e │ i(°) │ Ω(°) │ Da/epoch │
├──────────────┼────────┼────────┼────────┼────────┼──────────────┤
│ 2016-03-09 │ 1.4580 │ 0.2229 │ 10.83 │ 304.3 │ n/a │
│ 2017-03-09 │ 1.4581 │ 0.2229 │ 10.83 │ 304.2 │ +0.0001 │
│ ... │ ... │ ... │ ... │ ... │ ... │
└──────────────┴────────┴────────┴────────┴────────┴──────────────┘
No anomalous course corrections detected.
python aneos.py
-> Choice: 7 (Live Pipeline Dashboard)
Output:
Checking API sources ... 4/4 online
Historical Data Polling 100% 27,632 objects retrieved
ATLAS First-Stage Review 100% candidates flagged
Multi-Stage Validation 100% validated
Expert Review Queue 100% final candidates
Objects Processed : 27,632
Processing Time : 124.7 s
python aneos.py
-> Choice: 8 (Population Pattern Analysis)
-> Browse files -> select a multi-object list
Output:
Network sigma = 2.14 (PA-1 clustering + PA-3 harmonics + PA-5 correlation)
Clusters found : 3
Cluster Bonferroni p = 0.043
Synodic harmonic peak: 1.000 yr (F/yr=1.00)
Non-grav A2 correlation within clusters: r=0.41, p=0.12 (inconclusive)
# Start server
python aneos.py api --dev &
# Detect
curl "http://localhost:8000/api/v1/analysis/detect?designation=2020%20SO"
# Impact
curl "http://localhost:8000/api/v1/analysis/impact?designation=99942"
# Batch
curl -X POST "http://localhost:8000/api/v1/analysis/analyze/batch" \
-H "Content-Type: application/json" \
-d '{"designations": ["99942","433","2020 SO"], "include_evidence": true}'
# 10-year orbital history
curl "http://localhost:8000/api/v1/analysis/history?designation=433"
# Health
curl "http://localhost:8000/api/v1/health"import asyncio
from aneos_core.data.fetcher import DataFetcher
from aneos_core.detection.detection_manager import DetectionManager, DetectorType
from aneos_core.config.settings import ANEOSConfig
config = ANEOSConfig()
fetcher = DataFetcher(config)
manager = DetectionManager(DetectorType.AUTO)
async def screen(designation: str):
neo_data = await asyncio.to_thread(fetcher.fetch_neo_data, designation)
result = manager.analyze_neo(
designation=designation,
orbital_elements=neo_data.orbital_elements.__dict__,
additional_data={"physical_data": neo_data.physical_properties.__dict__
if neo_data.physical_properties else {}},
)
print(f"{designation}: sigma={result.sigma_confidence:.2f} "
f"tier={result.sigma_tier} P={result.artificial_probability:.4f}")
asyncio.run(screen("99942"))
# -> 99942: sigma=1.82 tier=INCONCLUSIVE P=0.0010
asyncio.run(screen("2020 SO"))
# -> 2020 SO: sigma=6.97 tier=EXCEPTIONAL P=0.0367 [spacecraft veto]What aNEOS provides:
- A secondary screening layer for newly discovered NEOs. Feed a designation into
GET /detectand receive a structuredDetectionResponsewith six independent evidence types (orbital, physical, trajectory, temporal, statistical, behavioral), sigma confidence, and a Fisher-combined p-value. GET /impactreturns a 16-field impact assessment including probability uncertainty bounds, keyhole passage analysis, peak risk decade, and a list of human-readable primary risk factors, supplementing (not replacing) your Monte Carlo orbit determination pipelines.- Batch screening of observation lists via
POST /analyze/batch.
What you bring:
- Authoritative orbit solutions. aNEOS uses JPL SBDB/Horizons orbital elements; for newly-discovered objects with short arcs, your own reduced elements will be more accurate.
- Telescope resources for follow-up. aNEOS flags anomalies; confirmation requires additional observations.
Example workflow:
# Screen a new discovery
curl "http://localhost:8000/api/v1/analysis/detect?designation=2024%20YR4"
# Get full impact profile
curl "http://localhost:8000/api/v1/analysis/impact?designation=2024%20YR4"
# Force fresh fetch (bypass cache)
curl "http://localhost:8000/api/v1/analysis/detect?designation=Apophis&force_refresh=true"Current quality: On the 3 confirmed artificial heliocentric objects in our ground truth set (Tesla Roadster, 2020 SO, J002E3), the detector achieves sigma >= 5.76 for all three. On 20+ real JPL natural NEOs, specificity = 1.00 (zero false positives at the calibrated threshold of 0.037). This is a small validation set; treat it as a proof of concept, not a production accuracy guarantee.
What aNEOS provides:
- An API endpoint (
GET /history) that retrieves 10-year Keplerian element time-series from JPL Horizons for any named body. Useful for visualising long-term orbital evolution without writing Horizons query scripts yourself. - Automated anomaly scoring across 6 indicator categories. If you observe an object that seems unusual, submit its orbital elements to
POST /detectand receive a structured assessment in seconds. - Close-approach data (within 0.2 AU, from present onward) fetched automatically from SBDB CAD API for every object analysed.
Example: check whether a newly reported object's orbit is consistent with natural dynamics
import requests
# Submit your reduced orbital elements directly
resp = requests.post("http://localhost:8000/api/v1/analysis/detect", json={
"a": 1.91, # AU
"e": 0.33,
"i": 11.4, # degrees
"diameter_km": 0.006,
"designation": "my_target",
})
result = resp.json()
print(f"sigma={result['sigma_confidence']:.2f}, tier={result['sigma_tier']}")
print(f"P(artificial)={result['artificial_probability']*100:.3f}%")
print(f"Evidence sources: {len(result['evidence_sources'])}")What aNEOS cannot do: It cannot process raw photometry, spectra, or astrometric residuals. It works only from orbital elements and physical properties (diameter, albedo), the same inputs available in public catalogues.
What aNEOS provides:
- A transparent Bayesian detection framework you can read, audit, and extend. The canonical detector (
aneos_core/detection/validated_sigma5_artificial_neo_detector.py) implements Fisher's method for combining p-values across independent evidence streams, followed by Bayesian updating with a 0.1% base-rate prior. All statistical methods are documented indocs/scientific/scientific-documentation.md. - A ground truth dataset builder (
aneos_core/datasets/ground_truth_dataset_preparation.py) that constructs a labelled corpus from JPL SBDB (confirmed naturals) and known heliocentric spacecraft (confirmed artificials). The corpus currently covers 9 artificials and up to 250 naturals. - Honest uncertainty quantification:
ImpactResponsereturnsprobability_uncertainty(lower/upper bounds),calculation_confidence, andimpact_probability_by_decade, making temporal evolution visible.
Key statistical property to understand:
| Observation | Sigma | P(artificial) |
|---|---|---|
| Tesla Roadster orbital+physical | 5.76 | ~3.7% |
| Apophis orbital only | < 2.0 | ~0.1% |
| Any natural NEO (observed threshold) | < 3.0 | ~0.1-0.2% |
The posterior is bounded by the base prior. To exceed 10% P(artificial), propulsion signatures or observed course corrections are required; no such automated data source currently exists. This is mathematically correct, not a software limitation.
What aNEOS provides:
- Impact keyhole analysis:
ImpactResponse.keyhole_passageslists resonant return opportunities with associated probability amplification. - Temporal risk evolution:
impact_probability_by_decadeandpeak_risk_period([start_year, end_year]) allow mission timeline planning against the probability curve. - Earth vs Moon impact ratio:
moon_earth_ratioquantifies which body is at greater risk, relevant for protecting future lunar infrastructure. - Artificial object uncertainty flag: if
is_artificial=Trueorartificial_probability > 0.037, the impact assessment is annotated withartificial_object_considerations, indicating that trajectory uncertainty from potential propulsion capability is not modelled.
Example: screen a candidate for a kinetic deflection mission
import requests
r = requests.get("http://localhost:8000/api/v1/analysis/impact",
params={"designation": "99942"}) # Apophis
data = r.json()
print(f"P(Earth) = {data['collision_probability']:.2e}")
print(f"P(Moon) = {data['moon_collision_probability']:.2e}")
print(f"Peak risk: {data['peak_risk_period']}")
print(f"Keyholes: {len(data['keyhole_passages'])}")
print(f"Energy: {data['impact_energy_mt']:.0f} MT TNT")
print(f"Damage radius: {data['damage_radius_km']:.1f} km")
for factor in data['primary_risk_factors']:
print(f" * {factor}")What aNEOS provides:
- The world's first open-source statistical framework specifically designed to test whether a heliocentric object's orbital and physical properties are inconsistent with the natural NEO population, the foundation of the Artificial NEOs Theory.
- Six independent anomaly indicators (orbital dynamics, physical properties, trajectory, temporal patterns, statistical anomaly, behavioral patterns), each contributing an independent p-value combined via Fisher's method.
- A calibrated interpretation tier system: ROUTINE / NOTABLE / INTERESTING / SIGNIFICANT (sigma>=3) / ANOMALOUS (sigma>=4) / EXCEPTIONAL (sigma>=5).
analysis_metadatain everyDetectionResponse: detector version, population reference statistics, and method parameters for reproducibility.
What aNEOS cannot prove: It cannot confirm artificial intelligence control, propulsion, or intentionality. High sigma (unusual orbit) + high P(artificial) is a flag for follow-up, not a discovery claim. The gap between "statistically unusual" and "artificial" requires propulsion/course-correction evidence that no automated catalogue provides today.
What aNEOS provides:
- A FastAPI application with 52+ REST endpoints, auto-generated OpenAPI schema (
docs/api/openapi.json, regenerated bymake spec), and typed Pydantic models for every request and response. GET /detect?designation=...&force_refresh=truefor real-time detection with cache control.POST /detectto supply your own orbital elements; optionally passorbital_history(fromGET /history) to enable course-correction analysis.GET /historyfor JPL Horizons 10-year Keplerian time-series.GET /impactfor a 16-field impact assessment.POST /analyze/batchfor concurrent batch detection with evidence detail in each result.GET /healthfor a typed health check with per-component status.
Quick API test:
# Install and start
python install.py --core && python aneos.py api --dev &
# Health check
curl http://localhost:8000/api/v1/health
# Detect 2020 SO (Centaur upper stage -- should return spacecraft_veto=true)
curl "http://localhost:8000/api/v1/analysis/detect?designation=2020%20SO"
# Get Apophis impact profile
curl "http://localhost:8000/api/v1/analysis/impact?designation=99942"
# Browse interactive docs
open http://localhost:8000/docsThe following results are reproducible by running python -m pytest tests/ -m "not network" -q and the ground truth validation suite.
| Metric | Value | Source |
|---|---|---|
| Unit / integration tests | 360 pass, 0 fail | pytest tests/ aneos_core/tests/ -m "not network" |
| Ground truth artificial objects | 3 confirmed | Tesla Roadster (SpaceX 2018-017A), 2020 SO (Centaur/Surveyor-2), J002E3 (Apollo 12 S-IVB) |
| Ground truth natural NEOs | 20+ | JPL SBDB query, real orbital data |
| Sensitivity (recall) | 1.00 | All 3 artificials correctly classified at calibrated threshold 0.037 |
| Specificity | 1.00 | Zero natural NEOs falsely flagged at calibrated threshold |
| F1 score | 1.00 | At calibrated threshold 0.037 |
| ROC-AUC | 1.00 | Validated externally |
| Tesla Roadster sigma | 5.76 | Sigma5DetectionResult |
| 2020 SO sigma | 6.97 | Sigma5DetectionResult |
| J002E3 sigma | 5.76 | Sigma5DetectionResult |
| Max P(artificial) from orbital+physical | 3-4% | Bayesian posterior, 0.1% prior |
Important context: The ground truth set is small (3 artificials, 20+ naturals). Perfect discrimination on this set demonstrates the approach works; it does not guarantee the same performance on a large, diverse unseen corpus. The Bayesian posterior ceiling (3-4%) is mathematically correct given the 0.1% base rate and available evidence types; it is not a software bug.
What aNEOS supports today:
- Statistical screening of NEOs by orbital and physical anomaly indicators
- Multi-source data acquisition: JPL SBDB, JPL Horizons, NEODyS, MPC (with graceful fallback)
- Close-approach history (upcoming, within 0.2 AU) via SBDB CAD API
- 200-year historical close-approach polling (40 x 5-year chunks, SBDB CAD API)
- Time-series orbital element history via JPL Horizons
- Earth and Moon impact probability with uncertainty bounds, keyholes, risk periods
- Population-level orbital clustering, synodic harmonic analysis, non-grav correlation (BC11)
- REST API with OpenAPI specification, Pydantic models, and batch processing
- Clean 15-option Rich terminal menu (
python aneos.py) - JSON/CSV export of analysis results
- shelve-based caching for CAD data (24-hour TTL)
What aNEOS does NOT support:
| Gap | Reason |
|---|---|
| Propulsion / manoeuvre signature detection | No automated data source exists; requires dedicated tracking campaigns |
| Radar polarimetry (SC/OC ratio) | SWARM KAPPA implemented but no live data feed |
| Thermal infrared modelling (NEATM) | SWARM LAMBDA implemented but requires WISE/NEOWISE photometry input |
| Gaia astrometric anomaly detection | SWARM MU implemented but requires Gaia epoch astrometry input |
| Real-time NEO discovery alerts | No MPC/JPL Scout webhook integration |
| Observation scheduling or telescope control | Out of scope for this platform |
| Production authentication (JWT) | Mock tokens in dev mode; not suitable for public deployment |
| ML classifier activation | Deferred (G-015); scikit-learn pipeline exists but is not wired into the default detection path |
| Processing raw photometry or spectra | Only processed orbital elements and physical properties are accepted |
| IAU Torino / Palermo scale ratings | aNEOS uses its own risk classification; Torino/Palermo require authoritative orbit solutions |
| ESA/NASA operational endorsement | aNEOS is an independent research tool |
- Report a result as "anomalous" only if
sigma_confidence >= 3.0(SIGNIFICANT tier). - Report a result as "potential artificial" only if
sigma_confidence >= 5.0(EXCEPTIONAL tier) and independent follow-up confirms the anomaly. - Do not cite
artificial_probabilityas proof of artificiality. The maximum posterior from orbital+physical evidence alone is 3-4%. Values in this range indicate "unusual orbit", not "confirmed artificial object". - Cross-check impact probabilities against JPL Scout or ESA NEOCC for any object with
collision_probability > 1e-6.
aneos-suite/
+-- aneos_core/ # Core science and data packages
| +-- data/ # DataFetcher, CacheManager, SBDB/Horizons/NEODyS/MPC sources
| +-- detection/ # ValidatedSigma5ArtificialNEODetector (canonical), DetectionManager
| +-- analysis/ # ImpactProbabilityCalculator, scoring, pipeline
| +-- validation/ # 6 SWARMs (KAPPA/LAMBDA/MU/CLAUDETTE/THETA/ATLAS), stats
| +-- datasets/ # Ground truth dataset builder and validator
| +-- ml/ # ML classifier (deferred, behind HAS_TORCH guard)
| +-- monitoring/ # Prometheus/Grafana, psutil metrics, SMTP alerts
| +-- config/ # APIConfig, settings
+-- aneos_api/ # FastAPI application
| +-- endpoints/ # analysis, dashboard, monitoring, admin, data
| +-- schemas/ # Pydantic models: DetectionResponse, ImpactResponse, OrbitalInput, ...
| +-- app.py # Application factory
+-- aneos_dashboard/ # Web dashboard (Flask)
+-- aneos_menu_v2.py # 15-option Rich terminal menu (primary)
+-- aneos_menu.py # Legacy 121-option menu (--legacy-menu flag)
+-- aneos_menu_base.py # Shared UI helpers: progress bars, file browser, display
+-- aneos.py # CLI entry point
+-- tests/ # 360 unit and integration tests
+-- docs/ # Architecture (ADR, DDD), API spec, user guide, scientific docs
Detection pipeline:
GET /detect?designation=Apophis
|
+- Known spacecraft catalog veto -> instant ARTIFICIAL (no analysis)
|
+- DataFetcher.fetch_neo_data()
| +- JPL SBDB -> orbital elements + physical properties
| +- JPL Horizons -> element table (fallback)
| +- NEODyS / MPC -> element table (fallback)
| +- SBDB CAD API -> close-approach history (supplemental, never blocks)
|
+- HorizonsSource.fetch_orbital_history() -> 10-year Keplerian time-series
|
+- ValidatedSigma5ArtificialNEODetector.analyze_neo_validated()
+- 6 evidence modules -> individual p-values
+- Fisher's method -> combined_p_value
+- Bayesian update -> bayesian_probability (0.1% prior)
+- DetectionResponse -> sigma_confidence, sigma_tier, evidence_sources, ...
Full OpenAPI specification: docs/api/openapi.json (regenerate with make spec).
Interactive documentation at http://localhost:8000/docs when the API server is running.
Key endpoints:
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/analysis/detect |
Run Sigma-5 detector on a named NEO |
| POST | /api/v1/analysis/detect |
Run detector on caller-supplied orbital elements |
| GET | /api/v1/analysis/impact |
Compute Earth/Moon impact probability |
| GET | /api/v1/analysis/history |
Fetch 10-year Keplerian history from Horizons |
| POST | /api/v1/analysis/analyze/batch |
Batch detection for multiple designations |
| GET | /api/v1/analysis/batch/{id}/status |
Poll batch job with full evidence detail |
| GET | /api/v1/health |
Per-component health check |
| GET | /api/v1/data/neo/{designation} |
Raw NEO data fetch |
DetectionResponse fields:
| Field | Description |
|---|---|
sigma_confidence |
Sigma above natural NEO null hypothesis |
sigma_tier |
ROUTINE / NOTABLE / INTERESTING / SIGNIFICANT / ANOMALOUS / EXCEPTIONAL |
artificial_probability |
Bayesian posterior (0.1% prior) |
combined_p_value |
Fisher's combined p-value across evidence types |
false_discovery_rate |
Expected FDR at current sigma threshold |
evidence_sources |
List of EvidenceSummary with anomaly_score, p_value, effect_size |
analysis_metadata |
Detector version, method, population statistics |
spacecraft_veto / veto_reason |
Instant classification for known spacecraft |
ImpactResponse fields (16 total):
| Field | Description |
|---|---|
collision_probability |
Earth impact probability |
probability_uncertainty |
[lower, upper] confidence interval |
moon_collision_probability |
Moon impact probability |
moon_earth_ratio |
Relative risk between Moon and Earth |
impact_energy_mt |
Energy released in megatons TNT |
crater_diameter_km |
Estimated crater diameter |
damage_radius_km |
Estimated damage radius |
keyhole_passages |
Resonant return windows |
peak_risk_period |
Decade of highest risk |
impact_probability_by_decade |
Time-resolved probability evolution |
primary_risk_factors |
Human-readable rationale list |
comparative_risk |
Risk context relative to historical events |
aNEOS builds on the Artificial NEOs Theory, the hypothesis that some Near Earth Objects may exhibit orbital or physical properties statistically inconsistent with natural formation and evolution, potentially indicating artificial origin. This is a scientific hypothesis, not an established finding.
The statistical framework is grounded in:
- Bayesian inference: Posterior probability updated from a 0.1% base rate (estimated fraction of heliocentric objects that could be artificial). This prior is conservative; the true rate is unknown.
- Fisher's method: Independent p-values from 6 evidence types are combined into a single test statistic. Under the natural null hypothesis, this statistic follows a chi-squared distribution with 2k degrees of freedom.
- Sigma-5 threshold: Classification as artificial requires combined significance >= 5-sigma (p < 5.7e-7), matching standard astronomical discovery criteria.
- Calibrated threshold: At p(Bayesian) >= 0.037, the current ground truth validation achieves sensitivity = 1.00 and specificity = 1.00 on the available corpus.
Further reading:
- Full methodology:
docs/scientific/scientific-documentation.md - Theory:
docs/scientific/theory.md - Honest caveats:
docs/scientific/VALIDATION_INTEGRITY.md - Architecture decisions:
docs/architecture/ADR.md(60 ADRs) - Domain model:
docs/architecture/DDD.md(11 bounded contexts) - Current state summary:
docs/current-state-summary.md
See CONTRIBUTING.md for development guidelines. The project follows the C&C + Implementation + Q&A agent structure defined in DEVELOPMENT_FRAMEWORK.md.
Run the test suite before opening a pull request:
python -m pytest tests/ aneos_core/tests/ -m "not network" -q # 360 tests, 0 fail
make spec # regenerate OpenAPI spec
git diff --stat docs/api/openapi.json # confirm spec is currentLicense: Scientific research and educational use. See LICENSE for complete terms.
aNEOS v1.2.2 | Phase 24 complete | Bug fixes: NEODyS provisional designation misparse, Gaia stdout suppression, DetectionResult falsy-zero guard, monitoring alert kwarg | Input validation: Pydantic bounds on OrbitalInput (a/e/i), designation length on AnalysisRequest | Endpoint wiring: get_validation_summary uses real DB, SSE streaming uses real alert_manager | Demo NEO list updated with real designations | REST API: 52+ endpoints | Test suite: 360 pass / 0 fail