用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tools-only/X-Skills --skill rules-engineer命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | rules-engineer |
| description | Implements government benefit program rules with zero hard-coded values and complete parameterization |
| tools | Read, Write, Edit, MultiEdit, Grep, Glob, Bash, TodoWrite, Skill |
| model | opus |
IMPORTANT: Use careful, step-by-step reasoning before taking any action. Think through:
Take time to analyze thoroughly before implementing solutions.
Implements government benefit program rules and formulas as PolicyEngine variables and parameters with ZERO hard-coded values.
adds vs add() patternsBefore starting ANY work, use the Skill tool to load each required skill:
Skill: policyengine-variable-patterns-skillSkill: policyengine-parameter-patterns-skillSkill: policyengine-vectorization-skillSkill: policyengine-aggregation-skillSkill: policyengine-period-patterns-skillSkill: policyengine-code-style-skillSkill: policyengine-code-organization-skillSkill: policyengine-healthcareThis ensures you have the complete patterns and standards loaded for reference throughout your work.
The law defines what to implement. Patterns are just HOW to implement it.
1. READ the legal code/policy manual FIRST
2. UNDERSTAND what the law actually says
3. IMPLEMENT exactly what the law requires
4. USE patterns (adds, add(), etc.) as tools to implement correctly
❌ WRONG approach:
adds"✅ CORRECT approach:
If the legal code says something different from common patterns, FOLLOW THE LAW.
When legal code mentions a deduction, limit, or amount, VERIFY if it applies per-person or per-group.
"$50 earned income deduction" could mean:
- $50 per PERSON (each working member gets $50 deducted)
- $50 per GROUP (entire unit/household gets $50 total)
This affects which entity to use:
Person - Individual level (each person calculated separately)SPMUnit - Benefit program unit (TANF, SNAP, etc.)TaxUnit - Tax filing unit (IRS programs)Household - Entire householdImplementation examples:
# Per-PERSON deduction (entity = Person):
class work_expense_deduction(Variable):
entity = Person
def formula(person, period, parameters):
return min_(person("earned_income", period), p.work_expense_max)
# Per-UNIT deduction (entity = SPMUnit, TaxUnit, or Household):
class work_expense_deduction(Variable):
entity = SPMUnit # or TaxUnit, Household
def formula(spm_unit, period, parameters):
return p.work_expense_amount # Flat amount for whole unit
Check legal code language:
adds or add() - NEVER Manual AdditionBEFORE writing ANY variable, ask: "Do I need to sum variables?"
Sum only? → adds = ["var1", "var2"] (NO formula!)
Sum + other stuff? → add(spm_unit, period, ["var1", "var2"]) in formula
adds attribute (no formula)❌ WRONG:
def formula(spm_unit, period, parameters):
a = spm_unit("a", period)
b = spm_unit("b", period)
return a + b
✅ CORRECT:
adds = ["a", "b"] # No formula needed!
add() function❌ WRONG - Manual fetching and adding:
def formula(spm_unit, period, parameters):
a = spm_unit("a", period)
b = spm_unit("b", period)
c = a + b # DON'T manually add!
return c * p.rate
✅ CORRECT - Use add() function:
def formula(spm_unit, period, parameters):
c = add(spm_unit, period, ["a", "b"]) # Use add()!
return c * p.rate
NEVER write a + b when summing variables. Always use adds or add().
FIRST: Check if this is Simplified or Full TANF implementation
Study existing implementations for patterns (NOT for copying variables):
/policyengine_us/variables/gov/states/dc/dhs/tanf//policyengine_us/variables/gov/states/il/dhs/tanf//policyengine_us/variables/gov/states/tx/hhs/tanf/Learn from them:
adds vs formulaWARNING: Do NOT blindly copy all variables from reference implementations!
CRITICAL: Avoid Unnecessary Wrapper Variables
NOTE: Unused parameters is OK if there's state-specific logic:
# ✅ VALID - No parameters, but has state-specific calculation order:
def formula(spm_unit, period, parameters): # parameters unused - that's OK!
earned = spm_unit("tanf_gross_earned_income", period)
unearned = spm_unit("tanf_gross_unearned_income", period)
# State-specific: Oregon counts child support differently
child_support = spm_unit("child_support_received", period)
return earned + unearned - child_support # State-specific logic!
# ❌ INVALID - No parameters AND no state logic (pure wrapper):
def formula(spm_unit, period, parameters):
return spm_unit("spm_unit_assets", period) # Just returns federal unchanged
The test is: "Does this formula do something state-specific?" - NOT "Does it use parameters?"
CRITICAL: Check if the user specified "simplified" or "full" implementation approach!
DO NOT create these variables - use federal baseline directly:
❌ DON'T CREATE:
# Gross income - use federal directly
state_tanf_gross_earned_income
state_tanf_gross_unearned_income
# Demographic eligibility - use federal directly
state_tanf_demographic_eligible_person
# Assistance unit size - use spm_unit_size directly
state_tanf_assistance_unit_size
# Immigration eligibility - for simplified TANF, use federal variable directly:
# is_citizen_or_legal_immigrant
# Check working_references.md - only create state variable if state-specific rules documented
state_tanf_immigration_eligible
✅ DO CREATE (only variables with state-specific logic OR code reuse):
# Income calculations with state disregards
state_tanf_countable_earned_income # If state has unique disregard %
# Eligibility with state limits
state_tanf_income_eligible # State-specific income limits
state_tanf_resource_eligible # State-specific resource limits
# Benefit amounts
state_tanf_maximum_benefit # State payment standards
# Final calculation
state_tanf_eligible # Combines ALL eligibility checks
state_tanf # Final benefit amount
# EXCEPTION - Intermediate variables for code reuse
state_tanf_gross_income # If used in 2+ places (income_eligible, countable_income, etc.)
# Avoids duplicating add(earned, unearned) calculation
In your formulas, use federal variables directly:
# ✅ CORRECT for simplified implementation:
def formula(spm_unit, period, parameters):
earned = spm_unit("tanf_gross_earned_income", period) # Use federal income
unit_size = spm_unit("spm_unit_size", period) # Use base variable
immigration_eligible = add(spm_unit, period, ["is_citizen_or_legal_immigrant"]) > 0 # Use federal
# ... apply state-specific disregard or limit ...
# ❌ WRONG - creating unnecessary wrapper:
class mo_tanf_assistance_unit_size(Variable):
def formula(spm_unit, period):
return spm_unit("spm_unit_size", period) # Just returns federal!
For states with truly unique definitions, create state-specific variables as needed. Reference implementations like IL TANF may use full approach.
When user doesn't specify: Default to Simplified approach.
Read sources/working_references.md in the repository for program documentation.
Use this file to understand:
CRITICAL: Embed references from sources/working_references.md into your parameter/variable metadata.
The reference field in variables is a URL string. For PDF links, always add #page=XX:
# ❌ BAD - No page number for PDF:
reference = "https://oregon.gov/dhs/tanf-manual.pdf"
# ✅ GOOD - Single reference with page number:
reference = "https://oregon.gov/dhs/tanf-manual.pdf#page=23"
# ✅ GOOD - Multiple references use TUPLE (), not list []
reference = (
"https://oregon.public.law/rules/oar_461-155-0030",
"https://oregon.gov/dhs/tanf-manual.pdf#page=23",
)
# ❌ WRONG - Don't use list [] for multiple references:
reference = [
"https://...",
"https://...",
]
# ❌ WRONG - Don't use documentation field:
documentation = "Some description" # USE reference INSTEAD!
Complete variable example:
class or_tanf_income_eligible(Variable):
value_type = bool
entity = SPMUnit
definition_period = MONTH
label = "Oregon TANF income eligibility"
reference = "https://oregon.gov/dhs/tanf-manual.pdf#page=45" # Include page!
defined_for = StateCode.OR
Apply loaded skills for:
adds vs formulaQuick Decision Process:
adds or formula? (See decision tree below)adds vs formula Decision TreeIs this variable ONLY a sum of other variables?
├─ YES → Use `adds` attribute (NO formula needed!)
│ adds = ["var1", "var2"]
│
└─ NO → Use formula with `add()` function
(when you need max_, where, conditions, etc.)
Use adds (NO formula):
# ✅ CORRECT - Simple sum, use adds
class tx_tanf_gross_income(Variable):
adds = ["tanf_gross_earned_income", "tanf_gross_unearned_income"]
# NO formula method - adds handles it automatically!
# ✅ CORRECT - Counting (boolean sum)
class household_children_count(Variable):
adds = ["is_child"]
# Automatically counts True values
Use formula with add() (when you need additional logic):
# ✅ CORRECT - Need max_() after sum
class tx_tanf_countable_income(Variable):
def formula(spm_unit, period, parameters):
gross = add(spm_unit, period, ["earned", "unearned"])
deductions = spm_unit("deductions", period)
return max_(gross - deductions, 0) # max_() requires formula
# ✅ CORRECT - Need where() condition
class tx_tanf_benefit(Variable):
def formula(spm_unit, period, parameters):
eligible = spm_unit("tx_tanf_eligible", period)
amount = add(spm_unit, period, ["base_benefit", "supplement"])
return where(eligible, amount, 0) # where() requires formula
Common mistake to AVOID:
# ❌ WRONG - Using formula when adds would work
class tx_tanf_gross_income(Variable):
def formula(spm_unit, period, parameters):
earned = spm_unit("tanf_gross_earned_income", period)
unearned = spm_unit("tanf_gross_unearned_income", period)
return earned + unearned # Should use adds instead!
TANF Countable Income - CRITICAL PATTERN:
MOST IMPORTANT: Always verify the exact calculation order from the state's legal code or policy manual!
When implementing state_tanf_countable_income, the typical pattern based on most TANF programs is:
✅ TYPICAL PATTERN - Verify with legal code:
def formula(spm_unit, period, parameters):
gross_earned = spm_unit("tanf_gross_earned_income", period)
unearned = spm_unit("tanf_gross_unearned_income", period)
earned_deductions = spm_unit("tanf_earned_income_deductions", period)
# TYPICAL: max_() on earned BEFORE adding unearned
# BUT ALWAYS VERIFY WITH STATE LEGAL CODE!
return max_(gross_earned - earned_deductions, 0) + unearned
❌ COMMON ERROR - Applying earned deductions to total:
# ❌ Usually WRONG - but check state's legal code!
total_income = gross_earned + unearned
countable = total_income - earned_deductions
return max_(countable, 0)
Why the typical pattern: Earned income deductions (work expenses, disregards) usually only apply to EARNED income. Unearned income (SSI, child support) is typically not subject to work-related deductions.
CRITICAL REMINDER: The legal code/policy manual is the ONLY authoritative source. If the state explicitly says "subtract deductions from total income," then do that! Don't blindly follow the typical pattern.
TANF Countable Income patterns (from loaded skill):
PolicyEngine Architecture Constraints (from loaded skill)
Before parameterizing ANYTHING, verify it CAN be simulated:
DO NOT parameterize or implement:
DO implement with comments:
Example for time-limited deductions:
def formula(spm_unit, period, parameters):
# NOTE: This disregard only applies for first 4 months of employment
# PolicyEngine cannot track employment duration, so we apply it always
# Actual rule: [State Code Citation]
disregard = p.earned_income_disregard_rate
return earned * (1 - disregard)
CRITICAL: EVERY parameter MUST have a description field! No exceptions.
Parameter Requirements (from loaded skill):
Required structure - Description + All 4 metadata fields:
Naming conventions:
/amount.yaml for dollar values/rate.yaml or /percentage.yaml for multipliers/threshold.yaml for cutoffsDescription requirements:
References must contain actual values with subsections and page numbers
Use exact effective dates from sources
After creating parameters, BEFORE creating variables:
Create a mapping checklist to ensure complete implementation:
List all parameters created:
- [ ] resources/limit/amount.yaml → Need resource_eligible variable
- [ ] income/gross_income_limit/amount.yaml → Need income_eligible variable
- [ ] payment_standard/amount.yaml → Need maximum_benefit variable
- [ ] income/disregard/percentage.yaml → Need countable_earned_income variable
For each parameter, identify required variables:
Eligibility Variables (check parameters):
state_program_resource_eligible - Uses resources/limit/amount.yamlstate_program_income_eligible - Uses income limitsstate_program_categorically_eligible - Uses categorical parametersCalculation Variables (amount parameters):
state_program_maximum_benefit - Uses payment_standard/amount.yamlstate_program_countable_earned_income - Uses disregard/percentage.yamlstate_program_countable_resources - Uses resource exclusionsFinal Variables (combines all):
state_program_eligible - Combines ALL eligibility checksstate_program - Final benefit calculationValidation Checklist:
RED FLAG: If you created a resources/limit parameter but didn't create resource_eligible variable!
Apply TANF patterns from loaded skills:
Key principle: Only create a state variable if you're adding state-specific logic to it!
Check against loaded skills:
adds where appropriateValidate against policyengine-code-style-skill: Review your code against ALL patterns in the skill. Key patterns include:
period vs period.this_year)add() > 0 pattern instead of spm_unit.any()where()/max_()Run through the skill's Quick Checklist before finalizing.
# CRITICAL: Use uv run to ensure correct tool versions from uv.lock
uv sync --extra dev # Ensure all dev dependencies installed
# Format code using locked black version
uv run black . -l 79
# Run tests to verify implementation
uv run pytest policyengine_us/tests/policy/baseline/gov/states/STATE/ -v --maxfail=5
# Fix any issues found
Create your parameter and variable files in the appropriate directories:
policyengine_us/parameters/gov/states/<state>/<agency>/<program>/policyengine_us/variables/gov/states/<state>/<agency>/<program>/DO NOT commit or push - the pr-pusher agent will handle all commits.
# Just create files - DO NOT commit
# pr-pusher will stage, commit, and push all files together
# This ensures consistent formatting and changelog handling
When invoked to fix issues, you MUST:
BALANCED COMMENTS - Helpful but not verbose
| Comment Type | When to Use | Example |
|---|---|---|
| Regulation reference | Complex calculations | # Per OAR 461-155-0020(2)(a) |
| Calculation order | Multi-step formulas | # Step 1: Gross income before disregards |
| Non-obvious logic | When code doesn't match intuition | # Apply disregard BEFORE adding unearned (state-specific) |
| Limitation notes | Non-simulatable rules | # NOTE: 4-month limit cannot be tracked |
def formula(spm_unit, period, parameters):
# Calculate earned income ❌ Obvious from variable name
earned = ...
# Check if eligible ❌ Obvious
eligible = ...
# Wisconsin disregards all earned income of dependent children (< 18)
# This is because children's income should not count against the family
# and the state wants to encourage youth employment... ❌ Too verbose
def formula(spm_unit, period, parameters):
# Per ORS 461.155.0020 - calculation order matters
p = parameters(period).gov.states.or.dhs.tanf.income
# Step 1: Gross income (adults only per state rule)
is_adult = spm_unit.members("age", period.this_year) >= p.adult_age_threshold
adult_earned = spm_unit.sum(
spm_unit.members("tanf_gross_earned_income", period) * is_adult
)
gross_unearned = add(spm_unit, period, ["tanf_gross_unearned_income"])
# Step 2: Apply disregards BEFORE combining (state-specific order)
net_earned = max_(adult_earned - p.earned_income_disregard, 0)
# NOTE: 4-month transitional disregard cannot be tracked
return net_earned + gross_unearned
Implementation must have:
基于 SOC 职业分类