Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: CI

on:
push:
branches: [main]
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
name: lint · tests · selftest (py${{ matrix.python }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: ["3.10", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt
- run: python -m pip install -r requirements-dev.txt
- name: ruff
run: python -m ruff check --select E,F,W --line-length 130 astraeus isaac tests scripts
- name: compile all entry points (incl. Isaac scripts that need the Isaac runtime to execute)
run: python -m compileall -q astraeus isaac tests legacy scripts
- name: pytest
run: python -m pytest tests -q
- name: selftest (19 physical / statistical invariants)
run: python -m astraeus selftest

server:
name: server smoke test
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- run: python -m pip install -r requirements.txt
- name: boot uvicorn and hit the API
run: |
python -m uvicorn astraeus.app:app --port 8000 --log-level warning &
for i in $(seq 1 30); do curl -sf localhost:8000/api/health && break; sleep 1; done
curl -sf localhost:8000/api/health
curl -sf localhost:8000/api/priors | head -c 300; echo
curl -sf -X POST localhost:8000/api/simulate -H 'content-type: application/json' \
-d '{"x":{"k_soil":2,"theta_r":0.724,"r_terrain":1,"rho_rock":2,"slope_deg":4,"sun_e":1.5,"sun_psi":200,"tau_dust":0.05},"seed":0}' \
| head -c 300; echo
curl -sf -o /tmp/frame.png "localhost:8000/api/whatif/frame.png?k_soil=2&theta_r=0.724&r_terrain=1&rho_rock=2&slope_deg=4&sun_e=1.5&sun_psi=200&tau_dust=0.05&w=320&h=180&q=2"
python -c "from PIL import Image; im=Image.open('/tmp/frame.png'); assert im.size==(320,180), im.size; print('frame', im.size)"
27 changes: 27 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cff-version: 1.2.0
message: "If you use Astraeus in academic work, please cite it as below."
title: "Astraeus: adversarial stress testing of off-world rover autonomy under unknown disturbance priors"
type: software
version: 2.0.0
date-released: 2026-09-12
license: MIT
repository-code: "https://github.com/vineigenphase/Non-Trivial---Astraeus"
authors:
- family-names: Vinujan
given-names: S.
email: svinujan10@gmail.com
keywords:
- adaptive stress testing
- importance sampling
- distribution shift
- lunar rover
- terramechanics
- autonomy validation
- cross-entropy method
abstract: >-
Astraeus simulates thousands of autonomous rover traverses under an eight-dimensional
disturbance vector (soil, terrain, rocks, slope, illumination, dust), re-weights one
defensive-mixture Monte-Carlo campaign under six competing environmental priors with
explicit effective-sample-size and support-coverage gates, searches adversarially for
the most plausible failures with the cross-entropy method, and renders every episode
in a deterministic software renderer and a live WebGL world model.
38 changes: 38 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Contributing

Astraeus is a research framework; correctness and honesty about what the model does and
does not capture matter more than features. Please keep that spirit.

## Setup

```bash
git clone https://github.com/vineigenphase/Non-Trivial---Astraeus.git
cd Non-Trivial---Astraeus
python -m pip install -r requirements-dev.txt
make check # ruff + pytest + 19 selftest invariants
```

## Ground rules

- **Determinism is a contract.** Every episode is a pure function of `(x, seed)`. If a change
alters trajectories, say so in the PR and regenerate `docs/VALIDATION.md` numbers with
`make campaign`.
- **Do not hide support mismatch.** Priors whose mass lies outside the simulated support must
read `n/a`, never a clean `0.000`.
- **Keep provenance.** Proposal (`mc`), adversarial (`cem`) and external simulator rows are
never mixed into the same importance-weighted estimate.
- **Model changes need a citation or a measurement.** New terramechanics, photometry or
perception terms should reference a source in `docs/RESEARCH.md` or be labelled as a
heuristic in `docs/PARAMETERS.md`.
- **Isaac Sim / ROS 2 code you cannot run here must be marked unverified** (see
`isaac/configs/ros2_topics.yaml`).

## Before opening a PR

```bash
make check # must be green
python scripts/make_renders.py runs/val.npz # only if the renderer or physics changed
```

CI runs ruff, `compileall`, pytest, the selftest, and boots the FastAPI server to hit the API on
Python 3.10 and 3.12.
Loading
Loading