likhitha281/orbital-collision-risk-agent

Python

0

13 commits

updated Oct 15, 2026

See the code

See what people are saying

SourceMessageScoreDate

Roast my GitHub projects — are these actually good enough for Applied AI/ML or FDE roles? (r/LargeLanguageModels)

Hey everyone! I'm currently pursuing a Master's in Data Science and targeting Applied AI Engineer, ML Engineer, and Forward Deployed Engineer (FDE) roles. I've been working on several projects to strengthen my engineering skills and portfolio. I'll be transparent: I used AI coding tools quite…

1

Oct 10, 2026

README

🛰️ Orbital Collision-Risk Agent

CI

Python License

🔴 Live Dashboard

A deterministic priority-scoring and trend-detection pipeline for real orbital conjunction data, with an optional LLM-assisted explanation layer.

The system is intentionally not an autonomous agent. It does not perform dynamic tool selection, maintain an open-ended decision loop, or delegate risk calculations to an LLM. Given collision probability, time to closest approach, and tracking-data age, operational priority is computed using a deterministic scoring function.

The optional LLM component is limited to generating human-readable explanations. It is structurally separated from numerical risk calculations and cannot modify collision probabilities or priority scores.

See Why the System Is Deterministic for the design rationale.

Overview

CelesTrak SOCRATES Plus
(real conjunction data)
        ↓
Persist to SQLite
(observation history keyed by object pair + TCA)
        ↓
Deterministic priority scoring
(Pc severity + urgency + data freshness)
        ↓
Trend detection
(escalating / decreasing / stable)
        ↓
Optional LLM explanation
(or rule-based fallback)
        ↓
Dashboard + Markdown/JSON report

For each conjunction, the system keeps three concerns explicitly separated:

  • Collision probability — Provided by CelesTrak SOCRATES Plus, which computes conjunction data using professional STK/Conjunction Analysis Tools and tracking covariance. This project does not independently recompute the value.

  • Operational priority — A 0–100 score calculated by src/risk_scoring.py from three explicitly weighted factors. The calculation is deterministic and isolated from the LLM layer.

  • Explanation — Generated by src/analyst.py from the calculated score and observation history. Its output schema contains no field capable of overriding a probability or priority score, regardless of whether the explanation comes from an LLM or the rule-based fallback.

Example Output

HIGH · 74.5/100

ISS (ZARYA) vs COSMOS 2251 DEB

MetricValue
Collision probability (SOCRATES)6.1 × 10⁻⁵
Miss distance620 m
Time to closest approach7.5 h
TrendFirst observation — insufficient history

Recommend an active maneuver evaluation and re-screen against fresher tracking data. (Low confidence, rule-based fallback — no API key configured for this example.)

Why the System Is Deterministic

An earlier version of this project used the term agent because it incorporated an LLM call. The current architecture uses more precise terminology.

Research such as ReAct (Yao et al., 2022) and Toolformer (Schick et al., 2023) characterizes agentic behavior around a model selecting actions or tools dynamically in response to observations. This pipeline follows a predefined execution path:

fetch → score → detect trend → explain

Each stage executes in the same order and has a clearly defined responsibility.

This design is particularly appropriate for collision-risk prioritization. When structured inputs and a well-defined scoring function are available, deterministic computation provides several important properties:

  • reproducibility;
  • low execution cost;
  • predictable latency;
  • straightforward testing; and
  • auditability.

The LLM therefore serves only as an explanation layer rather than a decision-making component.

A more detailed discussion—including a scoring defect discovered by the project's test suite, in which a near-zero collision probability could incorrectly produce a MEDIUM classification—is available in docs/RESEARCH.md.

Quick Start

Clone the repository and install the dependencies:

git clone https://github.com/likhitha281/orbital-collision-risk-agent.git
cd orbital-collision-risk-agent
pip install -r requirements.txt

Run the triage pipeline:

python run_triage.py \
  --max-results 50 \
  --min-probability 1e-6 \
  --output triage_report.md

Optional LLM Explanations

To use LLM-generated explanations instead of the rule-based fallback:

export ANTHROPIC_API_KEY=sk-ant-...
python run_triage.py --output triage_report.md

Both implementations follow the same output contract. Neither explanation path can modify numerical risk values.

Run the Tests

python -m pytest tests/ -v

The test suite contains 41 tests, including a schema-level check verifying that the explanation layer has no numeric override field.

Integration Note

Before relying on the live SOCRATES integration in production, verify the CSV endpoint used by src/socrates_client.py.

