Apply ACA PTC formula to historical premiums#8531
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8531 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 5 2 -3
Lines 62 46 -16
=========================================
- Hits 62 46 -16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
8f20740 to
1753cbb
Compare
PavelMakarchuk
left a comment
There was a problem hiding this comment.
Program Review — PR #8531 (ACA PTC formula activation 2018+)
Source Documents
- PDFs: IRS Rev. Proc. 2017-36 (2018), 2018-34 (2019), 2019-29 (2020) — listed in
/tmp/review-program-pdf-manifest.md - Year: 2018+ activation (formula rename
formula_2024→formula_2018) - Scope: PR changes only (3 new parameter entries × 2 files, 1 variable formula rename, 3 test files updated)
🔴 Critical (Must Fix)
No critical issues found.
- All 36 new parameter cells (2018/2019/2020 × initial+final × 6 brackets) match the cited IRS Revenue Procedures exactly.
- The formula-rename mechanic is correct (
formula_2018with defaultformula → 0for pre-2018 periods). - No hard-coded literals leaked into
aca_ptc.py; downstream consumers (assigned_aca_ptc,premium_tax_credit,marketplace_net_premium, etc.) integrate cleanly. - CI failure (Contrib
other-shard-1) is a GitHub Actions runner-shutdown timeout, not caused by this PR — same shard failing identically on unrelated branches (see/tmp/review-program-ci-failure.md).
🟡 Should Address
-
SLCSP backward-uprating silent inconsistency (
policyengine_us/variables/gov/aca/ptc/aca_ptc.py)
benchmark_premium_uprating.yamlcarries national-average SLCSP values for 2014–2017 ($273/$276/$299/$359). Ifslcspuprates backward via this parameter, it would return positive SLCSP for 2014–2017 whileaca_ptcreturns 0 for those years — silent inconsistency. Either (a) document inaca_ptc.pydocstring that the 2018 cutoff is gated on rating-area data availability (parameters/gov/aca/state_rating_area_cost.yamlstarts 2018-01-01), not on statute (IRC §36B applies from 2014), or (b) extendformula_2018to plainformulaand let $0 SLCSP naturally yield $0 PTC. -
Missing
periodmetadata in parameter YAMLs
policyengine_us/parameters/gov/aca/required_contribution_percentage/initial.yamland…/final.yamllack theperiod:metadata field (REQUIRED per the parameter-patterns skill). Addperiod: year. -
Missing 2017↔2018 boundary test (same household) (
policyengine_us/tests/policy/baseline/gov/aca/ptc/aca_ptc.yaml)
PR adds a 2017 zero test and a 2023 non-zero test, but no paired same-household test at the new activation boundary. Add a pair with identical inputs atperiod: 2017(→ 0) andperiod: 2018(→ non-zero) to lock informula_2018and prevent off-by-one regressions on the activation year. -
Missing 2024 regression test
The previous activation year was 2024. Existing tests cover 2023 (integration) and 2025 (unit) but no explicit 2024 unit test survives. Add aperiod: 2024case mirroring the 2025 unit test to prove the rename created no coverage hole at the old gate year. -
Missing 400% FPL cliff tests for 2018/2019/2020 (
policyengine_us/tests/policy/baseline/gov/aca/ptc/aca_required_contribution_percentage.yaml)
Original-ACA brackets define rates only through 300–400% FPL. Addaca_required_contribution_percentagetests for each of 2018/2019/2020 ataca_magi_fraction: 4.0(top of bracket → max rate) and4.01(above 400% FPL → 0, the original-ACA cliff). The existing fraction-4.40 test belongs to the ARPA schedule and does not exercise the cliff. -
Missing ARPA-era (2021–2022)
aca_ptc.yamlunit test
formula_2018now drives all years 2018+. Add at least oneperiod: 2021orperiod: 2022unit test asserting that a zero contribution percentage under ARPA yields the full SLCSP as PTC — protects against future refactors accidentally reintroducing an ARPA-specific branch. -
Changelog filename / PR number mismatch (
changelog.d/8527.fixed.md)
Branch iscodex/historical-aca-ptc; PR is #8531. Filename references issue/PR 8527. Confirm 8527 is the intended issue reference, or rename per branch-name convention.
🟢 Suggestions
- 2015/2016/2017 unindexed cosmetic — the
2015-01-01entries use the raw IRC §36B(b)(3)(A)(i) baseline (2.0/3.0/4.0/6.3/8.05/9.5). IRS published indexed tables for 2015 (Rev. Proc. 2014-37), 2016 (Rev. Proc. 2014-62), and 2017 (Rev. Proc. 2016-24). Sinceaca_ptcreturns 0 pre-2018, this has no output impact — but adding a code comment noting these are unindexed statutory baselines would prevent future confusion. - Parameter description template — descriptions ("Initial (starting) contribution percentage…") do not match the PolicyEngine "[entity] [verb] [category] to this share under the … program" template. Federal IRS parameters often deviate, so this is optional.
- Pre-existing 2026 reference (
rp-25-25.pdf) lacks a#page=anchor — inconsistent with the new entries but out of scope for this PR. - 2018 integration test — consider an end-to-end integration case at the new boundary year to complement the 2023 LA integration test.
- Inlining
is_filer— single-use intermediate inaca_ptc.py; the explanatory comment justifies keeping it. Optional.
PDF Audit Summary
| Category | Count |
|---|---|
| Confirmed correct | 36/36 (all 2018-2020 cells × initial+final, verified independently by regulatory agent and reconciliation against IRS Rev. Proc. PDF text) |
| Mismatches (code-path confirmed + visually verified) | 0 |
| Mismatches rejected (PDF audit misread branch) | 36 — investigated and cleared |
| Unmodeled items | 0 |
Note on the 36 rejected mismatches: The PDF-audit subagent read YAMLs from the local checkout, which is on branch fix-nj-filing-threshold-phantom-tax — not PR #8531's codex/historical-aca-ptc branch. The on-disk files therefore did not contain the PR's 2018/2019/2020 entries, and the audit reported them as missing. The reconciliation verifier (/tmp/review-program-codepath-1.md) re-read the PR diff at /tmp/review-program-diff.txt, confirmed every new entry is present and well-formed, and independently matched all 36 cells to the IRS Rev. Procs. The regulatory-accuracy agent (/tmp/review-program-regulatory.md) independently corroborated the same 36 matches. The audit's 36-mismatch claim is a false positive driven by branch state, not a real issue.
Validation Summary
| Check | Result |
|---|---|
| Regulatory Accuracy | 0 critical, 2 should-fix (SLCSP backward-uprating note, 2015–2017 unindexed cosmetic) |
| Reference Quality | 0 critical, 1 pre-existing warning (2026 ref missing #page=) — all 3 new refs well-formed |
| Code Patterns | 0 critical, 2 should-fix (period metadata missing, changelog filename/PR-number) |
| Test Coverage | 4 gaps (2017↔2018 boundary, 2024 regression, 400% FPL cliff for 2018-2020, ARPA-era unit test) |
| PDF Value Audit | 36 confirmed / 0 real mismatches (36 false-positive mismatches investigated and cleared) |
| CI Status | 25/26 pass; 1 unrelated runner-shutdown timeout on Contrib other-shard-1 (zero assertion failures, infra issue) |
Review Severity: APPROVE (with should-fix items)
99f3eac to
c2a96e9
Compare
|
Fixed the review items from #8531 (review). Changes made:
Verification:
The only warnings were dependency/test-runner startup noise ( |
…into pr/daphnehanse11/8531
Summary
Fixes #8527.
Tests
uv run python -m policyengine_core.scripts.policyengine_command test -c policyengine_us policyengine_us/tests/policy/baseline/gov/aca/ptc/aca_ptc.yaml policyengine_us/tests/policy/baseline/gov/aca/ptc/integration.yamlAlso run in the original workspace:
uv run python -m policyengine_core.scripts.policyengine_command test -c policyengine_us policyengine_us/tests/policy/baseline/gov/aca