Interactive threat-pathway simulator for biosecurity. Model bioweapon acquisition scenarios as directed acyclic graphs (DAGs), run Monte Carlo simulations to find adversary pathways, and identify where interventions matter most.
Built for the AIxBio Hackathon (Apr 24-26 2026, Apart Research).
cd backend
pip install -r requirements.txt
cp ../.env.example .env # fill in your API keysRequired env vars:
ANTHROPIC_API_KEY— Anthropic API key (required for LLM features)UPSTASH_REDIS_REST_URL— Upstash Redis URL (optional; falls back to in-memory storage)UPSTASH_REDIS_REST_TOKEN— Upstash Redis token (optional)
uvicorn main:app --reload --port 8000The API starts at http://localhost:8000. A pre-built seed scenario ("Non-state actor acquires engineered pathogen") loads automatically.
cd frontend
npm install
npm run devOpens at http://localhost:3000.
- Load the seed scenario from the left sidebar — it models a non-state actor's pathway to engineered pathogen deployment.
- Run Simulation (right panel) — set run count and adversary capability, click Run. For ≤20 runs, Claude adjudicates each node crossing via the game-master prompt.
- Read the results:
- Success rate — % of simulation runs where the adversary succeeded
- Gap nodes (red) — control points with <20% detection rate
- Hinge points (amber) — nodes where toggling the control most changes outcomes
- Outcome distribution — bar chart of how runs ended
- Toggle interventions — flip the switch on any node to disable/enable its control. Re-run simulation to see the counterfactual.
- Add AI nodes — select a node, click "Add AI Child Nodes" to have Claude suggest next decision points.
- Seed from description — describe any threat scenario in plain language; Claude generates a full DAG.
backend/
├── main.py FastAPI app + seed scenario data
├── models.py Pydantic v2 schemas
├── simulator.py Monte Carlo engine + LLM game-master calls
├── storage.py Upstash Redis wrapper with in-memory fallback
├── prompts.py Claude prompt templates
└── requirements.txt
frontend/
├── App.jsx Single React component (ReactFlow + Recharts + dagre)
├── main.jsx Vite entry point
├── index.html HTML shell
└── package.json
- Model: simulator uses
claude-sonnet-4-5-20250514. UpdateMODELinbackend/simulator.pyif needed. - LLM cost: The game-master prompt uses max_tokens=100. For >20 simulation runs, probabilistic simulation is used instead to keep costs low.
- No database required: without Upstash credentials, all data lives in process memory (resets on restart).