Commit Β·
6e28a1b
1
Parent(s): 50e16d4
Update all dashboard tabs and README with actual test run numbers
Browse files- README.md +41 -62
- server/app.py +20 -13
README.md
CHANGED
|
@@ -72,15 +72,17 @@ export MODEL_NAME="meta-llama/Llama-3.1-8B-Instruct"
|
|
| 72 |
export HF_TOKEN="hf_your_token_here"
|
| 73 |
export ENV_BASE_URL="https://therubberduckdebuggers-cascade-containment.hf.space"
|
| 74 |
|
|
|
|
| 75 |
python inference.py
|
|
|
|
|
|
|
|
|
|
| 76 |
```
|
| 77 |
|
| 78 |
---
|
| 79 |
|
| 80 |
## Action Space
|
| 81 |
|
| 82 |
-
One decision per step, deliberately minimal to maximise strategic depth:
|
| 83 |
-
|
| 84 |
| Field | Type | Values |
|
| 85 |
| --- | --- | --- |
|
| 86 |
| `action_type` | `string` | `"test"` Β· `"restrict"` Β· `"allocate"` |
|
|
@@ -92,7 +94,7 @@ One decision per step, deliberately minimal to maximise strategic depth:
|
|
| 92 |
| **restrict** | Free | Imposes movement restrictions; reduces spread rate; penalised if infection < 0.20 |
|
| 93 |
| **allocate** | 1 resource | Deploys medical resources; reduces existing infection by 5% and slows future spread |
|
| 94 |
|
| 95 |
-
Movement restrictions lift automatically once a district's infection drops below the safe threshold
|
| 96 |
|
| 97 |
---
|
| 98 |
|
|
@@ -111,8 +113,6 @@ CityObservation:
|
|
| 111 |
message: str | None
|
| 112 |
```
|
| 113 |
|
| 114 |
-
Each `DistrictObservation` exposes:
|
| 115 |
-
|
| 116 |
| Field | Description | Observability |
|
| 117 |
| --- | --- | --- |
|
| 118 |
| `reported_infection_rate` | Active infection fraction | Real-time (easy/medium); **3-day lagged** (hard) |
|
|
@@ -122,14 +122,10 @@ Each `DistrictObservation` exposes:
|
|
| 122 |
| `restriction_active` | Whether movement restrictions are in place | Always real-time |
|
| 123 |
| `tested_recently` | Tested within last 2 days | Always real-time |
|
| 124 |
|
| 125 |
-
**The agent never sees:** `true_infection_rate`, `true_spread_rate`, or any ground truth used by the grader.
|
| 126 |
-
|
| 127 |
---
|
| 128 |
|
| 129 |
## Epidemiological Model
|
| 130 |
|
| 131 |
-
The simulation uses a realistic discrete-time SIR-inspired model:
|
| 132 |
-
|
| 133 |
```text
|
| 134 |
new_infection = current + (spread_rate β natural_recovery β intervention) + geographic_spillover
|
| 135 |
```
|
|
@@ -149,104 +145,85 @@ new_infection = current + (spread_rate β natural_recovery β intervention) +
|
|
| 149 |
|
| 150 |
| Task | Districts | Steps | Resources | Data Lag | Challenge |
|
| 151 |
| --- | --- | --- | --- | --- | --- |
|
| 152 |
-
| **easy** | 2 | 10 | 10 | None | Single outbreak
|
| 153 |
| **medium** | 4 | 15 | 8 | None | Two simultaneous outbreaks; forced triage between competing threats |
|
| 154 |
| **hard** | 6 | 15 | 7 | **3 days** | Six growing outbreaks; invisible acceleration; scarce resources |
|
| 155 |
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
**Easy** establishes the core mechanic: D0 starts at 0.50 infection, D1 is clean. The agent must sustain focused allocation on D0 before D1 grows through spillover. A speed bonus fires if the agent acts decisively early.
|
| 159 |
|
| 160 |
-
**Medium**
|
| 161 |
|
| 162 |
-
**Hard**
|
| 163 |
|
| 164 |
---
|
| 165 |
|
| 166 |
## Reward Function
|
| 167 |
|
| 168 |
-
Five independent dense reward terms fire every step, providing rich learning signal throughout each episode:
|
| 169 |
-
|
| 170 |
| Term | Value | Fires When |
|
| 171 |
| --- | --- | --- |
|
| 172 |
-
| Infection penalty | `β0.50
|
| 173 |
-
| Hospital breach | `β1.00`
|
| 174 |
| Early containment | `+0.50 Γ (1 β step/max_steps)` | District infection < 0.20 |
|
| 175 |
| Correct prioritisation | `+0.30` | Allocate to highest-infected district |
|
| 176 |
| Unnecessary restriction | `β0.20` | Restrict district below 0.20 |
|
| 177 |
|
| 178 |
-
Key design choices:
|
| 179 |
-
|
| 180 |
-
- The **early containment bonus decays over time** β containing an outbreak on day 3 is worth more than on day 8. This teaches proactive behaviour rather than reactive scrambling.
|
| 181 |
-
- The **infection penalty scales with population density** β dense districts contribute more to the penalty, reflecting realistic triage priorities.
|
| 182 |
-
- The **hospital breach penalty** fires at 10% capacity, not 0% β reflecting real operational collapse thresholds where triage and diversion begin.
|
| 183 |
-
- **Restrictions lift automatically** when infection drops below the safe threshold, giving the agent a natural feedback loop on intervention effectiveness.
|
| 184 |
|
| 185 |
---
|
| 186 |
|
| 187 |
## Grader
|
| 188 |
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
### Score Components
|
| 192 |
|
| 193 |
| Component | Weight | Measures |
|
| 194 |
| --- | --- | --- |
|
| 195 |
| **Hospital score** | 45% | Average capacity preserved; Γ0.6 multiplier if any district collapsed |
|
| 196 |
-
| **Containment score** | 30% | Fraction of district-days below infection threshold (
|
| 197 |
-
| **Efficiency score** | 15% | Fraction of resource actions targeting
|
| 198 |
-
| **Speed score** | 10% | `1 β (steps / max_steps)` if episode ends
|
| 199 |
-
|
| 200 |
-
Weight rationale: In real epidemic response, preserving healthcare system function (45%) is the primary operational constraint β a functional hospital system is the prerequisite for everything else. WHO and CDC outbreak protocols define success primarily by healthcare capacity preservation, with infection containment as the secondary signal. Efficiency (15%) rewards triage intelligence. Speed (10%) rewards proactive early intervention.
|
| 201 |
|
| 202 |
-
|
| 203 |
|
| 204 |
---
|
| 205 |
|
| 206 |
## Baseline Agent β GRPO-Style Episodic Memory
|
| 207 |
|
| 208 |
-
|
| 209 |
|
| 210 |
### Learning Loop
|
| 211 |
|
| 212 |
```text
|
| 213 |
Rollout 1: Base prompt, no prior knowledge
|
| 214 |
compute advantage = R1 - mean([])
|
| 215 |
-
store
|
| 216 |
|
| 217 |
Rollout 2: Memory-augmented prompt
|
| 218 |
-
retrieve top-5 similar past decisions by L1 distance
|
| 219 |
inject as concrete examples into prompt
|
| 220 |
compute advantage = R2 - mean([R1])
|
| 221 |
-
reinforce if
|
| 222 |
|
| 223 |
-
... repeat for N rollouts
|
| 224 |
Report best grader score across all rollouts
|
| 225 |
```
|
| 226 |
|
| 227 |
-
###
|
| 228 |
|
| 229 |
-
|
| 230 |
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
|
| 234 |
-
|
|
| 235 |
-
|
|
| 236 |
-
|
|
| 237 |
-
| Medium | Dumb greedy | 0.18 | 0.21 | 0.40 | ~0.23 |
|
| 238 |
-
| Medium | LLM + GRPO memory | 0.44β0.73 | 0.97β1.00 | 0.87β1.00 | **0.70β0.85** |
|
| 239 |
-
| Hard | Dumb greedy | 0.12 | 0.18 | 0.25 | ~0.21 |
|
| 240 |
-
| Hard | LLM + GRPO memory | 0.28β0.51 | 0.86β0.97 | 0.47β0.73 | **0.58β0.65** |
|
| 241 |
|
| 242 |
-
The
|
| 243 |
|
| 244 |
---
|
| 245 |
|
| 246 |
## Generalisation
|
| 247 |
|
| 248 |
-
This environment is not epidemic-specific. The underlying mechanics apply directly to:
|
| 249 |
-
|
| 250 |
| Domain | Spreading cascade | Delayed data | Resource scarcity |
|
| 251 |
| --- | --- | --- | --- |
|
| 252 |
| π¦ **Epidemic containment** | Infection spreads between districts | Lagged case counts | Medical resources |
|
|
@@ -255,8 +232,6 @@ This environment is not epidemic-specific. The underlying mechanics apply direct
|
|
| 255 |
| π’ **Misinformation containment** | Narrative spread through networks | Viral detection lag | Correction budget |
|
| 256 |
| π€ **Poverty intervention** | Deprivation cascades through communities | Census data lag | Aid allocation |
|
| 257 |
|
| 258 |
-
The same trained policy generalises across domains with minimal prompt adaptation β this is the intended use case for the OpenEnv ecosystem.
|
| 259 |
-
|
| 260 |
---
|
| 261 |
|
| 262 |
## Project Structure
|
|
@@ -269,26 +244,29 @@ cascade-containment/
|
|
| 269 |
βββ openenv.yaml # Environment manifest for OpenEnv registry
|
| 270 |
β
|
| 271 |
βββ server/
|
| 272 |
-
β βββ app.py # FastAPI server + judge dashboard + /grade /info /demo endpoints
|
| 273 |
β βββ environment.py # Core RL loop (reset/step/state OpenEnv interface)
|
| 274 |
β βββ grader.py # Deterministic trajectory scorer β no LLM calls
|
| 275 |
β βββ constants.py # Single source of truth for all numeric configuration
|
| 276 |
β βββ utils.py # Spread computation, observation builder, helper functions
|
| 277 |
β βββ Dockerfile # Container definition
|
| 278 |
β βββ tasks/
|
| 279 |
-
β βββ task_easy.py # 2 districts, 10 steps, real-time data
|
| 280 |
β βββ task_medium.py # 4 districts, 15 steps, forced triage
|
| 281 |
β βββ task_hard.py # 6 districts, 15 steps, 3-day data lag
|
| 282 |
β
|
| 283 |
βββ baseline/
|
| 284 |
β βββ policy.py # LLM policy with chain-of-thought prompting
|
| 285 |
-
β βββ evaluator.py # GRPO episodic memory loop
|
| 286 |
β βββ run.py # CLI entry point
|
| 287 |
β
|
|
|
|
|
|
|
|
|
|
| 288 |
βββ core/
|
| 289 |
-
βββ trajectory.py # EpisodicMemory β L1 similarity retrieval
|
| 290 |
βββ reward.py # Score normalisation utilities
|
| 291 |
-
βββ policy_update.py # Advantage computation, memory gating
|
| 292 |
```
|
| 293 |
|
| 294 |
---
|
|
@@ -307,11 +285,12 @@ cascade-containment/
|
|
| 307 |
| HF Space deploys | β
|
|
| 308 |
| `inference.py` at root | β
|
|
| 309 |
| `[START][STEP][END]` structured logs | β
|
|
| 310 |
-
| Runtime < 20 minutes | β
~
|
| 311 |
| `API_BASE_URL`, `MODEL_NAME`, `HF_TOKEN` env vars | β
|
|
| 312 |
| OpenAI client for all LLM calls | β
|
|
| 313 |
| Grader scores in `[0.0, 1.0]` | β
|
|
| 314 |
| 3+ tasks with difficulty progression | β
|
|
|
|
|
| 315 |
|
| 316 |
---
|
| 317 |
|
|
|
|
| 72 |
export HF_TOKEN="hf_your_token_here"
|
| 73 |
export ENV_BASE_URL="https://therubberduckdebuggers-cascade-containment.hf.space"
|
| 74 |
|
| 75 |
+
# Full LLM+GRPO evaluation (~20 minutes, emits [START][STEP][END] logs)
|
| 76 |
python inference.py
|
| 77 |
+
|
| 78 |
+
# Local validation + greedy benchmark
|
| 79 |
+
python scripts/test_local.py
|
| 80 |
```
|
| 81 |
|
| 82 |
---
|
| 83 |
|
| 84 |
## Action Space
|
| 85 |
|
|
|
|
|
|
|
| 86 |
| Field | Type | Values |
|
| 87 |
| --- | --- | --- |
|
| 88 |
| `action_type` | `string` | `"test"` Β· `"restrict"` Β· `"allocate"` |
|
|
|
|
| 94 |
| **restrict** | Free | Imposes movement restrictions; reduces spread rate; penalised if infection < 0.20 |
|
| 95 |
| **allocate** | 1 resource | Deploys medical resources; reduces existing infection by 5% and slows future spread |
|
| 96 |
|
| 97 |
+
Movement restrictions lift automatically once a district's infection drops below the safe threshold.
|
| 98 |
|
| 99 |
---
|
| 100 |
|
|
|
|
| 113 |
message: str | None
|
| 114 |
```
|
| 115 |
|
|
|
|
|
|
|
| 116 |
| Field | Description | Observability |
|
| 117 |
| --- | --- | --- |
|
| 118 |
| `reported_infection_rate` | Active infection fraction | Real-time (easy/medium); **3-day lagged** (hard) |
|
|
|
|
| 122 |
| `restriction_active` | Whether movement restrictions are in place | Always real-time |
|
| 123 |
| `tested_recently` | Tested within last 2 days | Always real-time |
|
| 124 |
|
|
|
|
|
|
|
| 125 |
---
|
| 126 |
|
| 127 |
## Epidemiological Model
|
| 128 |
|
|
|
|
|
|
|
| 129 |
```text
|
| 130 |
new_infection = current + (spread_rate β natural_recovery β intervention) + geographic_spillover
|
| 131 |
```
|
|
|
|
| 145 |
|
| 146 |
| Task | Districts | Steps | Resources | Data Lag | Challenge |
|
| 147 |
| --- | --- | --- | --- | --- | --- |
|
| 148 |
+
| **easy** | 2 | 10 | 10 | None | Single outbreak; D1 starts infected, D0 is clean |
|
| 149 |
| **medium** | 4 | 15 | 8 | None | Two simultaneous outbreaks; forced triage between competing threats |
|
| 150 |
| **hard** | 6 | 15 | 7 | **3 days** | Six growing outbreaks; invisible acceleration; scarce resources |
|
| 151 |
|
| 152 |
+
**Easy** β D1 starts at 0.50 infection, D0 is clean. The agent must observe and target the correct district. A fixed-target agent ignoring observations scores ~43% and breaches hospitals 60% of the time.
|
|
|
|
|
|
|
| 153 |
|
| 154 |
+
**Medium** β D0 and D2 start in the danger zone; D1 and D3 grow into crisis within 4β6 steps. With 8 resources across 4 districts over 15 steps, genuine triage is required.
|
| 155 |
|
| 156 |
+
**Hard** β 3-day information lag means the agent sees infection rates from 3 days ago. The `growth_rate_hint` provides a noisy signal to estimate current state. Structural uncertainty β not testable around.
|
| 157 |
|
| 158 |
---
|
| 159 |
|
| 160 |
## Reward Function
|
| 161 |
|
|
|
|
|
|
|
| 162 |
| Term | Value | Fires When |
|
| 163 |
| --- | --- | --- |
|
| 164 |
+
| Infection penalty | `β0.50 Γ density` | District infection > 0.40 |
|
| 165 |
+
| Hospital breach | `β1.00` | Hospital capacity β€ 10% |
|
| 166 |
| Early containment | `+0.50 Γ (1 β step/max_steps)` | District infection < 0.20 |
|
| 167 |
| Correct prioritisation | `+0.30` | Allocate to highest-infected district |
|
| 168 |
| Unnecessary restriction | `β0.20` | Restrict district below 0.20 |
|
| 169 |
|
| 170 |
+
Key design choices: early containment bonus decays over time (proactive action worth more); infection penalty scales with population density (realistic triage); hospital breach fires at 10% not 0% (real ICU thresholds); restrictions auto-lift when infection drops below safe threshold.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
---
|
| 173 |
|
| 174 |
## Grader
|
| 175 |
|
| 176 |
+
Fully deterministic β no randomness, no LLM calls. Identical trajectories always produce identical scores in `[0.0, 1.0]`.
|
|
|
|
|
|
|
| 177 |
|
| 178 |
| Component | Weight | Measures |
|
| 179 |
| --- | --- | --- |
|
| 180 |
| **Hospital score** | 45% | Average capacity preserved; Γ0.6 multiplier if any district collapsed |
|
| 181 |
+
| **Containment score** | 30% | Fraction of district-days below infection threshold (first 2 steps excluded) |
|
| 182 |
+
| **Efficiency score** | 15% | Fraction of resource actions targeting highest-infected district (uses pre-action state) |
|
| 183 |
+
| **Speed score** | 10% | `1 β (steps / max_steps)` if episode ends early; else 0 |
|
|
|
|
|
|
|
| 184 |
|
| 185 |
+
Hospital is weighted highest because system capacity preservation is the primary operational constraint in real outbreak response β a functioning healthcare system is the prerequisite for everything else.
|
| 186 |
|
| 187 |
---
|
| 188 |
|
| 189 |
## Baseline Agent β GRPO-Style Episodic Memory
|
| 190 |
|
| 191 |
+
No weight updates, no gradient computation. The prompt is the policy; memory updates are the policy improvement.
|
| 192 |
|
| 193 |
### Learning Loop
|
| 194 |
|
| 195 |
```text
|
| 196 |
Rollout 1: Base prompt, no prior knowledge
|
| 197 |
compute advantage = R1 - mean([])
|
| 198 |
+
store steps with reward > -0.3 into EpisodicMemory
|
| 199 |
|
| 200 |
Rollout 2: Memory-augmented prompt
|
| 201 |
+
retrieve top-5 similar past decisions by L1 distance on infection profiles
|
| 202 |
inject as concrete examples into prompt
|
| 203 |
compute advantage = R2 - mean([R1])
|
| 204 |
+
reinforce if advantage > -0.5
|
| 205 |
|
| 206 |
+
... repeat for N rollouts (easy=3, medium=4, hard=4)
|
| 207 |
Report best grader score across all rollouts
|
| 208 |
```
|
| 209 |
|
| 210 |
+
### Benchmark Scores
|
| 211 |
|
| 212 |
+
Results from `baseline/run.py` (Llama 3.3 70B via Groq, runtime ~19.8 minutes):
|
| 213 |
|
| 214 |
+
| Task | Greedy (D0) | LLM+GRPO | Lift |
|
| 215 |
+
| --- | --- | --- | --- |
|
| 216 |
+
| Easy | 42.8% (breach 60%) | **90.8%** | +48pp |
|
| 217 |
+
| Medium | 42.7% (breach 80%) | **71.6%** | +29pp |
|
| 218 |
+
| Hard | 33.0% (breach 100%) | **66.1%** | +33pp |
|
| 219 |
+
| **Average** | **39.5%** | **76.2%** | **+37pp** |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
|
| 221 |
+
The greedy baseline (always allocates to D0) scores 33β43% with 60β100% hospital breach rates β no trivial exploit path. LLM+GRPO reaches 66β91% with zero breaches, demonstrating that genuine triage reasoning is required and rewarded.
|
| 222 |
|
| 223 |
---
|
| 224 |
|
| 225 |
## Generalisation
|
| 226 |
|
|
|
|
|
|
|
| 227 |
| Domain | Spreading cascade | Delayed data | Resource scarcity |
|
| 228 |
| --- | --- | --- | --- |
|
| 229 |
| π¦ **Epidemic containment** | Infection spreads between districts | Lagged case counts | Medical resources |
|
|
|
|
| 232 |
| π’ **Misinformation containment** | Narrative spread through networks | Viral detection lag | Correction budget |
|
| 233 |
| π€ **Poverty intervention** | Deprivation cascades through communities | Census data lag | Aid allocation |
|
| 234 |
|
|
|
|
|
|
|
| 235 |
---
|
| 236 |
|
| 237 |
## Project Structure
|
|
|
|
| 244 |
βββ openenv.yaml # Environment manifest for OpenEnv registry
|
| 245 |
β
|
| 246 |
βββ server/
|
| 247 |
+
β βββ app.py # FastAPI server + judge dashboard + /grade /info /demo /validate endpoints
|
| 248 |
β βββ environment.py # Core RL loop (reset/step/state OpenEnv interface)
|
| 249 |
β βββ grader.py # Deterministic trajectory scorer β no LLM calls
|
| 250 |
β βββ constants.py # Single source of truth for all numeric configuration
|
| 251 |
β βββ utils.py # Spread computation, observation builder, helper functions
|
| 252 |
β βββ Dockerfile # Container definition
|
| 253 |
β βββ tasks/
|
| 254 |
+
β βββ task_easy.py # 2 districts, 10 steps, real-time data (D1 seeded)
|
| 255 |
β βββ task_medium.py # 4 districts, 15 steps, forced triage
|
| 256 |
β βββ task_hard.py # 6 districts, 15 steps, 3-day data lag
|
| 257 |
β
|
| 258 |
βββ baseline/
|
| 259 |
β βββ policy.py # LLM policy with chain-of-thought prompting
|
| 260 |
+
β βββ evaluator.py # GRPO episodic memory loop (easy=3, medium=4, hard=4 rollouts)
|
| 261 |
β βββ run.py # CLI entry point
|
| 262 |
β
|
| 263 |
+
βββ scripts/
|
| 264 |
+
β βββ test_local.py # Phase 1 spec checks + greedy benchmark + variance analysis
|
| 265 |
+
β
|
| 266 |
βββ core/
|
| 267 |
+
βββ trajectory.py # EpisodicMemory β L1 similarity retrieval, phase-weighted
|
| 268 |
βββ reward.py # Score normalisation utilities
|
| 269 |
+
βββ policy_update.py # Advantage computation, memory gating (threshold -0.3)
|
| 270 |
```
|
| 271 |
|
| 272 |
---
|
|
|
|
| 285 |
| HF Space deploys | β
|
|
| 286 |
| `inference.py` at root | β
|
|
| 287 |
| `[START][STEP][END]` structured logs | β
|
|
| 288 |
+
| Runtime < 20 minutes | β
~19.8 minutes |
|
| 289 |
| `API_BASE_URL`, `MODEL_NAME`, `HF_TOKEN` env vars | β
|
|
| 290 |
| OpenAI client for all LLM calls | β
|
|
| 291 |
| Grader scores in `[0.0, 1.0]` | β
|
|
| 292 |
| 3+ tasks with difficulty progression | β
|
|
| 293 |
+
| Phase 1 automated validation | β
10/10 checks pass |
|
| 294 |
|
| 295 |
---
|
| 296 |
|
server/app.py
CHANGED
|
@@ -593,7 +593,7 @@ body{font-family:var(--mono);background:var(--bg);color:var(--text);min-height:1
|
|
| 593 |
<div class="brand-icon">π¦ </div>
|
| 594 |
<div>
|
| 595 |
<div class="brand-name">Cascade Containment</div>
|
| 596 |
-
<div class="brand-sub">OpenEnv Benchmark · Meta PyTorch Hackathon Γ SST 2026</div>
|
| 597 |
</div>
|
| 598 |
</div>
|
| 599 |
<div class="header-right">
|
|
@@ -636,8 +636,8 @@ body{font-family:var(--mono);background:var(--bg);color:var(--text);min-height:1
|
|
| 636 |
</div>
|
| 637 |
<div class="hero-stats">
|
| 638 |
<div class="hs-item"><div class="hs-val">3</div><div class="hs-label">Task levels</div></div>
|
| 639 |
-
<div class="hs-item"><div class="hs-val">
|
| 640 |
-
<div class="hs-item"><div class="hs-val">
|
| 641 |
</div>
|
| 642 |
</div>
|
| 643 |
|
|
@@ -742,16 +742,23 @@ body{font-family:var(--mono);background:var(--bg);color:var(--text);min-height:1
|
|
| 742 |
</div>
|
| 743 |
|
| 744 |
<div style="margin-top:1rem;" class="card">
|
| 745 |
-
<div class="card-title">
|
| 746 |
<table class="table">
|
| 747 |
-
<tr><th>Check</th><th>
|
| 748 |
-
<tr><td>
|
| 749 |
-
<tr><td>
|
| 750 |
-
<tr><td>
|
| 751 |
-
<tr><td>
|
| 752 |
-
<tr><td>
|
| 753 |
-
<tr><td>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 754 |
</table>
|
|
|
|
|
|
|
|
|
|
| 755 |
</div>
|
| 756 |
</div>
|
| 757 |
|
|
@@ -1014,7 +1021,7 @@ body{font-family:var(--mono);background:var(--bg);color:var(--text);min-height:1
|
|
| 1014 |
</tr>
|
| 1015 |
<tr>
|
| 1016 |
<td>Trivially containable (easy task too easy)</td>
|
| 1017 |
-
<td>
|
| 1018 |
<td><span class="badge badge-green">Addressed</span></td>
|
| 1019 |
</tr>
|
| 1020 |
<tr>
|
|
@@ -1147,7 +1154,7 @@ body{font-family:var(--mono);background:var(--bg);color:var(--text);min-height:1
|
|
| 1147 |
<div class="arch-card"><div class="arch-icon">π</div><div class="arch-name">grader.py</div><div class="arch-desc">Deterministic trajectory scorer. Reads hidden CityState. Four components weighted into final_score β [0.0, 1.0]. Zero LLM calls.</div></div>
|
| 1148 |
<div class="arch-card"><div class="arch-icon">π</div><div class="arch-name">utils.py</div><div class="arch-desc">SIR-inspired spread model with linear spillover (no wrap-around). Observation builder enforcing partial observability by task.</div></div>
|
| 1149 |
<div class="arch-card"><div class="arch-icon">π§ </div><div class="arch-name">core/trajectory.py</div><div class="arch-desc">EpisodicMemory. Stores (obs, action, reward) tuples. Retrieves top-k by L1 distance on infection profiles, phase-weighted.</div></div>
|
| 1150 |
-
<div class="arch-card"><div class="arch-icon">π―</div><div class="arch-name">baseline/evaluator.py</div><div class="arch-desc">GRPO-style loop. Advantage = Rα΅’ β mean(R). Memory
|
| 1151 |
</div>
|
| 1152 |
|
| 1153 |
<div class="card">
|
|
|
|
| 593 |
<div class="brand-icon">π¦ </div>
|
| 594 |
<div>
|
| 595 |
<div class="brand-name">Cascade Containment</div>
|
| 596 |
+
<div class="brand-sub">OpenEnv Benchmark · Meta PyTorch Hackathon Γ SST 2026 · LLM avg 76.2%</div>
|
| 597 |
</div>
|
| 598 |
</div>
|
| 599 |
<div class="header-right">
|
|
|
|
| 636 |
</div>
|
| 637 |
<div class="hero-stats">
|
| 638 |
<div class="hs-item"><div class="hs-val">3</div><div class="hs-label">Task levels</div></div>
|
| 639 |
+
<div class="hs-item"><div class="hs-val">76.2%</div><div class="hs-label">LLM+GRPO avg</div></div>
|
| 640 |
+
<div class="hs-item"><div class="hs-val">+37pp</div><div class="hs-label">vs greedy</div></div>
|
| 641 |
</div>
|
| 642 |
</div>
|
| 643 |
|
|
|
|
| 742 |
</div>
|
| 743 |
|
| 744 |
<div style="margin-top:1rem;" class="card">
|
| 745 |
+
<div class="card-title">Phase 1 Results β Last Run (2026-04-07)</div>
|
| 746 |
<table class="table">
|
| 747 |
+
<tr><th>Check</th><th>Result</th><th>Detail</th></tr>
|
| 748 |
+
<tr><td>Env instantiates</td><td><span class="badge badge-green">✓ Pass</span></td><td>EpidemicContainmentEnv()</td></tr>
|
| 749 |
+
<tr><td>Reset β Easy</td><td><span class="badge badge-green">✓ Pass</span></td><td>2 districts, 10 steps</td></tr>
|
| 750 |
+
<tr><td>Reset β Medium</td><td><span class="badge badge-green">✓ Pass</span></td><td>4 districts, 15 steps</td></tr>
|
| 751 |
+
<tr><td>Reset β Hard</td><td><span class="badge badge-green">✓ Pass</span></td><td>6 districts, 15 steps</td></tr>
|
| 752 |
+
<tr><td>Step works</td><td><span class="badge badge-green">✓ Pass</span></td><td>reward=-0.0599, done=False</td></tr>
|
| 753 |
+
<tr><td>State property</td><td><span class="badge badge-green">✓ Pass</span></td><td>episode_id present, step_count present</td></tr>
|
| 754 |
+
<tr><td>Grader valid range</td><td><span class="badge badge-green">✓ Pass</span></td><td>final_score=0.5573 in [0.0, 1.0]</td></tr>
|
| 755 |
+
<tr><td>Invalid action handled</td><td><span class="badge badge-green">✓ Pass</span></td><td>Gracefully defaulted to allocate</td></tr>
|
| 756 |
+
<tr><td>Difficulty progression</td><td><span class="badge badge-green">✓ Pass</span></td><td>easy=2d, medium=4d, hard=6d</td></tr>
|
| 757 |
+
<tr><td>Grader deterministic</td><td><span class="badge badge-green">✓ Pass</span></td><td>Scoring logic is pure β no internal randomness</td></tr>
|
| 758 |
</table>
|
| 759 |
+
<div style="margin-top:0.75rem;padding:0.6rem 1rem;background:var(--green-dim);border:1px solid rgba(61,214,140,0.2);border-radius:6px;font-size:0.7rem;color:var(--text);">
|
| 760 |
+
✓ <strong>10 / 10 checks passed.</strong> Click "Run Validation" above to re-run live against the deployed environment.
|
| 761 |
+
</div>
|
| 762 |
</div>
|
| 763 |
</div>
|
| 764 |
|
|
|
|
| 1021 |
</tr>
|
| 1022 |
<tr>
|
| 1023 |
<td>Trivially containable (easy task too easy)</td>
|
| 1024 |
+
<td>D0-only allocation scores 43% avg; 60β100% hospital breach rate β no trivial path to high scores</td>
|
| 1025 |
<td><span class="badge badge-green">Addressed</span></td>
|
| 1026 |
</tr>
|
| 1027 |
<tr>
|
|
|
|
| 1154 |
<div class="arch-card"><div class="arch-icon">π</div><div class="arch-name">grader.py</div><div class="arch-desc">Deterministic trajectory scorer. Reads hidden CityState. Four components weighted into final_score β [0.0, 1.0]. Zero LLM calls.</div></div>
|
| 1155 |
<div class="arch-card"><div class="arch-icon">π</div><div class="arch-name">utils.py</div><div class="arch-desc">SIR-inspired spread model with linear spillover (no wrap-around). Observation builder enforcing partial observability by task.</div></div>
|
| 1156 |
<div class="arch-card"><div class="arch-icon">π§ </div><div class="arch-name">core/trajectory.py</div><div class="arch-desc">EpisodicMemory. Stores (obs, action, reward) tuples. Retrieves top-k by L1 distance on infection profiles, phase-weighted.</div></div>
|
| 1157 |
+
<div class="arch-card"><div class="arch-icon">π―</div><div class="arch-name">baseline/evaluator.py</div><div class="arch-desc">GRPO-style loop. Per-task rollouts: easy=3, medium=4, hard=4. Advantage = Rα΅’ β mean(R). Memory threshold -0.3. Best score reported.</div></div>
|
| 1158 |
</div>
|
| 1159 |
|
| 1160 |
<div class="card">
|