Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/release-lock.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ The opt-in probe creates an isolated, minimal project with a standard PyPI
dependency and exercises actual uv locking. CI enables it. These commands do not
install or import the country model.

For the SPM integration, `spm-calculator` 1.0.0 reached PyPI on 2026-09-11, and
For the SPM integration, `spm-calculator` 1.1.0 reached PyPI on 2026-11-02, and
the committed country lock resolves it from `https://pypi.org/simple` with sdist
and wheel SHA-256 hashes, so `--committed` passes on the committed files.
`pyproject.toml` requires `>=1.0.0,<=1.0.0.post1` and the lock pins 1.0.0;
moving that pin to the post-release is an ordinary reviewed lock change. This
`pyproject.toml` requires `>=1.1.0,<1.2` and the lock pins 1.1.0; moving to a
later 1.1.x release is an ordinary reviewed lock change. This
guard validates dependency sources, artifact URLs and hashes, never a version
string, so the calculator requirement is held by `pyproject.toml` and review
rather than by `release_lock.py`. A stale root version or an older calculator
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Pull request
on:
pull_request:
branches: [main]
branches: [main, release/2.2.x]
# Concurrency: auto-cancels previous runs when new commits are pushed
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/push.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Push
on:
push:
branches: [main]
branches: [main, release/2.2.x]

jobs:
ReleaseLock:
Expand Down Expand Up @@ -333,6 +333,13 @@ jobs:
(github.repository == 'PolicyEngine/policyengine-us')
&& (github.event.head_commit.message == 'Update PolicyEngine US')
needs: [ReleaseLock, ReleaseLockTests, Baseline, HouseholdAPIPartners, Contrib, Rest, Microsimulation]
# PyPI trusted publishing, as on main: PyPI accepts uploads only from this
# workflow in the pypi environment, whose deployment branches must include
# release/2.2.x. No stored PyPI token.
environment: pypi
permissions:
contents: read
id-token: write
steps:
- name: Checkout repo
uses: actions/checkout@v6
Expand All @@ -355,6 +362,4 @@ jobs:
- name: Publish a Python distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI }}
skip-existing: true
1 change: 1 addition & 0 deletions changelog.d/cbo-cpi-2036.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add CBO's February 2026 calendar-2036 CPI-U and chained CPI-U points and keep their authored 2035 points instead of extrapolating over them, so single-year datasets extend through 2036 by default and IRS uprating projects through tax year 2036.
1 change: 1 addition & 0 deletions changelog.d/spm-calculator-1-1.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Require spm-calculator 1.1, whose canonical forecast covers 2022–2036, so SPM thresholds and SPM resources calculate for 2036.
2 changes: 1 addition & 1 deletion docs/spm.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
The country model uses the installed `spm-calculator` artifact for all five SPM
measurement amounts. It does not extrapolate thresholds with country CPI or income
parameters. Each supported year and scenario comes from the verified artifact.
The installed 1.0.0 artifact covers 2022 through 2035; unavailable years fail.
The installed 1.1.0 artifact covers 2022 through 2036; unavailable years fail.
Taxes, benefits, resources and the housing-assistance cap
remain country-model formulas. General household benefits and CBO transfer
aggregates count actual `housing_assistance`; only SPM resources count
Expand Down
3 changes: 2 additions & 1 deletion policyengine_us/parameters/gov/bls/cpi/c_cpi_u.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ values:
2033-02-01: 210.8 # 2034 value.
2034-02-01: 214.9 # 2035 value.
2035-02-01: 219.2 # 2036 value.
# Values for 2036-2100 are set programmatically in uprating_extensions.py
2036-02-01: 223.5 # 2037 value.
# Values for 2037-2100 are set programmatically in uprating_extensions.py
metadata:
economy: false
unit: currency-USD
Expand Down
3 changes: 2 additions & 1 deletion policyengine_us/parameters/gov/bls/cpi/cpi_u.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,8 @@ values:
2033-02-01: 389.6 # 2034 value.
2034-02-01: 398.4 # 2035 value.
2035-02-01: 407.3 # 2036 value.
# Values for 2036-2100 are set programmatically in uprating_extensions.py
2036-02-01: 416.5 # 2037 value.
# Values for 2037-2100 are set programmatically in uprating_extensions.py
metadata:
unit: currency-USD
label: CPI-U
Expand Down
15 changes: 10 additions & 5 deletions policyengine_us/parameters/uprating_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,9 @@ def set_all_uprating_parameters(parameters: ParameterNode) -> ParameterNode:

