Agent skill
policyengine-code-organization
Code organization patterns for PolicyEngine - variable naming conventions, folder structure, file organization
Install this agent skill to your Project
npx add-skill https://github.com/PolicyEngine/policyengine-claude/tree/main/skills/technical-patterns/policyengine-code-organization-skill
SKILL.md
PolicyEngine Code Organization
Patterns for organizing PolicyEngine code - naming conventions, folder structure, and file organization.
Using the Variable Prefix
The variable prefix is defined in sources/working_references.md.
Look for this section:
## Official Program Name
**Federal Program**: [Federal program name]
**State's Official Name**: [State's official name]
**Abbreviation**: [Abbreviation]
**Source**: [Legal citation]
**Variable Prefix**: `[state]_[abbreviation]`
Use this prefix for all variable and parameter names.
Variable Naming Patterns
State Programs
# Pattern: {state}_{program}
az_liheap # Arizona LIHEAP
ca_calfresh # California CalFresh (SNAP)
ny_heap # New York HEAP (LIHEAP)
ma_snap # Massachusetts SNAP (uses federal name)
# Sub-variables: {state}_{program}_{component}
az_liheap_eligible
az_liheap_income_eligible
az_liheap_benefit_amount
Federal Programs
# Pattern: just {program}
snap
liheap
wic
# Sub-variables: {program}_{component}
snap_eligible
snap_gross_income
liheap_eligible
Standard Variable Components
Use these standard suffixes with your variable prefix:
Eligibility Variables
{prefix}_eligible # Final eligibility (combines all checks)
{prefix}_income_eligible # Income eligibility
{prefix}_resource_eligible # Resource/asset eligibility
{prefix}_activity_eligible # Work/activity requirement eligibility
{prefix}_categorical_eligible # Categorical eligibility
{prefix}_demographic_eligible # Age, household composition eligibility
{prefix}_immigration_eligible # Immigration status eligibility
Calculation Variables
{prefix} # Final benefit amount
{prefix}_maximum_benefit # Maximum possible benefit
{prefix}_countable_income # Income after deductions
{prefix}_countable_earned_income
{prefix}_countable_unearned_income
{prefix}_gross_income # Total income before deductions
Deduction/Disregard Variables
{prefix}_earned_income_disregard
{prefix}_work_expense_deduction
{prefix}_dependent_care_deduction
{prefix}_standard_deduction
Threshold/Limit Variables
{prefix}_income_limit
{prefix}_resource_limit
{prefix}_payment_standard
{prefix}_need_standard # Use state's terminology
State-Specific Terminology
Use the terminology from sources/working_references.md.
States use different terms for the same concepts:
| Concept | Possible Terms | Example |
|---|---|---|
| Benefit amount | Payment Standard, Need Standard, Grant Amount | {prefix}_need_standard |
| Income threshold | Gross Income Limit, GMI, Countable Income Limit | {prefix}_gmi_limit |
| Earnings deduction | Earned Income Disregard, Work Expense Deduction | {prefix}_earned_income_disregard |
Match the exact terms from the documentation.
Folder Organization Principles
Core Principles
- Group logically - Files that relate to the same aspect should be together
- Don't create subfolder for 1 file - If only 1 file for an aspect, keep it at parent level
- Final output at root - The main benefit variable (e.g.,
{prefix}.py) stays at the program folder root
Common Aspects (adapt to your program)
income/- Income calculations, limits, deductionseligibility/- Eligibility checksresources/- Asset/resource calculationsdeductions/- Deductions and disregards
Study Existing Implementations
Each program is different. Before organizing, look at similar programs in the codebase:
ls policyengine_us/variables/gov/states/{state}/{agency}/
Folder Structure Patterns
Small Program (~5 files) - Keep Flat
policyengine_us/variables/gov/states/{state}/{agency}/{program}/
├── {prefix}.py # Final benefit (at root)
├── {prefix}_eligible.py
├── {prefix}_income_eligible.py
├── {prefix}_maximum_benefit.py
└── {prefix}_countable_income.py
Medium Program (6-15 files) - Light Organization
policyengine_us/variables/gov/states/{state}/{agency}/{program}/
├── {prefix}.py # Final benefit (at root)
├── eligibility/
│ ├── {prefix}_eligible.py
│ ├── {prefix}_income_eligible.py
│ └── {prefix}_resource_eligible.py
└── income/
├── {prefix}_countable_income.py
└── {prefix}_gross_income.py
Large Program (>15 files) - Full Structure
policyengine_us/variables/gov/states/{state}/{agency}/{program}/
├── {prefix}.py # Final benefit (at root)
├── eligibility/
│ ├── {prefix}_eligible.py
│ ├── {prefix}_income_eligible.py
│ ├── {prefix}_resource_eligible.py
│ └── {prefix}_demographic_eligible.py
├── income/
│ ├── {prefix}_countable_income.py
│ ├── {prefix}_countable_earned_income.py
│ └── {prefix}_gross_income.py
└── deductions/
├── {prefix}_earned_income_disregard.py
└── {prefix}_work_expense_deduction.py
Tests
policyengine_us/tests/policy/baseline/gov/states/{state}/{agency}/{program}/
├── {prefix}.yaml
├── {prefix}_eligible.yaml
├── {prefix}_income_eligible.yaml
└── integration.yaml # Always named integration.yaml
Parameter Folder Organization
Parameter folders follow similar principles to variable folders — group by function.
Keep folders focused on their purpose
Each subfolder should contain parameters that serve the same function. Don't use a folder as a catch-all.
# ❌ BAD — eligibility/ contains rate dimension boundaries that aren't eligibility criteria
ccap/
├── eligibility/
│ ├── income_limit.yaml # ✅ Eligibility
│ ├── child_age_threshold.yaml # ✅ Eligibility
│ ├── center_infant_max_months.yaml # ❌ Rate table age group boundary
│ ├── preschool_max_years.yaml # ❌ Rate table age group boundary
│ └── time_category.yaml # ❌ Authorization concept
└── rates/
# ✅ GOOD — each folder contains parameters that match its purpose
ccap/
├── age_groups/ # Age group boundaries for rate lookups
│ ├── center_infant_max_months.yaml
│ └── preschool_max_years.yaml
├── eligibility/ # Actual eligibility criteria
│ ├── income_limit.yaml
│ └── child_age_threshold.yaml
├── rates/
└── time_category.yaml # At root — doesn't fit neatly in a subfolder
The key question: "Is this parameter an eligibility rule, a rate-table dimension boundary, a benefit calculation input, or something else?" Put it in the folder that matches its function.
Common Mistakes to Avoid
Variable Names
# ❌ WRONG - Using federal name when state has official name
ca_tanf_eligible # California calls it CalWORKs
# ✅ CORRECT - Using state's official name
ca_calworks_eligible
# ❌ WRONG - Inconsistent naming
az_liheap_benefit
az_liheap_eligible_status # Should be az_liheap_eligible
# ✅ CORRECT - Consistent pattern
az_liheap
az_liheap_eligible
Test File Names
# ❌ WRONG - Prefixed integration test
az_liheap_integration.yaml
# ✅ CORRECT - Standard integration test name
integration.yaml
# ❌ WRONG - Descriptive test names
test_low_income_family.yaml
# ✅ CORRECT - Variable-based test names
az_liheap.yaml
az_liheap_eligible.yaml
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
policyengine-healthcare
Healthcare program modeling in PolicyEngine-US — Medicaid, ACA marketplace, CHIP, and Medicare. Covers encoding rules, running analyses, and navigating the unique complexity of US healthcare programs. Triggers: "healthcare", "health insurance", "Medicaid", "ACA", "CHIP", "Medicare", "marketplace", "premium tax credit", "APTC", "PTC", "SLCSP", "benchmark plan", "rating area", "age curve", "family tier", "coverage gap", "Medicaid expansion", "MAGI", "medicaid_magi", "aca_magi", "medicaid_income_level", "medicaid_category", "enrollment", "takeup", "take-up", "per capita", "CSR", "cost sharing", "insurance premium", "second lowest silver", "required contribution percentage", "42 CFR", "IRC 36B", "categorical eligibility", "expansion adult", "healthcare reform", "healthcare analysis", "health policy".
policyengine-us
ALWAYS LOAD THIS SKILL FIRST before writing any PolicyEngine-US code. Contains the correct API patterns for household calculations and population simulations using the new policyengine package. Covers US federal and state taxes/benefits. Triggers: "what would", "how much would a", "benefit be", "eligible for", "qualify for", "single parent", "married couple", "family of", "household of", "if they earn", "earning $", "making $", "calculate benefits", "calculate taxes", "benefit for a", "what would I get", "what is the maximum", "what is the rate", "poverty line", "income limit", "benefit amount", "maximum benefit", "compare states", "TANF", "SNAP", "EITC", "CTC", "SSI", "WIC", "Section 8", "Medicaid", "ACA", "child tax credit", "earned income", "supplemental security", "housing voucher", "microsimulation", "population", "reform", "policy impact", "budgetary", "decile".
policyengine-uk
ALWAYS LOAD THIS SKILL FIRST before writing any PolicyEngine-UK code. Contains the correct API patterns for household calculations and population simulations using the new policyengine package (not policyengine_uk directly). Triggers: "what would", "how much would a", "benefit be", "eligible for", "qualify for", "single parent", "married couple", "family of", "household of", "if they earn", "with income of", "earning £", "making £", "calculate benefits", "calculate taxes", "benefit for a", "tax for a", "what would I get", "what would they get", "what is the rate", "what is the threshold", "personal allowance", "maximum benefit", "income limit", "benefit amount", "how much is", "Universal Credit", "child benefit", "pension credit", "housing benefit", "council tax", "income tax", "national insurance", "JSA", "ESA", "PIP", "disability living allowance", "working tax credit", "child tax credit", "Scotland", "Wales", "UK", "microsimulation", "population", "reform", "policy impact", "budgetary", "decile".
policyengine-canada
ALWAYS LOAD THIS SKILL FIRST before writing any PolicyEngine-Canada code. Contains Canadian federal and provincial tax/benefit rules for household calculations. IMPORTANT: PolicyEngine-Canada does NOT have representative population microdata. Do NOT attempt microsimulation or population-level estimates for Canada. Only provide household-level analysis (single-family impacts, eligibility, benefit amounts). Triggers: "what would", "how much would a", "benefit be", "eligible for", "qualify for", "single parent", "married couple", "family of", "household of", "if they earn", "earning $", "making $", "calculate benefits", "calculate taxes", "benefit for a", "what would I get", "what is the maximum", "what is the rate", "income limit", "benefit amount", "maximum benefit", "compare provinces", "CCB", "Canada Child Benefit", "GST credit", "HST credit", "GST/HST", "OAS", "Old Age Security", "GIS", "Guaranteed Income Supplement", "CWB", "Canada Workers Benefit", "EI", "Employment Insurance", "CPP", "Canada Pension Plan", "RRSP", "TFSA", "Ontario Child Benefit", "OCB", "Ontario Trillium Benefit", "OTB", "BC Climate Action", "Alberta Child Benefit", "Quebec", "CRA", "Canada Revenue Agency", "Canadian", "Canada", "Ontario", "British Columbia", "Alberta", "Saskatchewan", "Manitoba", "Nova Scotia", "New Brunswick", "PEI", "Newfoundland", "Yukon", "NWT", "Nunavut", "provincial tax", "federal tax Canada".
policyengine-ui-kit-consumer
This skill should be used when setting up a new project that uses @policyengine/ui-kit, debugging CSS or styling issues in a consumer app, or when Tailwind utility classes are not being generated. Also use when creating globals.css, configuring PostCSS, or troubleshooting "no styles", "no spacing", or "no layout" problems. Triggers: "ui-kit import", "globals.css setup", "Tailwind not working", "styles not applying", "utility classes missing", "setup ui-kit", "PostCSS config", "no styling", "CSS broken", "import ui-kit", "theme.css", "no layout", "no spacing", "@tailwindcss/postcss"
policyengine-tailwind-shadcn
Tailwind CSS v4 + shadcn/ui integration patterns for PolicyEngine frontend projects. Covers @theme namespaces, CSS variable conventions, SVG var() usage, and common mistakes. Triggers: "Tailwind v4", "@theme", "shadcn", "CSS variables", "design tokens CSS", "theme.css", "@theme inline"
Didn't find tool you were looking for?