--- title: CrisisWorldCortex Environment Server emoji: 🧠 colorFrom: yellow colorTo: pink sdk: docker pinned: false app_port: 8000 base_path: /web tags: - openenv - crisis-simulation - multi-agent --- # CrisisWorldCortex Environment CrisisWorldCortex is an OpenEnv benchmark for crisis governance under partial observability. The outer environment, **CrisisWorld**, is a regional outbreak simulator with delayed telemetry, noisy measurements, scarce resources, legal constraints, hidden cascade events, and typed interventions. The inner agent system, **Cortex**, treats cognition itself as a budgeted control problem: which expert brain to consult, when to challenge consensus, when to recurse, and when to stop thinking and act. The core thesis is simple: > Same base model. Same compute. Better governance of thought should produce > better control of the world. Most environments reward only the final action. CrisisWorldCortex also makes the path to that action measurable: action validity, token budget, disagreement health, collapse risk, and the external outbreak outcome can all be tracked separately. That is the novelty: cognition is not hidden inside a prompt; it is an explicit, testable, trainable surface. ```mermaid flowchart LR A[Agent or Cortex] -->|typed OuterAction| E[CrisisWorld] E --> W[Latent outbreak state] W -->|delayed and noisy| O[Observation] W -->|dense r_outer| R[Reward] O --> A R --> A ``` ## Why It Matters CrisisWorldCortex is built to test a stronger claim than "more agents are better." Naive multi-agent systems often converge too early, repeat the same prior, or let a single judge collapse diverse reasoning into soft consensus. This benchmark asks whether a structured, budgeted council can outperform flat agents under matched model and token constraints. The environment is therefore designed around three properties: - **High-stakes partial observability**: reported cases are delayed and noisy, while hospital load, compliance, resources, and action history form the operational picture. - **Typed, enforceable action space**: six MVP actions are legal; V2-only or illegal actions are rejected and penalized without corrupting state. - **Dense reward signal**: per-tick reward separates active useful policies from no-op, rejected, and parse-failure behavior, making training and ablation curves meaningful. ```mermaid flowchart TB O[CrisisWorld observation] --> L[Per-brain lenses] L --> E[Epidemiology brain] L --> G[Governance brain] L --> Q[Logistics brain] E --> C[Council] G --> C Q --> C C --> M[Metacognition router] M -->|challenge or preserve dissent| C M -->|spend another round| E M -->|converge| A[One OuterAction] ``` ## Quick Start The simplest way to use the environment is through the `CrisisworldcortexEnv` class: ```python from CrisisWorldCortex import CrisisworldcortexAction, CrisisworldcortexEnv from CrisisWorldCortex.models import DeployResource, RequestData env = CrisisworldcortexEnv.from_docker_image("CrisisWorldCortex-env:latest") try: result = env.reset(task_name="outbreak_easy", seed=0, max_ticks=12) obs = result.observation print(f"Reset: tick={obs.tick}, regions={len(obs.regions)}") actions = [ RequestData(region="R1", data_type="case_survey"), DeployResource(region="R1", resource_type="test_kits", quantity=100), ] for payload in actions: result = env.step(CrisisworldcortexAction(action=payload)) obs = result.observation print(f"Action: {payload.kind}") print(f" tick: {obs.tick}") print(f" reward: {result.reward:.3f}") print(f" done: {result.done}") finally: env.close() ``` The `CrisisworldcortexEnv.from_docker_image()` method handles: - Starting the Docker container - Waiting for the server to be ready - Connecting to the environment - Container cleanup when you call `close()` ## Building the Docker Image Before using the environment from Docker, build the image: ```bash # From project root docker build -t CrisisWorldCortex-env:latest -f server/Dockerfile . ``` For the hackathon inference harness, the root `Dockerfile` is also present: ```bash docker build -t CrisisWorldCortex-runner:latest . ``` ## Deploying to Hugging Face Spaces You can deploy the OpenEnv environment to Hugging Face Spaces using `openenv push`: ```bash # From the environment directory, where openenv.yaml is located openenv push # Or specify options openenv push --repo-id my-org/CrisisWorldCortex --private ``` The `openenv push` command will: 1. Validate that the directory is an OpenEnv environment 2. Prepare a Hugging Face Docker Space build 3. Upload the Space, assuming Hugging Face auth is configured After deployment, your Space will be available at: ```text https://huggingface.co/spaces/ ``` The deployed Space includes: - **Web Interface** at `/web` - standard OpenEnv UI - **Cortex Dashboard** at `/cortex` - project-specific visual interface - **API Documentation** at `/docs` - OpenAPI/Swagger docs - **Health Check** at `/health` - container health monitoring - **WebSocket** at `/ws` - persistent session endpoint ## Environment Details ### Tasks | Task | Regions | What changes | |---|---:|---| | `outbreak_easy` | 4 | Lower spread, 1-tick telemetry delay, generous resources | | `outbreak_medium` | 4 | Higher spread, 2-tick delay, scarcer resources, multiple hot regions | | `outbreak_hard` | 5 | Higher spread, 3-tick delay, chain cascade, legal constraint, hidden superspreader | Training episodes default to 12 ticks. Evaluation can pass `max_ticks=20` when longer-horizon behavior is needed. ### Action Space `CrisisworldcortexAction` wraps one typed `OuterActionPayload`. | Action kind | Purpose | |---|---| | `deploy_resource` | Send test kits, hospital beds, mobile units, or vaccines to a region | | `request_data` | Reduce telemetry noise for a region for a few ticks | | `restrict_movement` | Apply none/light/moderate/strict movement restrictions | | `escalate` | Escalate authority; national escalation unlocks strict restrictions | | `reallocate_budget` | Move resources between inventory classes with efficiency loss | | `no_op` | Advance the tick without intervention | `public_communication` exists only as a V2 forward-compatible schema. In the MVP it is rejected at runtime and receives a policy penalty. ### Observation Space `CrisisworldcortexObservation` contains: - `regions`: delayed reported cases, current hospital load, compliance proxy - `resources`: current inventory for each resource class - `active_restrictions`: region-level policy constraints currently in force - `legal_constraints`: rules that block specific actions until unlocked - `tick` and `ticks_remaining` - `cognition_budget_remaining`: per-tick token budget surface - `recent_action_log`: last accepted or rejected actions Latent SEIR state is never exposed on the wire. The agent must infer the world from delayed/noisy telemetry and operational signals. ### Reward The environment returns a dense per-tick `r_outer` in `[-1.0, 1.0]`: ```text r_outer = 0.15 * infection_control + 0.05 * time_remaining + 0.10 * hospital_pressure + 0.10 * cascade_control + 0.55 * policy_validity + 0.05 * fairness ``` Policy validity is deliberately strong because it gives the learner a clean gradient: - Accepted real intervention: `+1.0` - Accepted `no_op`: `0.0` - Rejected legal/V2 action: `-0.5` - Parse-failure marker: `-1.0` and terminal failure Regression tests lock the reward signal quality: - all-`no_op` mean reward on `outbreak_easy` must stay below `0.40` - all-rejected mean reward must stay below `0.40` - active strategic deployment must stay above `0.50` - active-vs-no-op separation must stay at least `0.20` ```mermaid flowchart LR S[Post-tick WorldState] --> I[Infection] S --> H[Hospital load] S --> C[Cascade risk] S --> P[Action validity] S --> F[Fairness] I --> R[r_outer] H --> R C --> R P --> R F --> R B[Tokens used] --> T[Training reward] R --> T ``` ## Baselines and Cortex The repository includes controlled comparisons rather than only a single hero agent: - `baselines/flat_agent.py` - B1, one LLM call per tick. - `baselines/flat_agent_matched_compute.py` - B2, self-critique and revision under the same 6000-token per-tick envelope. - `baselines/cortex_fixed_router.py` - B3, Cortex with a deterministic router. - `cortex/` - typed subagents, per-brain lenses, council orchestration, anti-hivemind protocol, metacognition, and routing policy interfaces. - `training/` - reward shaping, rollout buffer, eval metrics, and notebook surfaces for GRPO/TRL-style training. The important comparison is not "Cortex used more thought." B2 exists to match compute. Cortex has to win by allocating thought better: preserving useful dissent, challenging overconfident consensus, and converging only when the action is ready. ## Running the Inference Harness `inference.py` runs the flat baseline across the three-task ladder and emits the validator-facing stdout format: ```text [START] task= env=CrisisWorldCortex model= [STEP] step= action= reward= done= error= [END] success= steps= score= rewards=<...> ``` Required: - `HF_TOKEN` - One of `LOCAL_IMAGE_NAME` or `ENV_URL` Optional: - `API_BASE_URL` - defaults to `https://router.huggingface.co/v1` - `MODEL_NAME` - defaults to `Qwen/Qwen2.5-72B-Instruct` Example: ```powershell $env:HF_TOKEN = "" $env:LOCAL_IMAGE_NAME = "CrisisWorldCortex-env:latest" uv run python inference.py ``` ## Advanced Usage ### Connecting to an Existing Server If a CrisisWorldCortex server is already running, connect directly: ```python from CrisisWorldCortex import CrisisworldcortexAction, CrisisworldcortexEnv from CrisisWorldCortex.models import NoOp env = CrisisworldcortexEnv(base_url="http://localhost:8000") result = env.reset(task_name="outbreak_medium", seed=1, max_ticks=12) result = env.step(CrisisworldcortexAction(action=NoOp())) ``` When connecting to an existing server, `env.close()` closes the client connection but does not stop the server process. ### Context Manager The client supports context manager usage for automatic connection cleanup: ```python from CrisisWorldCortex import CrisisworldcortexAction, CrisisworldcortexEnv from CrisisWorldCortex.models import DeployResource with CrisisworldcortexEnv(base_url="http://localhost:8000") as env: result = env.reset(task_name="outbreak_easy", seed=0) result = env.step( CrisisworldcortexAction( action=DeployResource( region="R1", resource_type="test_kits", quantity=100, ) ) ) ``` The client uses WebSocket sessions for: - Lower latency across many sequential steps - Persistent environment state per session - Cleaner episode loops for training and evaluation ## Development & Testing Install dependencies: ```bash uv sync --extra dev ``` Run the server locally: ```bash uv run server --port 8000 ``` Run tests: ```bash uv run pytest tests/ -v uv run ruff check . ``` Useful direct checks: ```bash # OpenEnv validation uv run openenv validate -v # Smoke one environment episode through tests uv run pytest tests/test_smoke_env.py tests/test_reward_signal_quality.py -v ``` ## Project Structure ```text CrisisWorldCortex/ |-- README.md |-- openenv.yaml |-- pyproject.toml |-- Dockerfile |-- inference.py |-- client.py |-- models.py |-- server/ | |-- app.py | |-- CrisisWorldCortex_environment.py | |-- simulator/ | | |-- seir_model.py | | `-- tasks.py | `-- graders/ | `-- outer_reward.py |-- cortex/ | |-- council.py | |-- routing_policy.py | |-- metacognition.py | |-- lenses.py | |-- subagents/ | `-- brains/ |-- baselines/ | |-- flat_agent.py | |-- flat_agent_matched_compute.py | `-- cortex_fixed_router.py |-- training/ | |-- reward_shaping.py | |-- rollout_buffer.py | `-- eval_metrics.py |-- frontend/ | `-- index.html `-- tests/ ```