From d2250877f6184942e35a43d054e9fcd171222b4a Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 15:12:21 -0400 Subject: [PATCH 1/3] Fill CBO total AGI for 2015-2018 with IRS SOI actuals calibration.gov.cbo.income_by_source.adjusted_gross_income had a 2015 value of $9.03T, cited to a Tax Foundation page whose table is tax-year 2013 AGI excluding dependent filers, and no values for 2016-2018, so the series and its per-capita sibling (the default uprating index for dollar inputs) held that figure through 2018 and then jumped 31.7% into 2019. Replace 2015 and add 2016-2018 with IRS SOI Publication 1304 Table 1.1, all returns, adjusted gross income less deficit: $10.210T, $10.226T, $11.010T and $11.643T. CBO values from 2019 on are unchanged. Co-Authored-By: Claude Opus 5.5 --- .../fix-cbo-agi-2016-2018-soi.fixed.md | 1 + .../calibration/gov/cbo/income_by_source.yaml | 29 ++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md diff --git a/changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md b/changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md new file mode 100644 index 00000000000..3d6f5cfe917 --- /dev/null +++ b/changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md @@ -0,0 +1 @@ +Fill total AGI in calibration.gov.cbo.income_by_source.adjusted_gross_income for 2015-2018 with IRS Statistics of Income actuals. The 2015 value was tax-year 2013 AGI excluding dependent filers and was held flat through 2018, so dollar inputs dated 2018 or earlier came out 13% to 29% too high when uprated to 2019 or later. diff --git a/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml b/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml index 74ae47aba21..19fef25c9bc 100644 --- a/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml +++ b/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml @@ -1,4 +1,4 @@ -description: Historical data and projections of detailed adjusted gross income (AGI) by source (2019-2036) +description: Historical data and projections of detailed adjusted gross income (AGI) by source (2019-2036), with IRS Statistics of Income actuals for total AGI in 2015-2018 metadata: propagate_metadata_to_children: true unit: currency-USD @@ -19,12 +19,33 @@ adjusted_gross_income: metadata: label: Total AGI values: + # IRS Statistics of Income actuals, all returns: adjusted gross income + # less deficit. 2015-01-01: - value: 9_033_840_000_000 + value: 10_210_310_102_000 metadata: reference: - - title: Tax Foundation - href: https://taxfoundation.org/data/all/federal/summary-latest-federal-income-tax-data-2015-update/ + - title: IRS SOI Tax Stats - Publication 1304 Table 1.1, tax year 2015, adjusted gross income less deficit + href: https://www.irs.gov/pub/irs-soi/15in11si.xls + 2016-01-01: + value: 10_225_938_479_000 + metadata: + reference: + - title: IRS SOI Tax Stats - Publication 1304 Table 1.1, tax year 2016, adjusted gross income less deficit + href: https://www.irs.gov/pub/irs-soi/16in11si.xls + 2017-01-01: + value: 11_009_900_155_000 + metadata: + reference: + - title: IRS SOI Tax Stats - Publication 1304 Table 1.1, tax year 2017, adjusted gross income less deficit + href: https://www.irs.gov/pub/irs-soi/17in11si.xls + 2018-01-01: + value: 11_643_439_106_000 + metadata: + reference: + - title: IRS SOI Tax Stats - Publication 1304 Table 1.1, tax year 2018, adjusted gross income less deficit + href: https://www.irs.gov/pub/irs-soi/18in11si.xls + # CBO from 2019. 2019-01-01: 11_962_000_000_000 2020-01-01: 12_650_000_000_000 2021-01-01: 14_791_339_000_000 From 8583be56bebcc40287c0c7540fa37d231b764ffb Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 16:06:25 -0400 Subject: [PATCH 2/3] Guard the default uprating series against missing years The CBO AGI total, which every dollar input without its own series follows per capita, must have a value for every year from its first to its last: a missing year holds the previous value, so the per-capita index drifts down with population and then jumps. The check fails on main (2016-2018 missing) and passes with the SOI fill. Co-Authored-By: Claude Opus 5.5 --- .../tests/core/test_uprating_series.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/policyengine_us/tests/core/test_uprating_series.py b/policyengine_us/tests/core/test_uprating_series.py index fb7d4e7aec6..5167af52f49 100644 --- a/policyengine_us/tests/core/test_uprating_series.py +++ b/policyengine_us/tests/core/test_uprating_series.py @@ -123,6 +123,22 @@ def test_series_is_defined_across_the_projection_window(series): assert _value(series, year) not in (None, 0) +def test_default_series_has_a_value_for_every_year(): + """A year with no value holds the previous one, so the per-capita index + drifts down with population and then jumps when values resume. CBO AGI + once had nothing for 2016 to 2018, so inputs dated 2018 came out 29% too + high by 2019.""" + total = get_parameter(system.parameters, _authored_series(DEFAULT)) + years = sorted( + { + int(value.instant_str[:4]) + for value in total.values_list + if value.instant_str.endswith("-01-01") + } + ) + assert years == list(range(years[0], years[-1] + 1)) + + @pytest.mark.parametrize("year", (2025, 2030, 2035, 2036)) def test_unemployment_compensation_grows_with_cbo_unemployment_outlays(year): soi = "calibration.gov.irs.soi.unemployment_compensation" From aeabda50bc760d6c1fd17adc352bd7f8f0e9135b Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 17:42:30 -0400 Subject: [PATCH 3/3] Name CBO as the 2019-2036 source; note in-window changes in changelog The node description now says the by-source series are CBO's, with SOI actuals for total AGI in 2015-2018. The changelog also covers inputs projected to a year within 2016-2018, which the old flat series grew up to 12% too little. Co-Authored-By: Claude Opus 5.5 --- changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md | 2 +- .../parameters/calibration/gov/cbo/income_by_source.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md b/changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md index 3d6f5cfe917..6fb7c5c3abe 100644 --- a/changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md +++ b/changelog.d/fix-cbo-agi-2016-2018-soi.fixed.md @@ -1 +1 @@ -Fill total AGI in calibration.gov.cbo.income_by_source.adjusted_gross_income for 2015-2018 with IRS Statistics of Income actuals. The 2015 value was tax-year 2013 AGI excluding dependent filers and was held flat through 2018, so dollar inputs dated 2018 or earlier came out 13% to 29% too high when uprated to 2019 or later. +Fill total AGI in calibration.gov.cbo.income_by_source.adjusted_gross_income for 2015-2018 with IRS Statistics of Income actuals. The 2015 value was tax-year 2013 AGI excluding dependent filers and was held flat through 2018, so dollar inputs dated 2018 or earlier came out 13% to 29% too high when uprated to 2019 or later, and up to 12% too low when uprated to a year within 2016-2018. diff --git a/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml b/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml index 19fef25c9bc..67939c85410 100644 --- a/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml +++ b/policyengine_us/parameters/calibration/gov/cbo/income_by_source.yaml @@ -1,4 +1,4 @@ -description: Historical data and projections of detailed adjusted gross income (AGI) by source (2019-2036), with IRS Statistics of Income actuals for total AGI in 2015-2018 +description: Historical data and projections of detailed adjusted gross income (AGI) by source from CBO (2019-2036), with IRS Statistics of Income actuals for total AGI in 2015-2018 metadata: propagate_metadata_to_children: true unit: currency-USD