|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## What Extropy Is |
| 6 | + |
| 7 | +Extropy is a Python framework + CLI for agent-based population simulation. |
| 8 | + |
| 9 | +It: |
| 10 | +- builds synthetic populations from statistically grounded attribute distributions, |
| 11 | +- adds scenario-relevant psychographic/context attributes, |
| 12 | +- connects sampled agents in a social network, |
| 13 | +- simulates multi-timestep opinion/behavior updates with two-pass LLM reasoning, |
| 14 | +- outputs segmented distributional results. |
| 15 | + |
| 16 | +## Core CLI Pipeline |
| 17 | + |
| 18 | +```bash |
| 19 | +extropy spec -> extropy extend -> extropy sample -> extropy network -> extropy persona -> extropy scenario -> extropy simulate |
| 20 | + | | |
| 21 | + extropy estimate extropy results |
| 22 | +``` |
| 23 | + |
| 24 | +Utility commands: `extropy validate`, `extropy config`. |
| 25 | + |
| 26 | +CLI entry point: `extropy` (from `pyproject.toml`), Python `>=3.11`. |
| 27 | + |
| 28 | +## Local Dev Commands |
| 29 | + |
| 30 | +```bash |
| 31 | +pip install -e ".[dev]" |
| 32 | + |
| 33 | +# tests |
| 34 | +pytest # all tests |
| 35 | +pytest tests/test_sampler.py # single file |
| 36 | +pytest -k "test_sampling" # pattern match |
| 37 | +pytest --tb=short -q # CI style (quick output) |
| 38 | + |
| 39 | +# lint / format |
| 40 | +ruff check . |
| 41 | +ruff format . |
| 42 | + |
| 43 | +# config |
| 44 | +extropy config show |
| 45 | +extropy config set pipeline.provider claude |
| 46 | +extropy config set simulation.provider openai |
| 47 | +``` |
| 48 | + |
| 49 | +## High-Level Architecture |
| 50 | + |
| 51 | +Three phases map to top-level packages: |
| 52 | + |
| 53 | +1. Population creation (`extropy/population/`) |
| 54 | +- Sufficiency check (`spec_builder/sufficiency.py`) |
| 55 | +- Attribute selection (`spec_builder/selector.py`) |
| 56 | +- Hydration (`spec_builder/hydrator.py`, `hydrators/`) |
| 57 | +- Dependency binding (`spec_builder/binder.py`) |
| 58 | +- Sampling (`sampler/core.py`) |
| 59 | +- Network generation (`network/`) |
| 60 | + |
| 61 | +2. Scenario compilation (`extropy/scenario/`) |
| 62 | +- Compiler (`compiler.py`) orchestrates parse -> exposure -> interaction -> outcomes -> assembly |
| 63 | +- Event types in code: `announcement`, `news`, `rumor`, `policy_change`, `product_launch`, `emergency`, `observation` |
| 64 | +- Outcomes: `categorical`, `boolean`, `float`, `open_ended` |
| 65 | + |
| 66 | +3. Simulation (`extropy/simulation/`) |
| 67 | +- Engine (`engine.py`) loops over timestep phases |
| 68 | +- Seed + network exposure propagation |
| 69 | +- Two-pass reasoning (role-play then classification) |
| 70 | +- Memory traces (sliding window) |
| 71 | +- Conviction-aware sharing + flip resistance |
| 72 | +- Checkpoint/resume via `simulation_metadata` |
| 73 | + |
| 74 | +## LLM Integration |
| 75 | + |
| 76 | +All LLM calls go through `extropy/core/llm.py`. |
| 77 | + |
| 78 | +Two-zone routing: |
| 79 | +- Pipeline zone (phases 1-2): `simple_call`, `reasoning_call`, `agentic_research` |
| 80 | +- Simulation zone (phase 3): `simple_call_async` |
| 81 | + |
| 82 | +Providers are created via `extropy/core/providers/`: |
| 83 | +- `openai` |
| 84 | +- `claude` |
| 85 | +- `azure_openai` |
| 86 | + |
| 87 | +Use provider factories (`get_pipeline_provider`, `get_simulation_provider`) rather than provider-specific calls in feature code. |
| 88 | + |
| 89 | +## Configuration |
| 90 | + |
| 91 | +Config lives in `extropy/config.py` and `~/.config/extropy/config.json`. |
| 92 | + |
| 93 | +Resolution order (highest first): |
| 94 | +1. Programmatic config (`configure(...)` / constructed `ExtropyConfig`) |
| 95 | +2. Environment variables |
| 96 | +3. Config file |
| 97 | +4. Pydantic model defaults |
| 98 | + |
| 99 | +Defaults in code: |
| 100 | +- `pipeline.provider = "openai"` |
| 101 | +- `simulation.provider = "openai"` |
| 102 | + |
| 103 | +API keys are env-only: |
| 104 | +- `OPENAI_API_KEY` |
| 105 | +- `ANTHROPIC_API_KEY` |
| 106 | +- `AZURE_OPENAI_API_KEY` |
| 107 | + |
| 108 | +Azure extras: |
| 109 | +- `AZURE_OPENAI_ENDPOINT` |
| 110 | +- `AZURE_OPENAI_API_VERSION` (defaults to `2025-03-01-preview`) |
| 111 | +- `AZURE_OPENAI_DEPLOYMENT` |
| 112 | + |
| 113 | +## Data Models |
| 114 | + |
| 115 | +Primary Pydantic models are under `extropy/core/models/`: |
| 116 | +- `population.py`: `PopulationSpec`, attribute/distribution/sampling models |
| 117 | +- `scenario.py`: `ScenarioSpec`, event/exposure/interaction/outcomes/simulation config |
| 118 | +- `simulation.py`: `AgentState`, `ReasoningContext`, `ReasoningResponse`, conviction maps, timestep summaries |
| 119 | +- `network.py`, `results.py`, `validation.py`, `sampling.py` |
| 120 | + |
| 121 | +YAML I/O helpers exist on core spec/config models (`to_yaml` / `from_yaml`). |
| 122 | + |
| 123 | +## Validation |
| 124 | + |
| 125 | +Population validation (`extropy/population/validator/`): |
| 126 | +- Structural: hard errors |
| 127 | +- Semantic: warnings |
| 128 | + |
| 129 | +Scenario validation: `extropy/scenario/validator.py`. |
| 130 | + |
| 131 | +## Conventions |
| 132 | + |
| 133 | +- Use `_id` from agent JSON as primary ID (fallback to index string). |
| 134 | +- Network edges are traversed bidirectionally during simulation. |
| 135 | +- Keep LLM reasoning pass semantic; classification pass handles structured outcome extraction. |
| 136 | +- Prefer data-driven network behavior through `NetworkConfig` over hardcoded social rules. |
| 137 | +- Use Pydantic `BaseModel` for all config/model classes — no dataclasses. |
| 138 | +- Canonical state lives in SQLite (`study.db`); use `StateManager` for simulation state access. |
| 139 | + |
| 140 | +## Testing & CI |
| 141 | + |
| 142 | +Tests are in `tests/` and run with `pytest`. Common fixtures are in `tests/conftest.py`: |
| 143 | +- `minimal_population_spec`, `complex_population_spec` — ready-to-use PopulationSpec objects |
| 144 | +- `ten_agents`, `sample_agents` — agent dicts for propagation/integration tests |
| 145 | +- `linear_network`, `star_network` — network topologies for testing propagation |
| 146 | + |
| 147 | +CI (`.github/workflows/test.yml`) runs: |
| 148 | +- lint: `ruff check`, `ruff format --check` |
| 149 | +- tests on Python 3.11/3.12/3.13 (via `uv`) |
| 150 | + |
| 151 | +## File Formats |
| 152 | + |
| 153 | +- YAML: population/spec/network/persona/scenario configs |
| 154 | +- JSON: sampled agents, network, result artifacts |
| 155 | +- SQLite: simulation state/checkpoints |
| 156 | +- JSONL: timeline events |
0 commit comments