The implementation assumes that SOCRATES Plus accepts a FORMAT=CSV parameter, following conventions used elsewhere by CelesTrak. The development environment used for this project could not directly verify that URL.

The CSV parsing logic itself follows CelesTrak's documented column format. See the module docstring for additional details.

Trend Detection

A single execution provides a snapshot of the current conjunction data. Repeated executions add temporal context.

The scheduled live-monitor.yml workflow persists observation history between runs, allowing the system to identify changes such as:

Collision probability increased 51× across the last three observations.

This is materially different from simply restating a single observation.

During development, trend detection was tested end-to-end using two simulated observations of the same object pair:

  • the first observation correctly reported insufficient historical data;
  • the second increased the fixture's collision probability;
  • the system detected a 50.8× escalation; and
  • operational priority changed from MEDIUM to HIGH.

The calculated escalation matched the underlying ratio rather than relying on generated interpretation.

Physics Baseline

run_baseline.py provides a secondary, educational implementation of orbital propagation and conjunction screening.

It includes:

  • SGP4 orbit propagation;
  • conjunction screening; and
  • the 2D collision-probability method described by Foster & Estes (1992).

This component is included to demonstrate the orbital mechanics underlying conjunction analysis. It is not used by the live operational pipeline.

Because TLE data does not include real tracking covariance, the baseline uses an assumed covariance. Its resulting collision-probability values should therefore be treated as illustrative rather than operational.

Established tools already provide full-catalog conjunction screening, including:

  • CelesTrak SOCRATES Plus; and
  • the open-source SIMPLETON screener.

For this reason, the live pipeline consumes SOCRATES conjunction data rather than attempting to replace established screening infrastructure.

Run the baseline with the included sample catalog:

python run_baseline.py \
  --input data/sample_catalog.tle \
  --output report.md

Or fetch live CelesTrak TLE data:

python run_baseline.py \
  --live \
  --live-group stations \
  --output report.md

See docs/RESEARCH.md for implementation details, assumptions, and the rationale for separating the physics baseline from the live pipeline.

Optional Chat Interface

The dashboard includes an optional chat interface for querying the current dataset in natural language, for example:

  • “What is the highest-priority event?”
  • “Are any conjunctions escalating?”

The chatbot is grounded exclusively in the dashboard's JSON snapshot and is instructed not to generate numerical values that are absent from the source data.

Because GitHub Pages provides static hosting, the LLM API key cannot safely be stored in client-side JavaScript. The project therefore includes chatbot/worker.js, a Cloudflare Worker that keeps the API key server-side.

See chatbot/README.md for deployment instructions and a discussion of the security boundaries, including what CORS does and does not protect.

Request handling—including CORS behavior, validation, rate limiting, and error handling—is tested independently through:

chatbot/test_worker.mjs

The test suite contains 11 checks and does not require a live deployment.

Deployment Options

The core pipeline remains unchanged across deployment environments. The available options differ only in how the pipeline is packaged, scheduled, and operated.

The default deployment uses GitHub Actions through:

.github/workflows/live-monitor.yml

For the current workload—one fetch and scoring pass every 12 hours with no inter-task dependencies—this provides a lightweight scheduling mechanism without additional infrastructure.

Alternative deployment configurations are included for environments with different operational requirements:

ApproachAppropriate Use Case
Docker (Dockerfile, docker-compose.yml)Running the application independently of GitHub-hosted infrastructure
Kubernetes (k8s/cronjob.yaml)Deploying alongside workloads in an existing Kubernetes cluster
Prefect (orchestration/)Coordinating multiple data sources, task dependencies, retries, or backfills

Project Structure

