PolicyEngine parameter patterns - YAML structure, naming conventions, metadata requirements, federal/state separation
From essentialnpx claudepluginhub policyengine/policyengine-claude --plugin data-scienceThis skill uses the workspace's default tool permissions.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Optimizes cloud costs on AWS, Azure, GCP via rightsizing, tagging strategies, reserved instances, spot usage, and spending analysis. Use for expense reduction and governance.
Comprehensive patterns for creating PolicyEngine parameter files.
Every parameter MUST have this exact structure:
description: [One sentence description].
values:
YYYY-MM-DD: value
metadata:
unit: [type] # REQUIRED
period: [period] # REQUIRED
label: [name] # REQUIRED
reference: # REQUIRED
- title: [source]
href: [url]
Missing ANY metadata field = validation error
Before creating ANY parameter files, read 3-5 files from a similar program in another state. Match their structure — don't invent your own. This is the single most effective way to produce correct parameter files.
Search broadly by program concept (not just program name):
# For a childcare program, search by concept keywords:
Glob 'policyengine_us/parameters/gov/states/*/*/*child*care*/'
Glob 'policyengine_us/parameters/gov/states/*/*/*ccap*/'
Glob 'policyengine_us/parameters/gov/states/*/*/*ccfa*/'
Good references by program type:
/parameters/gov/states/{st}/{agency}/tanf//parameters/gov/states/{st}/{agency}/ccfa/ or ccap//parameters/gov/states/az/{agency}/liheap/Dollar amounts → /amount.yaml
income/deductions/work_expense/amount.yaml # $120
resources/limit/amount.yaml # $6,000
payment_standard/amount.yaml # $320
Percentages/rates → /rate.yaml or /percentage.yaml
income_limit/rate.yaml # 1.85 (185% FPL)
benefit_reduction/rate.yaml # 0.2 (20%)
income/disregard/percentage.yaml # 0.67 (67%)
Thresholds → /threshold.yaml
age_threshold/minor_child.yaml # 18
age_threshold/elderly.yaml # 60
income/threshold.yaml # 30_000
description: [State] [verb] [category] to [this X] under the [Full Program Name] program.
Components:
this amount (for currency-USD)this share or this percentage (for rates/percentages)this threshold (for age/counts)For income limits:
description: [State] limits gross income to this amount under the Temporary Assistance for Needy Families program.
For resource limits:
description: [State] limits resources to this amount under the Temporary Assistance for Needy Families program.
For payment standards:
description: [State] provides this amount as the payment standard under the Temporary Assistance for Needy Families program.
For disregards:
description: [State] excludes this share of earnings from countable income under the Temporary Assistance for Needy Families program.
Descriptions should focus on what matters for simulation, not copy regulatory language verbatim. Omit regulatory details that have no practical impact:
# ❌ Too literal — no one simulates a 1-week-old:
description: Rhode Island defines the infant/toddler age range as 1 week up to 3 years under the Child Care Assistance Program.
# ✅ Practical:
description: Rhode Island defines the infant/toddler age range as up to 3 years under the Child Care Assistance Program.
Run this check on EVERY description:
# Pseudo-code validation
def validate_description(desc):
checks = [
desc.count('.') == 1, # Exactly one sentence
'TANF' not in desc, # No acronyms
'SNAP' not in desc, # No acronyms
'this amount' in desc or 'this share' in desc or 'this percentage' in desc,
'under the' in desc and 'program' in desc,
'by household size' not in desc, # No explanatory text
'based on' not in desc, # No explanatory text
'for eligibility' not in desc, # Redundant
]
return all(checks)
CRITICAL: Always spell out full program names in descriptions!
values:
2024-01-01: 3_000 # Use underscores
# NOT: 3000
2024-01-01: 0.2 # Remove trailing zeros
# NOT: 0.20 or 0.200
2024-01-01: 2 # No decimals for integers
# NOT: 2.0 or 2.00
Use exact dates from sources:
# If source says "effective July 1, 2023"
2023-07-01: value
# If source says "as of October 1"
2024-10-01: value
# NOT arbitrary dates:
2000-01-01: value # Shows no research
Date format: YYYY-MM-01 (always use 01 for day)
Use the program's effective date, not filing or publication dates:
# Regulation filed June 5, 2003; effective January 1, 2004
❌ 2003-06-05: 500 # Filing date — WRONG
✅ 2004-01-01: 500 # Effective date — CORRECT
Beware backward extrapolation: A parameter's first entry (e.g., 2006-07-01: 20) is returned for ALL prior periods. If the program didn't exist before that date, add an explicit zero:
# ❌ Phantom $20 appears in 2005:
values:
2006-07-01: 20
# ✅ Zero before program start:
values:
2000-01-01: 0
2006-07-01: 20
Don't duplicate unchanged values. If a value is the same across eras, keep one entry at the earliest applicable date.
Before removing "duplicate" date entries, verify ALL sub-categories — what looks identical at the top level may differ in specific combinations (e.g., School Age Part Time rates changed while other age/time categories stayed the same).
Flag unverified historical values in the PR description rather than silently including them.
Common units:
currency-USD - Dollar amounts/1 - Rates, percentages (as decimals)month - Number of monthsyear - Age in yearsbool - True/falseperson - Count of peopleyear - Annual valuesmonth - Monthly valuesday - Daily valueseternity - Never changesMatch period to the parameter's semantic meaning. A dimensionless rate or ratio should use period: year, not the period of the quantity it modifies (e.g., don't use period: week for a weekly copay rate — the rate itself is time-invariant).
Pattern: [State] [PROGRAM] [description]
label: Montana TANF minor child age threshold
label: Illinois TANF earned income disregard rate
label: California SNAP resource limit
Rules:
Requirements:
#page=XX at end of href ONLY (never in title)Reference Source Hierarchy — prefer online over PDF:
https://www.law.cornell.edu/regulations/rhode-island/218-RICR-20-00-4.6.gov pages with section anchors#page=XX is correctWhy: Online references are linkable, searchable, and don't require page number verification. PDF page numbers are error-prone (file page vs printed page) and links break when documents are updated.
Title Format - Include ALL subsection levels (NO page numbers):
# ❌ BAD - Too generic:
title: OAR 461-155 # Missing subsections!
title: Section 5 # Which subsection?
title: TEA Manual, page 13 # Page number belongs in href, not title!
# ✅ GOOD - Full section path, no page number:
title: OAR 461-155-0030(2)(a)(B) # All levels included
title: 7 CFR § 273.9(d)(6)(ii)(A) # Federal regulation with all subsections
title: Indiana Admin Code 12-14-2-3.5(b)(1) # State admin code
title: Arkansas TEA Manual Section 5.2.3 # Manual with section (page in href)
PDF Link Format - Always include page in href:
CRITICAL: Use the PDF file page number, NOT the printed page number inside the document.
#page=XX value is the page position in the PDF file (1st page = 1, 2nd page = 2, etc.)# ❌ BAD - No page number:
href: https://state.gov/manual.pdf
# ✅ GOOD - Page anchor in href (file page number):
href: https://humanservices.arkansas.gov/wp-content/uploads/TEA_MANUAL.pdf#page=13
href: https://adminrules.idaho.gov/rules/current/16/160503.pdf#page=8
Complete Examples:
✅ GOOD (page number in href only):
reference:
- title: OAR 461-155-0030(2)(a)(B)
href: https://oregon.public.law/rules/oar_461-155-0030
- title: Oregon DHS TANF Policy Manual Section 4.3.2
href: https://oregon.gov/dhs/tanf-manual.pdf#page=23
✅ GOOD:
reference:
- title: 7 CFR § 273.9(d)(6)(ii)(A)
href: https://www.ecfr.gov/current/title-7/section-273.9#p-273.9(d)(6)(ii)(A)
- title: Arkansas TEA Manual Section 2100
href: https://humanservices.arkansas.gov/wp-content/uploads/TEA_MANUAL.pdf#page=45
❌ BAD (page number in title):
reference:
- title: Arkansas TEA Manual, page 13 # Page belongs in href!
href: https://humanservices.arkansas.gov/wp-content/uploads/TEA_MANUAL.pdf
❌ BAD (missing info):
reference:
- title: Federal LIHEAP regulations # Too generic - no section!
href: https://www.acf.hhs.gov/ocs # No specific page
- title: OAR 461-155 # Missing subsections (2)(a)(B)!
href: https://oregon.gov/manual.pdf # Missing #page=XX
Distinguish statute from regulation. Cite the statute that establishes a rule and the regulation that implements it separately — they are different legal instruments.
Prefer direct document URLs over landing-page or index-page URLs. Agency websites frequently reorganize navigation pages while direct document links remain stable.
Annotate reference coverage windows. When a source has a known publication cutoff (e.g., last published in 2011), note which values it corroborates — don't cite it for values postdating the cutoff.
Secondary sources (WorkWorld, SSA reports) are simplified. They may omit eligibility requirements, payment categories, or add interpretive language. Always treat the Admin Code/state regulation as authoritative; use secondary sources for cross-verification only.
Verify regulation text is present. When fetching from legal databases (Cornell LII, Westlaw), verify the content contains actual regulation body text, not just a JavaScript shell — many databases render client-side.
When a regulation portal migrates domains, update ALL parameter files referencing the old domain in one pass — broken redirects are systematic.
For state policy choices, cite the state regulation, not the federal CFR that merely sets the ceiling.
Location: /parameters/gov/{agency}/{program}/
# parameters/gov/hhs/fpg/first_person.yaml
description: HHS sets this amount as the federal poverty guideline for one person.
Location: /parameters/gov/states/{state}/{agency}/{program}/
# parameters/gov/states/ca/dss/tanf/income_limit/rate.yaml
description: California uses this multiplier of the federal poverty guideline for TANF income eligibility.
income/ - Income limits, deductions, disregardseligibility/ - Age thresholds, citizenship requirementsresources/ - Asset/resource limitsEach program is different. Before organizing, look at similar programs:
ls policyengine_us/parameters/gov/states/{state}/{agency}/
# income_limit/rate.yaml
description: State uses this multiplier of the federal poverty guideline for program income limits.
values:
2024-01-01: 1.85 # 185% FPL
metadata:
unit: /1
period: year
label: State PROGRAM income limit multiplier
# payment_standard/amount.yaml
description: State provides this amount as the monthly program benefit.
values:
2024-01-01: 500
metadata:
unit: currency-USD
period: month
label: State PROGRAM payment standard amount
# age_threshold/minor_child.yaml
description: State defines minor children as under this age for program eligibility.
values:
2024-01-01: 18
metadata:
unit: year
period: eternity
label: State PROGRAM minor child age threshold
When eligibility depends on age ranges, use a single bracket-style parameter instead of separate min/max files.
# eligibility/by_age.yaml
description: Massachusetts determines eligibility for the Bay Transportation reduced fare program based on age.
metadata:
threshold_unit: year
amount_unit: bool
period: year
type: single_amount
label: Massachusetts Bay Transportation reduced fare age eligibility
reference:
- title: MBTA Reduced Fare Program
href: https://www.mbta.com/fares/reduced
brackets:
- threshold:
2024-01-01: 0
amount:
2024-01-01: false # Under 18: not eligible
- threshold:
2024-01-01: 18
amount:
2024-01-01: true # Ages 18-64: eligible
- threshold:
2024-01-01: 65
amount:
2024-01-01: false # 65+: not eligible (different program)
Federal example (SNAP student eligibility):
# parameters/gov/usda/snap/student_age_eligibility_threshold.yaml
description: The United States includes students in this age range for SNAP eligibility.
brackets:
- threshold:
2018-01-01: 0
amount:
2018-01-01: true # Under 18: eligible
- threshold:
2018-01-01: 18
amount:
2018-01-01: false # Ages 18-49: not eligible (student restrictions)
- threshold:
2018-01-01: 50
amount:
2018-01-01: true # 50+: eligible
metadata:
type: single_amount
threshold_unit: year
amount_unit: bool
label: SNAP student age eligibility threshold
reference:
- title: 7 U.S. Code § 2015 - Eligibility disqualifications
href: https://www.law.cornell.edu/uscode/text/7/2015
When to use bracket-style:
When NOT to use bracket-style:
threshold.yaml)single_amount brackets with currency amounts)# income/disregard/percentage.yaml
description: State excludes this share of earned income from program calculations.
values:
2024-01-01: 0.67 # 67%
metadata:
unit: /1
period: eternity
label: State PROGRAM earned income disregard percentage
CRITICAL: Handling Negative Values
When creating bracket-based parameters (e.g., tax credits based on AGI), the first bracket threshold MUST be -.inf if negative values are possible, NOT 0.
❌ WRONG - Excludes negative AGI:
# threshold.yaml (for single filers)
brackets:
- threshold:
2023-01-01: 0 # ❌ Bug: negative AGI excluded!
amount:
2023-01-01: 300
- threshold:
2023-01-01: 30_000
amount:
2023-01-01: 110
✅ CORRECT - Includes all possible values:
# threshold.yaml (for single filers)
brackets:
- threshold:
2023-01-01: -.inf # ✅ Covers negative AGI
amount:
2023-01-01: 300
- threshold:
2023-01-01: 30_000
amount:
2023-01-01: 110
When to use -.inf:
When 0 is appropriate:
Real-world example: Hawaii Food/Excise Tax Credit uses AGI brackets. The first threshold must be -.inf to correctly handle taxpayers with negative AGI (e.g., business losses).
CRITICAL: PolicyEngine's single_amount bracket uses "at or above threshold" logic. A value exactly at the threshold gets that bracket's rate, not the previous bracket's. When a regulation says "above X%" (meaning X% itself belongs to the lower bracket), shift the threshold by 0.0001 to match.
Example — co-payment tiers by FPL:
Regulation says:
Level 0: Less than or equal to 100% → $0
Level 1: Above 100% up to and including 125% → 2%
Level 2: Above 125% up to and including 150% → 5%
Level 3: Above 150% up to and including 261% → 7%
❌ WRONG — family at exactly 100% FPL gets 2% instead of 0%:
brackets:
- threshold:
2024-01-01: 0
amount:
2024-01-01: 0
- threshold:
2024-01-01: 1.0 # ❌ At 100% FPL → hits this bracket
amount:
2024-01-01: 0.02
✅ CORRECT — shift by 0.0001 to encode "above X%":
brackets:
- threshold:
2024-01-01: 0
amount:
2024-01-01: 0
- threshold:
2024-01-01: 1.0001 # ✅ "Above 100%" → 100% stays in previous bracket
amount:
2024-01-01: 0.02
- threshold:
2024-01-01: 1.2501 # ✅ "Above 125%"
amount:
2024-01-01: 0.05
- threshold:
2024-01-01: 1.5001 # ✅ "Above 150%"
amount:
2024-01-01: 0.07
BOUNDARY CHECK — do this for every bracket parameter:
When to apply the 0.0001 shift:
When NOT to shift:
When a rate table has multiple dimensions (e.g., age group × star rating × authorization level), use Enum breakdowns in a small number of parameter files — NOT one file per combination.
❌ BAD — 45 files (one per age × time level):
rates/licensed_center/infant/full_time.yaml # breakdown: [star_rating]
rates/licensed_center/infant/half_time.yaml
rates/licensed_center/toddler/full_time.yaml
... (16 files for center alone, 45 total)
✅ GOOD — 3 files (one per provider type) with multi-dimensional Enum breakdowns:
rates/licensed_center.yaml # breakdown: [time_category, star_rating, age_group]
rates/licensed_family.yaml # breakdown: [time_category, star_rating, age_group]
rates/license_exempt.yaml # breakdown: [time_category, step_rating, age_group]
Example rate file with 3D Enum breakdown:
# rates/licensed_center.yaml
description: Rhode Island provides these weekly reimbursement rates for licensed child care centers under the Child Care Assistance Program.
metadata:
period: week
unit: currency-USD
label: Rhode Island CCAP licensed center weekly rates
breakdown:
- ri_ccap_time_category
- ri_ccap_star_rating
- ri_ccap_center_age_group
reference:
- title: 218-RICR-20-00-4.12
href: https://www.law.cornell.edu/regulations/rhode-island/218-RICR-20-00-4.12
FULL_TIME:
STAR_1:
INFANT:
2025-07-01: 334
TODDLER:
2025-07-01: 278
PRESCHOOL:
2025-07-01: 236
SCHOOL_AGE:
2025-07-01: 210
STAR_2:
INFANT:
2025-07-01: 341
...
The variable lookup becomes simple Enum indexing:
p.licensed_center[time_category][star_rating][center_age]
When dimensions differ by category (e.g., licensed centers have 4 age groups, family care has 3):
ri_ccap_center_age_group, ri_ccap_family_age_group)select() on the top-level category (provider type) — each branch uses its own EnumsWhen quality ratings differ (e.g., star ratings 1-5 for licensed, step ratings 1-4 for exempt):
ri_ccap_star_rating, ri_ccap_step_rating)Rule of thumb: If you need helper functions in the variable to do the rate lookup, your parameter structure is too granular. Restructure the parameters.
Don't create parameters for:
WEEKS_IN_YEAR / MONTHS_IN_YEAR gives weeks-per-month. MONTHS_IN_YEAR gives 12. Don't create a weeks_per_month.yaml parameter.When a parameter changes structure over time (e.g., a flat rate becomes a tiered/marginal rate in a later year), you CANNOT put both structures in a single YAML file. Instead, split into separate files with a boolean toggle.
Problem: A single rate.yaml with marginal brackets would retroactively apply the tiered structure to years that had a flat rate.
Solution: Create a rate/ folder with three files:
rate/
├── flat.yaml # The original flat-rate value
├── incremental.yaml # The new bracket/marginal structure
└── flat_applies.yaml # Boolean toggle: true = use flat, false = use brackets
rate/flat.yaml — The original single-value parameter:
description: Washington taxes long-term capital gains at this rate.
values:
2022-01-01: 0.07
metadata:
unit: /1
period: year
label: Washington flat capital gains tax rate
reference:
- title: RCW 82.87.040(1) Tax imposed—Long-term capital assets
href: https://app.leg.wa.gov/RCW/default.aspx?cite=82.87.040
rate/incremental.yaml — The new bracket structure:
description: Washington taxes long-term capital gains at these marginal rates.
brackets:
- threshold:
2022-01-01: 0
rate:
2022-01-01: 0.07
- threshold:
2025-01-01: 1_000_000
rate:
2025-01-01: 0.099
metadata:
threshold_unit: currency-USD
rate_unit: /1
threshold_period: year
type: marginal_rate
label: Washington marginal capital gains tax rate
reference:
- title: RCW 82.87.040(1)-(2) Tax imposed—Long-term capital assets
href: https://app.leg.wa.gov/RCW/default.aspx?cite=82.87.040
- title: ESSB 5813, Chapter 421, Laws of 2025, Sec. 101
href: https://lawfilesext.leg.wa.gov/biennium/2025-26/Htm/Bills/Session%20Laws/Senate/5813-S.SL.htm
rate/flat_applies.yaml — The boolean toggle:
description: Washington uses this indicator to determine whether the flat capital gains tax rate applies.
values:
2022-01-01: true
2025-01-01: false
metadata:
unit: bool
period: year
label: Washington flat capital gains tax rate applies
reference:
- title: RCW 82.87.040(1) Tax imposed—Long-term capital assets
href: https://app.leg.wa.gov/RCW/default.aspx?cite=82.87.040
- title: ESSB 5813, Chapter 421, Laws of 2025, Sec. 101
href: https://lawfilesext.leg.wa.gov/biennium/2025-26/Htm/Bills/Session%20Laws/Senate/5813-S.SL.htm
When to use this pattern:
When NOT to use this pattern:
See variable patterns skill for the corresponding variable-side logic (if p.rate.flat_applies).
When a new bracket is added to an existing scale in a later year, you CANNOT simply add the bracket with only the new year's date — the bracket would have no defined threshold/amount for prior years, breaking the scale.
Solution: Add the new bracket with its threshold set to .inf (or -.inf for rate brackets starting from the bottom) for the base year. This makes the bracket structurally present for all years but functionally unreachable before the year it takes effect.
Example: Ohio personal exemption phase-out (HB 96)
Ohio's personal exemption had 3 brackets (by AGI). Starting 2025, a 4th bracket phases the exemption to $0 at high incomes ($750k in 2025, $500k in 2026+):
brackets:
- threshold:
2021-01-01: 0
amount:
2021-01-01: 2_400
- threshold:
2021-01-01: 40_001
amount:
2021-01-01: 2_150
- threshold:
2021-01-01: 80_001
amount:
2021-01-01: 1_900
# New bracket: use .inf for base year so pre-2025 is unaffected
- threshold:
2021-01-01: .inf # Pre-2025: unreachable → bracket is inert
2025-01-01: 750_000 # 2025: phase-out at $750k
2026-01-01: 500_000 # 2026+: phase-out drops to $500k
amount:
2021-01-01: 0 # $0 exemption above threshold
Why .inf works:
.inf, so the bracket never activatesAnother example: Ohio joint filing credit MAGI cap
brackets:
- threshold:
2021-01-01: 0
amount:
2021-01-01: 0.2
- threshold:
2021-01-01: 25_000
amount:
2021-01-01: 0.15
- threshold:
2021-01-01: 50_000
amount:
2021-01-01: 0.1
- threshold:
2021-01-01: 75_000
amount:
2021-01-01: 0.05
# New bracket: MAGI cap added by HB 96
- threshold:
2021-01-01: .inf
2025-01-01: 750_000
2026-01-01: 500_000
amount:
2021-01-01: 0
When to use .inf for new brackets:
When NOT to use this pattern:
Real-world reference: policyengine-us PR #7107 — Ohio 2025 income tax update (HB 96 personal exemption and joint filing credit MAGI caps).
The flat→bracket transition, .inf new bracket, and in_effect provision gating patterns all handle parameters that change over time, but they solve different problems:
| Flat→Bracket Transition | .inf New Bracket | in_effect Provision Gating | |
|---|---|---|---|
| Problem | Structure type changes (flat → brackets) | New bracket added to existing scale | A provision starts or ends at a specific date |
| Parameter side | Split into folder + boolean toggle | Add bracket with .inf threshold | Single in_effect.yaml boolean |
| Variable side | if p.toggle: to choose access method | No changes — .calc() works | if p.in_effect: gates entire logic block |
| Example | WA capital gains: flat 7% → tiered 7%/9.9% | OH exemptions: 3→4 brackets | CT TFA high earnings reduction (new in 2024) |
in_effect BooleanWhen a provision starts (or ends) at a specific date, create a boolean parameter that gates the entire logic block in the variable formula. This is different from flat_applies — it doesn't switch between two parameter access methods, it controls whether a block of logic runs at all.
Use case: A new program feature is added by legislation (e.g., a high-earnings reduction that didn't exist before 2024), or an existing feature is repealed.
in_effect.yaml — Boolean that tracks when the provision is active:
# e.g., payment/high_earnings/in_effect.yaml
description: Connecticut uses this indicator to determine whether the high-earnings benefit reduction applies under the Temporary Family Assistance program.
values:
1997-01-01: false
2024-01-01: true
metadata:
unit: bool
period: month
label: Connecticut TFA high earnings reduction in effect
reference:
- title: State of Connecticut TANF State Plan 2024-2026, High Earnings Provision
href: https://portal.ct.gov/dss/-/media/departments-and-agencies/dss/state-plans-and-federal-reports/tanf-state-plan/ct-tanf-state-plan-2024---2026---41524-amendment.pdf#page=10
- title: Connecticut General Statutes § 17b-112(d)
href: https://cga.ct.gov/current/pub/chap_319s.htm#sec_17b-112
Sibling parameters — The provision's actual values live alongside in_effect.yaml:
payment/high_earnings/
├── in_effect.yaml # false before 2024, true from 2024
├── rate.yaml # FPL multiplier threshold (e.g., 0.75)
└── reduction_rate.yaml # Benefit reduction rate (e.g., 0.25)
See variable patterns skill for the corresponding variable-side logic (if p.high_earnings.in_effect:).
When to use this pattern:
When NOT to use this pattern:
.inf pattern)regional_in_effect BooleanWhen a program has regional payment variations that start or end at a specific date, create a boolean that switches between regional lookup and a flat statewide amount.
Use case: A state originally had different payment standards by region, then consolidated to a single statewide amount (or vice versa).
regional_in_effect.yaml — Boolean that tracks when regional variation applies:
# e.g., payment/regional_in_effect.yaml
description: Connecticut uses this indicator to determine whether regional payment standards apply under the Temporary Family Assistance program.
values:
1997-01-01: true
2022-07-01: false
metadata:
unit: bool
period: month
label: Connecticut TFA regional payment standards in effect
reference:
- title: Connecticut General Statutes § 17b-104(c)
href: https://cga.ct.gov/current/pub/chap_319s.htm#sec_17b-104
- title: State of Connecticut TANF State Plan 2021-2023
href: https://portal.ct.gov/dss/-/media/departments-and-agencies/dss/state-plans-and-federal-reports/tanf-state-plan/ct-tanf-plan-2021-2023--draft.pdf#page=57
Folder structure — Regional amounts AND the flat statewide amount coexist:
payment/
├── regional_in_effect.yaml # true before 2022-07, false after
├── regional/
│ ├── region_a/amount.yaml # Regional amounts (by household size)
│ ├── region_b/amount.yaml
│ └── region_c/amount.yaml
├── amount.yaml # Flat statewide amount (used when regional_in_effect is false)
└── max_unit_size.yaml
See variable patterns skill for the corresponding variable-side logic (if p.regional_in_effect:).
When to use this pattern:
When NOT to use this pattern:
where() in variable)Real-world reference: Connecticut TFA payment standards — regional (Region A/B/C) before July 2022, flat statewide amount after.
CRITICAL: When referencing bracket/scale parameters in reform dicts or Python code, the bracket index goes directly on the scale node, NOT on a .brackets sub-path.
The YAML file defines brackets as a list, but the parameter tree flattens them. The bracket index attaches to the node that contains the brackets list, not to a child called brackets.
# Tax bracket rates — index on the scale node directly
"gov.states.ca.tax.income.rates.single[8].rate"
"gov.states.ca.tax.income.rates.single[8].threshold"
# UK income tax rates
"gov.hmrc.income_tax.rates.uk[0].rate"
"gov.hmrc.income_tax.rates.uk[1].threshold"
# CTC amount (bracket-based parameter)
"gov.irs.credits.ctc.amount.base[0].amount"
# EITC phase-out thresholds
"gov.irs.credits.eitc.phase_out.start[0].amount"
# ❌ WRONG — there is no ".brackets" in the path
"gov.states.ca.tax.income.rates.single.brackets[8].rate"
"gov.irs.credits.ctc.amount.base.brackets[0].amount"
# ❌ WRONG — missing bracket index entirely
"gov.states.ca.tax.income.rates.single.rate"
"gov.irs.credits.ctc.amount.base.amount"
parameters/gov/states/ca/tax/income/rates/single.yaml).yaml)path.to.scale_file[N].rate or path.to.scale_file[N].thresholdfrom policyengine_us import CountryTaxBenefitSystem
p = CountryTaxBenefitSystem().parameters
# Navigate to the node and check:
print(p.gov.irs.credits.ctc.amount.base[0].amount("2026-01-01"))
from policyengine_core.reforms import Reform
# ✅ Correct
reform = Reform.from_dict({
'gov.irs.credits.ctc.amount.base[0].amount': {
'2026-01-01.2100-12-31': 3000
},
'gov.states.ca.tax.income.rates.single[8].rate': {
'2026-01-01.2100-12-31': 0.143
},
}, 'policyengine_us')
# ❌ Wrong — will fail or silently not apply
reform = Reform.from_dict({
'gov.irs.credits.ctc.amount.base.brackets[0].amount': {
'2026-01-01.2100-12-31': 3000
},
}, 'policyengine_us')
When transcribing rate tables, verify each individual value against the source PDF. Single-digit transpositions (e.g., 305 vs 355) cascade to all derived values.
Never assume fractional-time rates are simple fractions of full-time (e.g., half-time ≠ FT/2). Always verify against the official published rate schedule — actual ratios may differ significantly.
Always implement ALL rows from the regulatory payment table, not just those in secondary sources. WorkWorld and SSA reports may omit categories that exist in the Admin Code.
When the parameter framework caches the root parameter tree during microsim init, parameters with start dates after the test year cause ParameterNotFoundError. Use the program's actual policy effective date, not a regulation amendment filing date.