$npx -y skills add PolicyEngine/policyengine-claude --skill policyengine-usUS tax-benefit domain knowledge for analysts computing household or population impacts with the policyengine package (pe.us). Load for: which entity a US program attaches to (tax_unit vs spm_unit vs person), tax-unit role flags and filing status, post-OBBBA current-law values (20
| 1 | # PolicyEngine US domain knowledge |
| 2 | |
| 3 | This skill is the US-specific layer for analysts using the `policyengine` package. It assumes |
| 4 | you already know the shared mechanics — `pe.us.calculate_household`, population `Simulation`, |
| 5 | reform dicts, datasets — from the **policyengine** skill; read that first for anything not |
| 6 | US-specific. For building new US variables or parameters, use **policyengine-model-development**. |
| 7 | For Medicaid / ACA / CHIP / Medicare, use **policyengine-healthcare**. |
| 8 | |
| 9 | Verified against policyengine 4.21.0 / policyengine-us 1.764.6 (2026-07). Re-verify law-year |
| 10 | values before reporting — the model updates continuously. |
| 11 | |
| 12 | ## The six entities, and which program lives on which |
| 13 | |
| 14 | US taxes and benefits are administered by different units, so the model has six entities. A |
| 15 | program's variable is defined on exactly one of them, and reading it from the wrong entity is the |
| 16 | most common US mistake. |
| 17 | |
| 18 | | Entity | Plural key | What it groups | |
| 19 | |---|---|---| |
| 20 | | `person` | `people` | individuals | |
| 21 | | `marital_unit` | `marital_units` | a married couple (or a single person) | |
| 22 | | `family` | `families` | a nuclear family (Census-style) | |
| 23 | | `tax_unit` | `tax_units` | a tax-filing unit (a 1040) | |
| 24 | | `spm_unit` | `spm_units` | a Supplemental Poverty Measure resource-sharing unit | |
| 25 | | `household` | `households` | everyone at a physical address | |
| 26 | |
| 27 | Which entity a program attaches to (verified — entity *and* definition period both matter): |
| 28 | |
| 29 | | Program / measure | Variable | Entity | Period | |
| 30 | |---|---|---|---| |
| 31 | | Federal income tax | `income_tax` | tax_unit | year | |
| 32 | | EITC | `eitc` | tax_unit | year | |
| 33 | | Child Tax Credit | `ctc` | tax_unit | year | |
| 34 | | State income tax (aggregate) | `state_income_tax` | tax_unit | year | |
| 35 | | SNAP | `snap` | spm_unit | **month** | |
| 36 | | TANF | `tanf` | spm_unit | year | |
| 37 | | SSI | `ssi` | **person** | **month** | |
| 38 | | Net income | `household_net_income` | household | year | |
| 39 | | Total benefits | `household_benefits` | household | year | |
| 40 | | Total taxes | `household_tax` | household | year | |
| 41 | | In poverty (SPM) | `in_poverty` | spm_unit | year | |
| 42 | | Person in poverty | `person_in_poverty` | person | year | |
| 43 | | Is a child | `is_child` | person | year | |
| 44 | |
| 45 | Rules of thumb: **income tax and its credits (EITC, CTC, CDCC, education, and the aggregate |
| 46 | `state_income_tax`) are tax-unit variables**; **means-tested transfers keyed to a resource-sharing |
| 47 | unit (SNAP, TANF, school meals, housing) are spm_unit variables**; **SSI is a person-level |
| 48 | benefit** (each individual's own SSI), rolled up into `household_benefits`. Poverty is measured on |
| 49 | the `spm_unit`. On a `calculate_household` result you read these as dot-attributes on the singular |
| 50 | entity — `result.tax_unit.eitc`, `result.spm_unit.snap`, `result.person[0].ssi`, |
| 51 | `result.household.household_net_income`. |
| 52 | |
| 53 | ## Tax-unit roles and filing status |
| 54 | |
| 55 | `tax_unit={"filing_status": ...}` accepts `SINGLE`, `JOINT`, `SEPARATE`, `HEAD_OF_HOUSEHOLD`, |
| 56 | `SURVIVING_SPOUSE`. |
| 57 | |
| 58 | Three person-level role flags exist: `is_tax_unit_head`, `is_tax_unit_spouse`, |
| 59 | `is_tax_unit_dependent`. **You usually do not set them for a simple family** — minor children in |
| 60 | the `people` list are inferred as dependents automatically, the first adult is the head, and |
| 61 | `JOINT` designates the second adult as the spouse. Setting them wrong is worse than omitting them. |
| 62 | |
| 63 | **When you do need them: adult dependents.** An adult in the `people` list is *not* auto-inferred |
| 64 | as a dependent. A 20-year-old student, a supported parent, or any qualifying relative must be |
| 65 | flagged `is_tax_unit_dependent: True`, or the model treats them as an independent unit member and |
| 66 | their credit vanishes. Verified — a HOH filer with a 20-year-old earning $4,000: |
| 67 | |
| 68 | <!-- verify --> |
| 69 | ```python |
| 70 | import policyengine as pe |
| 71 | |
| 72 | def odc(dependent): |
| 73 | kid = {"age": 20, "employment_income": 4_000} |
| 74 | if dependent: |
| 75 | kid["is_tax_unit_dependent"] = True |
| 76 | return pe.us.calculate_household( |
| 77 | people=[{"age": 45, "e |