├── run_triage.py
│   └── Primary pipeline entry point
│
├── run_baseline.py
│   └── Secondary SGP4 physics baseline
│
├── src/
│   ├── socrates_client.py
│   │   └── CelesTrak SOCRATES Plus conjunction data
│   ├── observation_store.py
│   │   └── SQLite observation history
│   ├── risk_scoring.py
│   │   └── Deterministic priority scoring
│   ├── trends.py
│   │   └── Historical trend detection
│   ├── analyst.py
│   │   └── Explanation layer
│   ├── triage.py
│   │   └── Record filtering and prioritization
│   ├── tle_loader.py
│   ├── live_fetch.py
│   ├── conjunction.py
│   ├── probability_of_collision.py
│   ├── knowledge_base.py
│   ├── reasoning_agent.py
│   └── report.py
│
├── data/
│   └── sample_catalog.tle
│
├── examples/
│   └── Worked example outputs
│
├── tests/
│   └── 41 automated tests
│
├── docs/
│   ├── index.html
│   │   └── GitHub Pages dashboard and chat interface
│   ├── latest.json
│   │   └── Auto-updated dashboard data
│   └── RESEARCH.md
│       └── Research references, design rationale, and limitations
│
├── chatbot/
│   ├── worker.js
│   │   └── Cloudflare Worker backend
│   ├── test_worker.mjs
│   │   └── Worker tests
│   └── wrangler.toml
│
├── Dockerfile
├── docker-compose.yml
├── k8s/
├── orchestration/
│
└── .github/workflows/
    ├── ci.yml
    │   └── Continuous integration
    └── live-monitor.yml
        └── Scheduled fetch, scoring, and publishing

Known Limitations

  • SOCRATES CSV endpoint — The exact CSV endpoint parameter used by src/socrates_client.py could not be verified from the project's development environment. It should be validated before production use.

  • Physics-baseline knowledge base — The baseline uses six manually written reference notes rather than a comprehensive corpus of operational documentation.

  • External collision probabilities — The live pipeline trusts and attributes collision-probability values provided by CelesTrak. It does not independently validate those values.

  • Trend estimation — Trend detection compares the oldest and newest stored observations rather than fitting a time-series model. Early noisy observations may therefore influence initial classifications until additional history is available.

  • Baseline scalability — The educational physics baseline uses fixed-grid screening with O(n²) scaling. This limitation does not affect the live pipeline because that path consumes precomputed SOCRATES conjunction data.

Research and References

docs/RESEARCH.md contains the project's research background and detailed engineering rationale, including:

  • Foster & Estes (1992) on 2D collision probability;
  • Vallado et al. on SGP4;
  • Kessler & Cour-Palais (1978);
  • Yao et al. (2022) on ReAct;
  • Schick et al. (2023) on Toolformer;
  • CelesTrak SOCRATES Plus;
  • SIMPLETON; and
  • documented implementation assumptions and simplifications.

It also describes issues identified during development and how automated testing exposed and corrected them.

License

MIT — see LICENSE.

likhitha281/orbital-collision-risk-agent

Python

0

13 commits

updated Oct 15, 2026

See the code

See what people are saying

SourceMessageScoreDate

Roast my GitHub projects — are these actually good enough for Applied AI/ML or FDE roles? (r/LargeLanguageModels)

Hey everyone! I'm currently pursuing a Master's in Data Science and targeting Applied AI Engineer, ML Engineer, and Forward Deployed Engineer (FDE) roles. I've been working on several projects to strengthen my engineering skills and portfolio. I'll be transparent: I used AI coding tools quite…

1

Oct 10, 2026

README

🛰️ Orbital Collision-Risk Agent

CI

Python License

🔴 Live Dashboard

A deterministic priority-scoring and trend-detection pipeline for real orbital conjunction data, with an optional LLM-assisted explanation layer.

The system is intentionally not an autonomous agent. It does not perform dynamic tool selection, maintain an open-ended decision loop, or delegate risk calculations to an LLM. Given collision probability, time to closest approach, and tracking-data age, operational priority is computed using a deterministic scoring function.

The optional LLM component is limited to generating human-readable explanations. It is structurally separated from numerical risk calculations and cannot modify collision probabilities or priority scores.

See Why the System Is Deterministic for the design rationale.

Overview

CelesTrak SOCRATES Plus
(real conjunction data)
        ↓
Persist to SQLite
(observation history keyed by object pair + TCA)
        ↓
Deterministic priority scoring
(Pc severity + urgency + data freshness)
        ↓
Trend detection
(escalating / decreasing / stable)
        ↓
Optional LLM explanation
(or rule-based fallback)
        ↓
Dashboard + Markdown/JSON report

For each conjunction, the system keeps three concerns explicitly separated:

  • Collision probability — Provided by CelesTrak SOCRATES Plus, which computes conjunction data using professional STK/Conjunction Analysis Tools and tracking covariance. This project does not independently recompute the value.

  • Operational priority — A 0–100 score calculated by src/risk_scoring.py from three explicitly weighted factors. The calculation is deterministic and isolated from the LLM layer.

  • Explanation — Generated by src/analyst.py from the calculated score and observation history. Its output schema contains no field capable of overriding a probability or priority score, regardless of whether the explanation comes from an LLM or the rule-based fallback.