# IRS uprating - special case that computes from CPI
IRS_UPRATING_START_YEAR = 2010
IRS_LAST_PROJECTED_YEAR = 2035
# 2036 averages chained CPI-U from August 2034 to July 2035, the 2034 and
# 2035 February instants, which hold CBO's February 2026 calendar points.
IRS_LAST_PROJECTED_YEAR = 2036

uprating_index = parameters.gov.irs.uprating

Expand Down Expand Up @@ -446,19 +448,22 @@ def set_all_uprating_parameters(parameters: ParameterNode) -> ParameterNode:
period_day=1,
)

# CPI-U (February values, last projection year 2034)
# CPI-U (February values, last projection year 2036). Each February
# instant holds CBO's February 2026 calendar-year average for that year
# (the "# YYYY value" comments name the tax year it feeds), so CBO's last
# point, calendar 2036, sits at the 2036 instant.
extend_parameter_values(
parameters.gov.bls.cpi.cpi_u,
last_projected_year=2034,
last_projected_year=2036,
end_year=END_YEAR,
period_month=2,
period_day=1,
)

# Chained CPI-U (February values, last projection year 2034)
# Chained CPI-U (February values, last projection year 2036), as for CPI-U.
extend_parameter_values(
parameters.gov.bls.cpi.c_cpi_u,
last_projected_year=2034,
last_projected_year=2036,
end_year=END_YEAR,
period_month=2,
period_day=1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1103,14 +1103,14 @@ class FakeParam:

def test_with_real_cpi_u_parameter(self):
"""Verify get_parameter_last_year works on the actual CPI-U
parameter YAML, returning 2035 (not 2100 from uprating_extensions)."""
parameter YAML, returning 2036 (not 2100 from uprating_extensions)."""
from policyengine_us.system import system

cpi_u = _resolve_parameter(system.parameters, "gov.bls.cpi.cpi_u")
last_year = get_parameter_last_year(cpi_u)
# CPI-U YAML currently extends to 2035; if the YAML is updated,
# CPI-U YAML currently extends to 2036; if the YAML is updated,
# this assertion should be updated to match.
assert last_year == 2035
assert last_year == 2036


# ---------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def canonical(forecast, year, tenure, *, adults=2, children=2, county=None):
)
def test_every_amount_uses_canonical_final_value_for_every_supported_year(tenure):
forecast = load_forecast()
assert list(forecast.years) == list(range(2022, 2036))
assert list(forecast.years) == list(range(2022, 2037))
# Explicit period inputs cover the artifact, including its historical years.
situation = household(county="06037", tenure=tenure)
for person in situation["people"].values():
Expand Down Expand Up @@ -164,10 +164,11 @@ def test_unavailable_selection_or_consumer_extrapolation_rejected(config):
create_spm_provider(config)


def test_unknown_year_has_no_country_cpi_extrapolation():
@pytest.mark.parametrize("year", [2037, 2099])
def test_unknown_year_has_no_country_cpi_extrapolation(year):
simulation = Simulation(situation=household(county="06037"))
with pytest.raises(ValueError, match="no entry"):
simulation.calculate("spm_unit_spm_threshold", 2099)
simulation.calculate("spm_unit_spm_threshold", year)


@pytest.mark.parametrize(
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dependencies = [
# extension and is available on every supported Python version.
"pandas>=3.0",
"policyengine-core>=3.30.1",
"spm-calculator>=1.0.0,<=1.0.0.post1",
"spm-calculator>=1.1.0,<1.2",
"tables>=3.9",
"tqdm>=4.67.1",
]
Expand Down
8 changes: 4 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading