PolicyPulse Development
This skill guides AI agents in developing PolicyPulse, a professional analytical tool for stress-testing policies against synthetic populations using hybrid AI (LLM + Neural Network).
When to use
Activate this skill when:
- Building or modifying PolicyPulse application code
- Creating modular Python components following clean architecture
- Designing dashboard UI components for Streamlit
- Implementing type-safe Python code with proper annotations
- Writing tests for PolicyPulse functionality
Core Principles
1. Document-Driven Development
- Source of Truth: PRD.md, DESIGN_DOC.md, and TECH_STACK.md are authoritative
- No Feature Invention: Only implement features explicitly defined in documents
- Incremental Progress: Small, safe steps that keep the project runnable
- No Summary Documents: Don't create documentation unless explicitly requested
2. Clean Architecture (Modular Monolith)
Follow the defined module structure:
app.py # Entry point, session management
ui_sections.py # UI component rendering
simulation.py # Simulation orchestration
llm_client.py # Gemini API wrapper
nn_model.py # Neural network training/inference
population.py # Synthetic citizen generation
stats.py # Aggregation and statistics
data_models.py # Dataclass definitions
utils.py # Helper functions
config.py # Environment loading
ml_data.py # Training dataset management
Module Dependency Rules:
data_models.py has no dependencies (stdlib only)
config.py is imported by app.py only
- UI layers depend on business logic, not vice versa
- External dependencies (genai, sklearn) isolated in specific modules
3. Python Type Safety
- Always use type hints: Function signatures, variables, return types
- Leverage Python 3.10+ features:
- Dataclasses for data models
- Union types with
| syntax (e.g., str | None)
- Type aliases for complex types
- Example Pattern:
from dataclasses import dataclass
from typing import Literal
@dataclass
class Citizen:
id: int
age: int
income_level: Literal["Low", "Middle", "High"]
happiness: float
def calculate_average(citizens: list[Citizen]) -> float:
return sum(c.happiness for c in citizens) / len(citizens)
4. Professional Dashboard Design
- Data Density without Overwhelm: Show comprehensive info in digestible chunks
- Progressive Disclosure: Start simple, reveal complexity on demand
- Sidebar + Main Content: Sidebar for config (300-320px fixed), main area for results
- Muted Professional Palette:
- Primary: Deep Purple (#667EEA)
- Semantic: Teal (positive), Coral (negative)
- Neutrals: Charcoal text, Pearl backgrounds
- Tabbed Analysis: Overview, Demographics, Individuals, Experts, AI Insights, Compare
- Metric Cards: Large bold values, small change indicators with colored arrows
- Responsible AI: Prominent disclaimer that this is synthetic simulation, not prediction
5. Streamlit-Specific Patterns
- Session State: Use
st.session_state for simulation results, populations, models
- File Persistence: Save models to
models/, training data to data/ as CSV/Joblib
- Component Organization: Separate UI rendering from business logic
- Layout Structure:
# Sidebar config
with st.sidebar:
# Population, steps, mode, policy config
pass
# Main content with tabs
tab1, tab2, tab3 = st.tabs(["Overview", "Demographics", "Individuals"])
with tab1:
# Metrics cards, time-series charts
pass
Implementation Guidelines
Data Models First
- Define dataclasses in
data_models.py with full type annotations
- Include docstrings explaining purpose and constraints
- Use
frozen=True for immutable data
Business Logic Isolation
- Keep simulation logic in
simulation.py, population.py, nn_model.py
- No Streamlit imports in business logic modules
- Return structured data (dataclasses, DataFrames), not UI components
UI Components
- UI rendering functions in
ui_sections.py
- Accept typed data structures as parameters
- Use Plotly for charts (
st.plotly_chart(fig, use_container_width=True))
- Follow design system: spacing (8px base), typography (Inter font), colors
Error Handling
- Graceful degradation: LLM → NN → Rule-based fallback
- User-friendly error messages in UI
- Log technical details for debugging
- Never crash the app; show error state and recovery options
Testing Patterns
- Unit tests for business logic (population generation, stats calculations)
- Integration tests for simulation workflow
- Mock external dependencies (Gemini API)
- Validate type contracts with pytest
File Organization
policypulse/
├── .streamlit/
│ └── config.toml # Streamlit configuration
├── data/
│ └── llm_training_samples.csv # Persistent training data
├── models/
│ ├── citizen_reaction_model.joblib # Trained NN
│ └── feature_scaler.joblib # Feature normalization
├── src/ # Source code modules
│ ├── app.py
│ ├── ui_sections.py
│ ├── simulation.py
│ ├── llm_client.py
│ ├── nn_model.py
│ ├── population.py
│ ├── stats.py
│ ├── data_models.py
│ ├── utils.py
│ ├── config.py
│ └── ml_data.py
├── tests/ # Test files
├── requirements.txt # Python dependencies
├── .env.example # Template for API keys
├── .gitignore
└── README.md
Technology Stack Constraints
- Python: 3.10+ only (for dataclasses, type hints, pattern matching)
- Web Framework: Streamlit (no React, Flask, or alternatives)
- LLM: Google Gemini (free tier: 15 req/min, 200/day)
- ML: Scikit-learn MLPRegressor (no PyTorch, TensorFlow)
- Data: Pandas + NumPy (no Spark, Dask)
- Charts: Plotly (no Matplotlib, Altair)
- Persistence: File-based CSV/Joblib (no databases)
Anti-Patterns to Avoid
❌ Don't:
- Invent features not in PRD
- Create React/JavaScript frontends
- Use databases (PostgreSQL, MongoDB, etc.)
- Add user authentication/accounts
- Create pixel-perfect custom CSS (accept Streamlit's design)
- Parallelize with threading (Python GIL limitations)
- Make predictive accuracy claims in UI
✅ Do:
- Follow the three source documents strictly
- Use Streamlit's built-in components
- Implement file-based persistence
- Maintain session-based architecture
- Show prominent "synthetic simulation" disclaimers
- Implement graceful LLM fallbacks
Quick Reference
Adding a New Feature
- Verify it's in PRD.md
- Check DESIGN_DOC.md for UI specs
- Review TECH_STACK.md for implementation patterns
- Create/update data models if needed
- Implement business logic (pure Python)
- Add UI rendering (Streamlit components)
- Write tests
- Keep project runnable at each step
Code Review Checklist
1---2name: policypulse-development-23description: AI-powered synthetic population simulator with clean architecture, Python type safety, and professional dashboard design patterns4---56# PolicyPulse Development78This skill guides AI agents in developing PolicyPulse, a professional analytical tool for stress-testing policies against synthetic populations using hybrid AI (LLM + Neural Network).910## When to use1112Activate this skill when:13- Building or modifying PolicyPulse application code14- Creating modular Python components following clean architecture15- Designing dashboard UI components for Streamlit16- Implementing type-safe Python code with proper annotations17- Writing tests for PolicyPulse functionality1819## Core Principles2021### 1. Document-Driven Development22- **Source of Truth**: PRD.md, DESIGN_DOC.md, and TECH_STACK.md are authoritative23- **No Feature Invention**: Only implement features explicitly defined in documents24- **Incremental Progress**: Small, safe steps that keep the project runnable25- **No Summary Documents**: Don't create documentation unless explicitly requested2627### 2. Clean Architecture (Modular Monolith)28Follow the defined module structure:29```30app.py # Entry point, session management31ui_sections.py # UI component rendering 32simulation.py # Simulation orchestration33llm_client.py # Gemini API wrapper34nn_model.py # Neural network training/inference35population.py # Synthetic citizen generation36stats.py # Aggregation and statistics37data_models.py # Dataclass definitions38utils.py # Helper functions39config.py # Environment loading40ml_data.py # Training dataset management41```4243**Module Dependency Rules**:44- `data_models.py` has no dependencies (stdlib only)45- `config.py` is imported by app.py only46- UI layers depend on business logic, not vice versa47- External dependencies (genai, sklearn) isolated in specific modules4849### 3. Python Type Safety50- **Always use type hints**: Function signatures, variables, return types51- **Leverage Python 3.10+ features**: 52 - Dataclasses for data models53 - Union types with `|` syntax (e.g., `str | None`)54 - Type aliases for complex types55- **Example Pattern**:56```python57from dataclasses import dataclass58from typing import Literal5960@dataclass61class Citizen:62 id: int63 age: int64 income_level: Literal["Low", "Middle", "High"]65 happiness: float66 67def calculate_average(citizens: list[Citizen]) -> float:68 return sum(c.happiness for c in citizens) / len(citizens)69```7071### 4. Professional Dashboard Design72- **Data Density without Overwhelm**: Show comprehensive info in digestible chunks73- **Progressive Disclosure**: Start simple, reveal complexity on demand74- **Sidebar + Main Content**: Sidebar for config (300-320px fixed), main area for results75- **Muted Professional Palette**: 76 - Primary: Deep Purple (#667EEA)77 - Semantic: Teal (positive), Coral (negative)78 - Neutrals: Charcoal text, Pearl backgrounds79- **Tabbed Analysis**: Overview, Demographics, Individuals, Experts, AI Insights, Compare80- **Metric Cards**: Large bold values, small change indicators with colored arrows81- **Responsible AI**: Prominent disclaimer that this is synthetic simulation, not prediction8283### 5. Streamlit-Specific Patterns84- **Session State**: Use `st.session_state` for simulation results, populations, models85- **File Persistence**: Save models to `models/`, training data to `data/` as CSV/Joblib86- **Component Organization**: Separate UI rendering from business logic87- **Layout Structure**:88```python89# Sidebar config90with st.sidebar:91 # Population, steps, mode, policy config92 pass9394# Main content with tabs95tab1, tab2, tab3 = st.tabs(["Overview", "Demographics", "Individuals"])96with tab1:97 # Metrics cards, time-series charts98 pass99```100101## Implementation Guidelines102103### Data Models First1041. Define dataclasses in `data_models.py` with full type annotations1052. Include docstrings explaining purpose and constraints1063. Use `frozen=True` for immutable data107108### Business Logic Isolation1091. Keep simulation logic in `simulation.py`, `population.py`, `nn_model.py`1102. No Streamlit imports in business logic modules1113. Return structured data (dataclasses, DataFrames), not UI components112113### UI Components1141. UI rendering functions in `ui_sections.py`1152. Accept typed data structures as parameters1163. Use Plotly for charts (`st.plotly_chart(fig, use_container_width=True)`)1174. Follow design system: spacing (8px base), typography (Inter font), colors118119### Error Handling1201. Graceful degradation: LLM → NN → Rule-based fallback1212. User-friendly error messages in UI1223. Log technical details for debugging1234. Never crash the app; show error state and recovery options124125### Testing Patterns1261. Unit tests for business logic (population generation, stats calculations)1272. Integration tests for simulation workflow1283. Mock external dependencies (Gemini API)1294. Validate type contracts with pytest130131## File Organization132133```134policypulse/135├── .streamlit/136│ └── config.toml # Streamlit configuration137├── data/138│ └── llm_training_samples.csv # Persistent training data139├── models/140│ ├── citizen_reaction_model.joblib # Trained NN141│ └── feature_scaler.joblib # Feature normalization142├── src/ # Source code modules143│ ├── app.py144│ ├── ui_sections.py145│ ├── simulation.py146│ ├── llm_client.py147│ ├── nn_model.py148│ ├── population.py149│ ├── stats.py150│ ├── data_models.py151│ ├── utils.py152│ ├── config.py153│ └── ml_data.py154├── tests/ # Test files155├── requirements.txt # Python dependencies156├── .env.example # Template for API keys157├── .gitignore158└── README.md159```160161## Technology Stack Constraints162163- **Python**: 3.10+ only (for dataclasses, type hints, pattern matching)164- **Web Framework**: Streamlit (no React, Flask, or alternatives)165- **LLM**: Google Gemini (free tier: 15 req/min, 200/day)166- **ML**: Scikit-learn MLPRegressor (no PyTorch, TensorFlow)167- **Data**: Pandas + NumPy (no Spark, Dask)168- **Charts**: Plotly (no Matplotlib, Altair)169- **Persistence**: File-based CSV/Joblib (no databases)170171## Anti-Patterns to Avoid172173❌ **Don't**:174- Invent features not in PRD175- Create React/JavaScript frontends176- Use databases (PostgreSQL, MongoDB, etc.)177- Add user authentication/accounts178- Create pixel-perfect custom CSS (accept Streamlit's design)179- Parallelize with threading (Python GIL limitations)180- Make predictive accuracy claims in UI181182✅ **Do**:183- Follow the three source documents strictly184- Use Streamlit's built-in components185- Implement file-based persistence186- Maintain session-based architecture187- Show prominent "synthetic simulation" disclaimers188- Implement graceful LLM fallbacks189190## Quick Reference191192### Adding a New Feature1931. Verify it's in PRD.md1942. Check DESIGN_DOC.md for UI specs1953. Review TECH_STACK.md for implementation patterns1964. Create/update data models if needed1975. Implement business logic (pure Python)1986. Add UI rendering (Streamlit components)1997. Write tests2008. Keep project runnable at each step201202### Code Review Checklist203- [ ] Type hints on all functions and class attributes204- [ ] Dataclasses used for structured data205- [ ] No Streamlit imports in business logic modules206- [ ] Error handling with graceful degradation207- [ ] Follows design system (colors, spacing, typography)208- [ ] Matches PRD feature specifications exactly209- [ ] No invented functionality outside documents