Example Output

HIGH · 74.5/100

ISS (ZARYA) vs COSMOS 2251 DEB

MetricValue
Collision probability (SOCRATES)6.1 × 10⁻⁵
Miss distance620 m
Time to closest approach7.5 h
TrendFirst observation — insufficient history

Recommend an active maneuver evaluation and re-screen against fresher tracking data. (Low confidence, rule-based fallback — no API key configured for this example.)

Why the System Is Deterministic

An earlier version of this project used the term agent because it incorporated an LLM call. The current architecture uses more precise terminology.

Research such as ReAct (Yao et al., 2022) and Toolformer (Schick et al., 2023) characterizes agentic behavior around a model selecting actions or tools dynamically in response to observations. This pipeline follows a predefined execution path:

fetch → score → detect trend → explain

Each stage executes in the same order and has a clearly defined responsibility.

This design is particularly appropriate for collision-risk prioritization. When structured inputs and a well-defined scoring function are available, deterministic computation provides several important properties:

  • reproducibility;
  • low execution cost;
  • predictable latency;
  • straightforward testing; and
  • auditability.

The LLM therefore serves only as an explanation layer rather than a decision-making component.

A more detailed discussion—including a scoring defect discovered by the project's test suite, in which a near-zero collision probability could incorrectly produce a MEDIUM classification—is available in docs/RESEARCH.md.

Quick Start

Clone the repository and install the dependencies:

git clone https://github.com/likhitha281/orbital-collision-risk-agent.git
cd orbital-collision-risk-agent
pip install -r requirements.txt

Run the triage pipeline:

python run_triage.py \
  --max-results 50 \
  --min-probability 1e-6 \
  --output triage_report.md

Optional LLM Explanations

To use LLM-generated explanations instead of the rule-based fallback:

export ANTHROPIC_API_KEY=sk-ant-...
python run_triage.py --output triage_report.md

Both implementations follow the same output contract. Neither explanation path can modify numerical risk values.

Run the Tests

python -m pytest tests/ -v

The test suite contains 41 tests, including a schema-level check verifying that the explanation layer has no numeric override field.

Integration Note

Before relying on the live SOCRATES integration in production, verify the CSV endpoint used by src/socrates_client.py.

The implementation assumes that SOCRATES Plus accepts a FORMAT=CSV parameter, following conventions used elsewhere by CelesTrak. The development environment used for this project could not directly verify that URL.

The CSV parsing logic itself follows CelesTrak's documented column format. See the module docstring for additional details.

Trend Detection

A single execution provides a snapshot of the current conjunction data. Repeated executions add temporal context.

The scheduled live-monitor.yml workflow persists observation history between runs, allowing the system to identify changes such as:

Collision probability increased 51× across the last three observations.

This is materially different from simply restating a single observation.

During development, trend detection was tested end-to-end using two simulated observations of the same object pair:

  • the first observation correctly reported insufficient historical data;
  • the second increased the fixture's collision probability;
  • the system detected a 50.8× escalation; and
  • operational priority changed from MEDIUM to HIGH.

The calculated escalation matched the underlying ratio rather than relying on generated interpretation.

Physics Baseline

run_baseline.py provides a secondary, educational implementation of orbital propagation and conjunction screening.

It includes:

  • SGP4 orbit propagation;
  • conjunction screening; and
  • the 2D collision-probability method described by Foster & Estes (1992).

This component is included to demonstrate the orbital mechanics underlying conjunction analysis. It is not used by the live operational pipeline.

Because TLE data does not include real tracking covariance, the baseline uses an assumed covariance. Its resulting collision-probability values should therefore be treated as illustrative rather than operational.

Established tools already provide full-catalog conjunction screening, including:

  • CelesTrak SOCRATES Plus; and
  • the open-source SIMPLETON screener.

For this reason, the live pipeline consumes SOCRATES conjunction data rather than attempting to replace established screening infrastructure.

Run the baseline with the included sample catalog:

python run_baseline.py \
  --input data/sample_catalog.tle \
  --output report.md

Or fetch live CelesTrak TLE data:

python run_baseline.py \
  --live \
  --live-group stations \
  --output report.md

See docs/RESEARCH.md for implementation details, assumptions, and the rationale for separating the physics baseline from the live pipeline.

Optional Chat Interface

The dashboard includes an optional chat interface for querying the current dataset in natural language, for example:

  • “What is the highest-priority event?”
  • “Are any conjunctions escalating?”

