CodeQuasar/orbital-anomaly-openenv
π°οΈ Orbital Anomaly OpenEnv v3
You are the last line of defense for a β¬500M spacecraft. 400km above Earth. 36 decision windows before the batteries die. Ground station is out of view. You cannot ask for help.
    
A spacecraft digital-twin mission-control benchmark for training LLM agents on causal world modeling, long-horizon planning, and multi-agent coordination under partial observability and delayed fault cascades.
π― Theme Alignment
Scaler AI Labs bonus: Spacecraft mission operations is an enterprise workflow β physical KPIs (battery SOC, thermal margins), incident management (fault response), resource allocation (science vs survivability).
π Real-World Motivation
Real satellite operations engineers face exactly these problems daily:
- A stuck MPPT controller reduces solar charging β battery drain β heater shutdown in eclipse β avionics reset cascade
- Reaction wheel saturation causes attitude drift β poor solar alignment β thermal instability β comms degradation
- Ground station blackout windows prevent uplink during anomaly response
- Active science observation windows create genuine tradeoffs: disabling payload saves the spacecraft but wastes a rare imaging opportunity
Every fault mode, thermal cascade, and orbital constraint in this environment is grounded in real spacecraft engineering.
ποΈ Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MULTI-AGENT LAYER (Theme 1) β
β MissionCommanderAgent β oversight, delegation, rationale logging β
β ββ EPSSpecialistAgent (battery + solar) β
β ββ ThermalSpecialistAgent (thermal + payload) β
β ββ CommsSpecialistAgent (RF chain + comms) β
ββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β action
ββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β EXTENDED MISSION MODE β 36 STEPS (Theme 2) β
β Phase 0 (steps 1-12): EPS Crisis β solar misalignment + drain β
β Phase 1 (steps 13-24): Thermal Crisis β payload heat spike β
β Phase 2 (steps 25-36): Comms Crisis β RF chain degradation β
β [battery_soc + payload_temp CARRY OVER between phases] β
ββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β SPACECRAFT SIMULATOR v3 β
β EPS: power-balance physics (solar input, bus drain, SOC) β
β ADCS: cosine solar alignment, reaction wheel saturation β
β Thermal: 3-zone propagation (payload / avionics / battery) β
β Comms: transponder + antenna pointing chain β
β Orbital: eclipse cycles, GS windows, radiation, science windows β
β Faults: 13-fault latent causal graph (hidden, cascading) β
β Partial observability: 6 sensor dropout patterns β
ββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β metadata.fault_beliefs (every obs)
ββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β FAULT BELIEF STATE (Theme 3: World Model) β
β Heuristic posterior over 13 faults from observable symptoms. β
β Updated every step. Agent reasons about hidden fault state. β
β mppt_stuck(78%), radiator_stuck(60%), transponder_hot(52%)... β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββπ¬ Environment Specification
Observation Space (40+ fields)
V1 fields (grader backward-compatible):
V2 extended telemetry (fields marked * may carry sentinel values under dropout):
v3 metadata (in every observation):
Action Space
β οΈ Key rule: rotate_to_sun is useless in eclipse (sunlit=False). The model must learn this.
Reward Function
Dense multi-objective mission utility strictly in (0, 1):
reward = safe_map(
0.30 Γ eps_score # battery SOC + bus voltage
+ 0.22 Γ thermal_score # 3-zone temperatures within limits
+ 0.18 Γ adcs_score # attitude error + wheel saturation
+ 0.15 Γ comms_score # BER + packet loss
+ 0.15 Γ survivability # catastrophe multiplier
) Γ survivability
+ science_bonus(0.12) # payload ON during observation_window_active
# Survivability: Γ0.4 if SOC<10%, Γ0.7 if SOC<20%, Γ0.5 if avionics>80Β°C
# Mapping: reward = 0.001 + raw Γ 0.998 (strict open interval, grader-safe)Three independent reward components prevent single-objective reward hacking.
Partial Observability β Sensor Dropout Map
Six telemetry fields drop out deterministically (not randomly), so agents can learn the dropout pattern:
π Benchmark Tasks
π’ Easy β EPS Crisis
- State:
battery_soc=38%,attitude_error=42Β°, sunlit, 1 fault:mppt_stuck - Challenge: Restore solar alignment, recover battery. Single fault, no eclipse.
- Baseline: 0.57 | Trained LLM: ~0.70
π‘ Medium β Thermal Overload + Science Window
- State:
payload_temp=68Β°C,radiator_efficiency=0.55,observation_window_active=True - Faults:
radiator_valve_stuck+amplifier_degradation - Challenge: Thermal tradeoff against +0.12 science bonus. Two interacting faults.
- Baseline: 0.55 | Trained LLM: ~0.65
π΄ Hard β Cascading Multi-System Failure
- State:
battery_soc=22%, eclipse, GS blackout, radiation zone,star_tracker=False, 7 simultaneous faults - Faults:
reaction_wheel_saturation,gyro_drift,star_tracker_dropout,heat_pipe_failure,heater_relay_latch,transponder_overheating,mppt_stuck - Challenge: Belief-state planning, 6 dropout fields, eclipse dynamics, no ground contact.
- Baseline: 0.07β0.13
The dramatic easyβhard gap (0.57 vs 0.07) shows the environment meaningfully scales difficulty.
π Training Results
Method: TRL GRPOTrainer + Unsloth 4-bit LoRA on Qwen2.5-1.5B-Instruct
What the Agent Learned
- Eclipse detection: Untrained model does
rotate_to_sunin eclipse (useless β no sun). Trained model usesswitch_power_businstead. Requires trackingsunlit=Falseand understanding the causal chain: no sun β solar useless β use battery reserve.
- Thermal cascade prevention: Untrained model waits until
thermal_temp > 80Β°C. Trained model disables payload at 65Β°C, preventing cascade 3-4 steps later. This is temporal credit assignment β the model learned delayed consequences.
- Science window tradeoff: Trained model holds payload ON during
observation_window_activeto capture +0.12 bonus, until temperature reaches a risk threshold. This is a genuine multi-objective policy.
π Training Visualizations
All plots are produced automatically when running the Colab notebook. Each visualization cell is self-contained and auto-downloads the PNG.
π Fault Belief State β World Modeling in Action
Step 0 β Hard task (eclipse, 7 faults active, none directly observable)
mppt_stuck ββββββββββββββββββββ 78% β EPS fault inferred from low solar
radiator_valve_stuck ββββββββββββββββββββ 62% β Thermal fault inferred from high temp
transponder_overheating ββββββββββββββββββββ 53% β Comms fault inferred from low signal
battery_aging ββββββββββββββββββββ 43%
heat_pipe_failure ββββββββββββββββββββ 38%
Step 1 β after switch_power_bus
mppt_stuck ββββββββββββββββββββ 60% β belief updated as SOC rises
...Judges watch the agent build its world model in real time. Available via obs.metadata["fault_beliefs"] every step. The dominant_subsystem key tells you which fault group is dominating, routing the MissionCommanderAgent to the right specialist automatically.
π Extended Mission Mode (Theme 2: Long-Horizon)
Phase 0: EPS (1-20) Phase 1: Thermal (21-40) Phase 2: Comms (41-60) Phase 3: Cascade (61-80)
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β Steps 1-12 ββββββββΆβ Steps 13-24 ββββββββΆβ Steps 25-36 β
β SOC: 22-38% β β Temp: 79Β°C+ β β BER: 0.18+ β
β Solar: degraded β β Radiator fault β β Antenna stall β
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
ββββββββββββ battery_soc + payload_temp + wheel_sat CARRY OVER ββββββPoor battery management in Phase 0 β lower SOC entering Phase 1 β thermal mitigation harder. The optimal policy cannot be computed phase-by-phase in isolation.
π€ Multi-Agent Architecture
from inference import mission_commander_decide, compute_fault_beliefs
obs = env.reset(task_id="hard").observation
# World model: 13-fault belief state
beliefs = compute_fault_beliefs(obs)
# β {"mppt_stuck": 0.78, "radiator_valve_stuck": 0.60, ...}
# Commander delegates to highest-confidence specialist
action, rationale, recs = mission_commander_decide(obs)
# β ("switch_power_bus",
# "[EPS_Specialist|97%] CRITICAL: battery at floor β reserve bus",
# {"EPS_Specialist": (...), "Thermal_Specialist": (...), "Comms_Specialist": (...)})Every action includes a rationale string logged to stdout. Researchers and judges can inspect agent reasoning in real time.
π Quickstart
Python Client
from client import OrbitalAnomalyOpenenvEnv
from models import OrbitalAnomalyOpenenvAction
with OrbitalAnomalyOpenenvEnv(
base_url="https://codequasar-orbital-anomaly-openenv.hf.space"
).sync() as env:
result = env.reset(task_id="hard")
obs = result.observation
print(f"Phase: {obs.metadata['phase']} | SOC: {obs.battery_soc:.1f}%")
print(f"Fault beliefs: {obs.metadata['fault_beliefs']}")
for step in range(36):
action = OrbitalAnomalyOpenenvAction(action_type="rotate_to_sun")
result = env.step(action)
print(f"Step {step+1}: reward={result.reward:.4f}")
if result.done:
breakHTTP API
# Reset
curl -X POST https://codequasar-orbital-anomaly-openenv.hf.space/reset \
-H "Content-Type: application/json" -d '{"task_id": "hard"}'
# Step
curl -X POST https://codequasar-orbital-anomaly-openenv.hf.space/step \
-H "Content-Type: application/json" -d '{"action_type": "rotate_to_sun"}'
# State
curl https://codequasar-orbital-anomaly-openenv.hf.space/stateHeuristic Baseline
python inference.py # multi-agent heuristic
HF_TOKEN=hf_... python inference.py # LLM via HF inference APIπ» Local Setup
git clone https://github.com/umed-indulkar/orbital-anomaly-openenv.git
cd orbital-anomaly-openenv
uv sync
openenv validate
uv run server # β http://localhost:8000π³ Docker
docker build -t orbital-anomaly-openenv .
docker run -p 8000:8000 orbital-anomaly-openenvπ§ͺ Tests
python test_reward.pyAll 8 tests must pass:
test_tasks_by_nameβ all 3 tasks accessible by name with valid rewardstest_physics_couplingβ actions affect correct subsystemstest_hard_fault_cascadeβ eclipse drains battery without interventiontest_science_window_rewardβ observation window adds science bonustest_cyclingβ sequential resets cycle through all 3 taskstest_no_boundary_rewardsβ all rewards strictly in (0, 1)test_partial_observabilityβ sensor dropout on hard tasktest_counter_independenceβ explicit task_id always wins
π Repository Structure
orbital-anomaly-openenv/
βββ server/
β βββ app.py # FastAPI + OpenEnv server
β βββ orbital_anomaly_openenv_environment.py # v3 spacecraft simulator
βββ models.py # Pydantic typed models
βββ client.py # Typed Python client
βββ inference.py # Multi-agent baseline + LLM policy
βββ test_reward.py # Complete V2 test suite
βββ Orbital_Anomaly_openenv.ipynb # GRPO training notebook
βββ blog.md # Plain-English explainer + images
βββ images/ # All blog/training visualizations
β βββ task_snapshot.png
β βββ baseline_distributions.png
β βββ training_analysis.png
β βββ action_policy_heatmap.png
β βββ fault_belief_evolution.png
β βββ telemetry_timeline_36step.png
β βββ final_dashboard.png
βββ openenv.yaml # OpenEnv manifest
βββ pyproject.toml # Dependencies (uv)
βββ Dockerfile # HF Spaces container
βββ README.mdπ API Reference
β OpenEnv Compliance
π§ Why This Is Hard for LLMs
- Causal fault inference: 13 faults are never directly observable. The agent must infer
mppt_stuckfrom the symptom pattern:solar_array_currentlower than expected givensun_vector_alignmentANDpanel_healthnot degraded. This requires causal world modeling.
- Temporal credit assignment: Action at step 3 (disable payload) affects thermal at step 5, which affects comms at step 8. Short-sighted policies fail consistently.
- Partial observability: 6 sensor fields drop out deterministically. Agent must reason about what it cannot see.
- Eclipse-conditional actions:
rotate_to_sunis useful in sunlight, useless in eclipse. Pre-trained models without environment experience fail this systematically.
- Multi-objective tradeoff: Science bonus (+0.12) vs thermal safety β no simple threshold resolves this without knowing current temperature trajectory and fault state.
- Inter-phase state persistence: In the 36-step extended mode, decisions in Phase 0 constrain what's possible in Phase 1 and Phase 2. Greedy per-phase optimization fails.
π Blog Post
A complete beginner-friendly walkthrough of how this was built, what it does, and what the AI actually learned is in [blog.md](./blog.md).
π Links
π Citation
@misc{orbital-anomaly-openenv-2026,
title = {Orbital Anomaly OpenEnv: A Spacecraft Digital-Twin Benchmark
for LLM World Modeling and Long-Horizon Planning},
author = {Indulkar, Umed},
year = {2026},
url = {https://huggingface.co/spaces/codequasar/orbital-anomaly-openenv}
}