The chatbot is grounded exclusively in the dashboard's JSON snapshot and is instructed not to generate numerical values that are absent from the source data.

Because GitHub Pages provides static hosting, the LLM API key cannot safely be stored in client-side JavaScript. The project therefore includes chatbot/worker.js, a Cloudflare Worker that keeps the API key server-side.

See chatbot/README.md for deployment instructions and a discussion of the security boundaries, including what CORS does and does not protect.

Request handling—including CORS behavior, validation, rate limiting, and error handling—is tested independently through:

chatbot/test_worker.mjs

The test suite contains 11 checks and does not require a live deployment.

Deployment Options

The core pipeline remains unchanged across deployment environments. The available options differ only in how the pipeline is packaged, scheduled, and operated.

The default deployment uses GitHub Actions through:

.github/workflows/live-monitor.yml

For the current workload—one fetch and scoring pass every 12 hours with no inter-task dependencies—this provides a lightweight scheduling mechanism without additional infrastructure.

Alternative deployment configurations are included for environments with different operational requirements:

ApproachAppropriate Use Case
Docker (Dockerfile, docker-compose.yml)Running the application independently of GitHub-hosted infrastructure
Kubernetes (k8s/cronjob.yaml)Deploying alongside workloads in an existing Kubernetes cluster
Prefect (orchestration/)Coordinating multiple data sources, task dependencies, retries, or backfills

Project Structure

├── run_triage.py
│   └── Primary pipeline entry point
│
├── run_baseline.py
│   └── Secondary SGP4 physics baseline
│
├── src/
│   ├── socrates_client.py
│   │   └── CelesTrak SOCRATES Plus conjunction data
│   ├── observation_store.py
│   │   └── SQLite observation history
│   ├── risk_scoring.py
│   │   └── Deterministic priority scoring
│   ├── trends.py
│   │   └── Historical trend detection
│   ├── analyst.py
│   │   └── Explanation layer
│   ├── triage.py
│   │   └── Record filtering and prioritization
│   ├── tle_loader.py
│   ├── live_fetch.py
│   ├── conjunction.py
│   ├── probability_of_collision.py
│   ├── knowledge_base.py
│   ├── reasoning_agent.py
│   └── report.py
│
├── data/
│   └── sample_catalog.tle
│
├── examples/
│   └── Worked example outputs
│
├── tests/
│   └── 41 automated tests
│
├── docs/
│   ├── index.html
│   │   └── GitHub Pages dashboard and chat interface
│   ├── latest.json
│   │   └── Auto-updated dashboard data
│   └── RESEARCH.md
│       └── Research references, design rationale, and limitations
│
├── chatbot/
│   ├── worker.js
│   │   └── Cloudflare Worker backend
│   ├── test_worker.mjs
│   │   └── Worker tests
│   └── wrangler.toml
│
├── Dockerfile
├── docker-compose.yml
├── k8s/
├── orchestration/
│
└── .github/workflows/
    ├── ci.yml
    │   └── Continuous integration
    └── live-monitor.yml
        └── Scheduled fetch, scoring, and publishing

Known Limitations

  • SOCRATES CSV endpoint — The exact CSV endpoint parameter used by src/socrates_client.py could not be verified from the project's development environment. It should be validated before production use.

  • Physics-baseline knowledge base — The baseline uses six manually written reference notes rather than a comprehensive corpus of operational documentation.

  • External collision probabilities — The live pipeline trusts and attributes collision-probability values provided by CelesTrak. It does not independently validate those values.

  • Trend estimation — Trend detection compares the oldest and newest stored observations rather than fitting a time-series model. Early noisy observations may therefore influence initial classifications until additional history is available.

  • Baseline scalability — The educational physics baseline uses fixed-grid screening with O(n²) scaling. This limitation does not affect the live pipeline because that path consumes precomputed SOCRATES conjunction data.

Research and References

docs/RESEARCH.md contains the project's research background and detailed engineering rationale, including:

  • Foster & Estes (1992) on 2D collision probability;
  • Vallado et al. on SGP4;
  • Kessler & Cour-Palais (1978);
  • Yao et al. (2022) on ReAct;
  • Schick et al. (2023) on Toolformer;
  • CelesTrak SOCRATES Plus;
  • SIMPLETON; and
  • documented implementation assumptions and simplifications.

It also describes issues identified during development and how automated testing exposed and corrected them.

License

MIT — see LICENSE.