Skip to content

Model the Minnesota Paid Leave employer premium - #10294

Open
MaxGhenis wants to merge 14 commits into
mainfrom
mn-employer-paid-leave-premium
Open

MaxGhenis wants to merge 14 commits into
mainfrom
mn-employer-paid-leave-premium

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #10285. CI only runs on PRs into main, so this branch contains #10285's commits. Review git diff 3698893465..HEAD (3698893 is #10285's current head, which merges main): commits 156453fd59, 5e55446497, f2f4314171, f5b8ec27a2, b0596abccf and a19c04c83c, plus merges of #10285's head (75ec5a58dc, c1c6da1a38). This PR merges after #10285. (#10282, which #10285 waited on, was closed once #10279 fixed the same NC test on main.)

What this changes

Minnesota Paid Leave had only an employee-side variable. So employer_additional_state_payroll_tax, employer_payroll_tax and the employer-level employer_total_additional_state_payroll_tax left out Minnesota's employer premium. Under #10285, the part of the permitted employee share an employer does not deduct also had nowhere to land. This PR models the premium under Minn. Stat. 268B.14:

  1. The premium is payable by the employer (subd. 1), at the annual rate: 0.88% for 2026 and 2027. That is the statutory 0.7% of subd. 6, as the commissioner adjusted it under subd. 7; DEED's July 31, 2026 bulletin keeps it for 2027.
  2. The employer pays at least half (subd. 3). Employees pay "the remaining portion, if any", by wage deduction.
  3. A small employer eligible under subd. 5a pays 75% of the rate, and must itself pay at least 25% of the full rate (subd. 5a(b)).
  4. The employer pays the premium less the employee deduction. With Let employers deduct less than the permitted state payroll premium, and apply Massachusetts' 2027 PFML cap swap #10285, that deduction is state_payroll_premium_deduction_share times the permitted employee portion.
2026 and 2027 Large employer Small employer (subd. 5a)
Premium rate 0.88% 75% × 0.88% = 0.66%
Employer minimum 50% × 0.88% = 0.44% 25% × 0.88% = 0.22%
Largest employee deduction 0.88% − 0.44% = 0.44% 0.66% − 0.22% = 0.44%
Employer pays, at deduction share s 0.88% − s × 0.44% 0.66% − s × 0.44%

Each rate applies to taxable wages: wages up to the Social Security base rounded to the nearest $1,000, which is $185,000 in 2026 (268B.01, subd. 43). The two statutes differ here. 268B.14, subd. 4 caps wages at the unrounded Social Security maximum, $184,500 for 2026. The model, which already did this on main before this PR, follows subd. 43's rounded figure, the one DEED publishes. Using $184,500 instead would lower the 2026 maximum premium per worker from $1,628 to $1,623.60. DEED's premiums page confirms each figure (pl.mn.gov, read 2026-10-19). It gives the 0.88% rate for 2026 and 2027, the 0.66% small employer rate and the 0.44% employee maximum. It adds that "the maximum contribution from employees in this case is the same as an employee of a large employer". DEED's small employer designation notice says the same ("Like large employers, small employers can deduct up to 0.44% of wages"). It also defines the 2026 basis period and the wage limit used below.

Parameters (gov.states.mn.tax.payroll.paid_leave)

  • rate: 0.88% from 2026, with 2027 entered explicitly.
  • employer_minimum_share: 50%.
  • small_employer.rate_share: 75%.
  • small_employer.employer_minimum_share: 25% of the full rate.
  • small_employer.max_headcount: 30.
  • small_employer.max_average_wage_ratio: 150% (subd. 5a(a)(2)).
  • small_employer.state_average_annual_wage: $73,989 for 2026 premiums (DEED's statewide average annual wage for 2025).

Each parameter starts with a 0000-01-01 sentinel. pe-us backdates first values only to 2015, so without one, every Minnesota calculation before 2015 fails with ParameterNotFoundError; a 2014 YAML case guards this. rate's sentinel is 0, which keeps the program off before 2026. The others carry their 2026 values, so a reform that sets an earlier rate gets the statutory split rather than a zero employer minimum.

employee_rate (0.44%) is removed. The 0.44% is now derived as the rate less the employer's minimum. Deriving it is what lets a small employer's employee portion come out right, and lets a reform of the rate or the shares reach both sides. A reform that set gov.states.mn.tax.payroll.paid_leave.employee_rate must now set rate or employer_minimum_share instead.

Variables

  • mn_paid_leave_small_employer: the subd. 5a(a) test (see the proxies below).
  • mn_paid_leave_premium_rate: the rate, or 75% of it for a small employer.
  • mn_paid_leave_permitted_employee_rate: the premium rate less the employer's minimum, held between 0 ("the remaining portion, if any") and the premium itself.
  • mn_paid_leave_premium: the premium rate times taxable wages.
  • mn_employee_paid_leave_contribution: the permitted employee rate times taxable wages times the deduction share. It was 0.44% times wages times the share, and is unchanged at every current parameter value.
  • mn_employer_paid_leave_contribution: the premium less the employee contribution.
  • mn_employer_additional_state_payroll_tax: added to employer_additional_state_payroll_tax.
  • employer_total_mn_paid_leave_taxable_wages: the employer-level wage base.
  • employer_total_additional_state_payroll_tax gains a Minnesota branch. It computes (premium rate − share × permitted employee rate) × employer-level wages, reading the same two rate variables as the per-worker path.

Proxies for subds. 5a–5c, and what is not modeled

  • Employee count (subd. 5b). employer_headcount (default 100) stands in for the employer's highest quarterly count of wage records in the basis period, the four quarters ending September 30 of the prior year. For an employer not covered for the whole period, it stands in for the employer's own estimate (5b(c)).
  • Average wage (subd. 5c). The new input is mn_paid_leave_employer_average_quarterly_wage. Per DEED, it is the covered wages of the employer's highest-paid quarter divided by its highest employee count. Its default of 0 treats the wage test as met, so employer_headcount alone decides the small employer rate unless the input is set. Two alternatives were rejected:
    • Proxying with the worker's own wages would turn a firm-level test into a jump in the employer's premium at $110,983.52 a year of the worker's own pay, which the law does not have.
    • Deriving the average from employer-level totals would make the per-worker and employer-level paths disagree.
  • Wage limit. The limit is the statutory 150% times DEED's statewide average annual wage, divided by four quarters, compared in whole cents. DEED's designation notice applies $27,745.88 a quarter to 2026 premiums, whose basis period is October 2024 to September 2025. That figure is 150% of its 2025 statewide average annual wage of $73,989, which is $18,497.25 a quarter. The model reproduces it as 150% × $73,989 / 4 = $27,745.875, rounded half up to $27,745.88. The input is compared unrounded with that limit, at the input's float32 precision:
    • an input of exactly $27,745.88 meets it;
    • $27,745.885 doesn't, as it wouldn't against DEED's published figure.
    • We found no DEED figure for 2027 premiums (basis period October 2025 to September 2026) as of 2026-10-19, so the 2026 value carries forward.
  • Employer-level wages. employer_total_mn_paid_leave_taxable_wages defaults to employer_total_taxable_earnings_for_social_security, which caps each worker at the Social Security base ($184,500 in 2026) rather than Minnesota's rounded base ($185,000). The two bases differ by at most $500 a worker. The default understates in 2026 ($184,500 against $185,000) and overstates in 2027 ($192,300 against $192,000). Users can set the input directly.
  • Not modeled:
    • approved private plans (subds. 1 and 6(2)–(3), section 268B.10). The model assumes the employer participates in both state programs;
    • recalculation after a new employer's low estimate (subds. 5b(d), 5c(c));
    • subd. 3's minimum-wage floor on deductions;
    • DEED's administrative third condition for the small employer rate, that the employer filed every wage detail report in the basis period.

Default outputs that change

From 2026, every Minnesota worker now has an employer premium. At the defaults (100 employees, full deduction) it is 0.44% of taxable wages, and it flows into:

  • employer_additional_state_payroll_tax;
  • employer_state_payroll_tax;
  • employer_payroll_tax;
  • employer_cost_of_employment.

For Minnesota employer-level inputs, the employer-level path rises the same way: employer_total_additional_state_payroll_tax, employer_total_state_payroll_tax, employer_total_payroll_tax and employer_total_cost_of_employment. Employee-side amounts don't change, because the permitted employee rate is 0.44% for both sizes of employer. Household outputs don't change either. No household or tax-unit variable reads these employer-side variables. The CRFB tax_employer_payroll_tax reform adds only employer Social Security and Medicare tax to gross income, so it doesn't pick up the premium either.

Invariants

These are checked by policyengine_us/tests/core/test_state_payroll_premium_deduction_share_invariants.py (Hypothesis, extended from #10285). They hold for every worker, wage, employer size, average wage and share, in 2026 and 2027:

  • Properties 1–6 of Let employers deduct less than the permitted state payroll premium, and apply Massachusetts' 2027 PFML cap swap #10285 now cover Minnesota.
    • Conservation (3). Employee plus employer premium doesn't depend on the share. Only New York's employer cost stays unmodeled, and its employer amount is 0 at any share.
    • Monotonicity (4). A larger share never lowers the employee amount or raises the employer amount.
    • Differential (5). For a one-worker employer whose Minnesota wage total is capped at the rounded base, the employer-level employer_total_additional_state_payroll_tax equals the per-worker employer_additional_state_payroll_tax.
  • New property 7: a statute-literal reference for Minnesota. The test computes the premium itself from the statute and DEED figures, not from the parameter files: 0.88%, or 0.66% for 30 or fewer employees at an average quarterly wage of at most $27,745.88. It checks three things:
    • mn_paid_leave_premium equals that premium;
    • employee plus employer equals it at every share;
    • the employer pays exactly its minimum (half the premium, or 0.22% of wages for a small employer) plus (1 − share) times the rest.
  • What the draw covers. It adds Minnesota's 30/31-employee boundary and a drawn average wage in whole cents, including $27,745.88 and $27,745.89. Each example includes a small and a large Minnesota employer.

Tests run locally

Targeted files only, per the host rules; the full YAML shards are left to CI.

  • New policyengine_us/tests/policy/baseline/gov/states/mn/tax/payroll/paid_leave/mn_employer_paid_leave_contribution.yaml: 22 passed. Each new value is computed by hand in a comment from the statute and DEED figures; cases that repeat a value computed earlier in the file don't repeat the comment. The cases cover:

    • large and small employers at shares 1, 0.5 and 0;
    • the 30/31-employee boundary, and the wage limit at $27,745.88, $27,745.885 and $27,745.89;
    • the $185,000 cap, fractional cents and negative wages;
    • the flow into employer_payroll_tax ($8,510 on $100,000);
    • 2014 (before parameter backdating), 2025 and 2027, and a worker outside Minnesota;
    • the employer-level total, including a Minnesota-base override.
  • state_payroll_premium_deduction_share.yaml (16 passed, its Minnesota case now checks the employer's $660) and mn_employee_paid_leave_contribution.yaml (3 passed).

  • policyengine_us/tests/core/test_payroll_contributions.py: 107 passed. Minnesota is added to the employer-side and employer-level cases. A new test, test_minnesota_paid_leave_shares_follow_the_parameters, applies reforms of the rate and both employer minimums and checks the derived employee portion against two bounds:

    • its floor: a small employer minimum of 80% leaves employees $0;
    • its cap: a small employer minimum of −10% leaves employees the whole $750 premium, not more.

    A second new test, test_minnesota_small_employer_wage_limit_rounds_half_up, pins the limit's rounding. A reform setting the statewide average to $73,991 gives 150% × $73,991 / 4 = $27,746.625, which rounds half up to $27,746.63. So $27,746.63 qualifies and $27,746.64 doesn't. Half-to-even rounding would give $27,746.62, and the test fails under it.

  • policyengine_us/tests/core/test_input_variable_definitions.py: 4 passed.

  • Invariants: 2 passed (2.7–9.2 s of test time, 31 s wall at most, peak footprint 1.07 GB).

Mutation check

Each mutant breaks one formula, aggregate or parameter. Runs, in order:

  • r1, at 5e55446. 19 mutants. The full targeted set killed all 19. The invariants test alone killed 17; the two it can't reach are:
    • the employee floor, which only a reform reaches (the reform test kills it);
    • the employer-level wage default, which the property test sets directly (the YAML kills it).
  • r2, at f2f4314. 23 mutants, after the review fixes. 22 killed. The survivor rounded the input to cents, which turned out to be a design flaw rather than a test gap: an average a fraction of a cent above the limit qualified. f5b8ec2 removes it.
  • r3, at f5b8ec2. 8 mutants on the new wage logic and the restored sentinel, all killed. They make the test strict, compare in float64, skip the quarter or the cent rounding, change the ratio or the state average, or drop the sentinel.
  • r4, at b0596ab. 13 mutants on the wage logic, the sentinels and every share and limit parameter, all killed.
  • a19c04c. The new rounding test fails under a half-to-even mutant.

The rest of the code is unchanged since r2. Script and results: ~/reviews/mn-employer-paid-leave-premium-2026-10-19/ (mutants.py, runs/mutants-*.txt).

Review

Independent adversarial review (Opus 5.5, in session; no Subfleet lanes were open), ~/reviews/mn-employer-paid-leave-premium-2026-10-19/runs/review-r1.md.

r1: APPROVE, no must-fix. The reviewer recomputed every case and confirmed the statute reading against DEED's small employer designation notice. It found that nothing references employee_rate in this repo, policyengine-api, policyengine-app-v2 or policyengine.py. It also showed property 7 is independent of the parameter files: under five parameter reforms, only property 7 fails. f2f4314 addresses its findings:

  • S1: the wage limit gets a dated source, and the limit is restructured as ratio × state average.
  • S2: whole-cent draws in the property test.
  • N2: the employee portion is capped at the premium.
  • N3: the placeholders were dropped, then restored (see below).
  • N4: a removed changelog fragment.
  • N1, N5, N6: this body.
  • N7: rulespec-us#1819.

Delta review r2: APPROVE, runs/review-r2.md. It caught a regression in f2f4314: dropping the placeholders broke pre-2015 calculations, and f5b8ec2 fixes it. b0596ab applies its suggestions:

  • statutory-value sentinels;
  • half-up rounding of the limit;
  • wording.

r3: APPROVE at b0596ab (runs/review-r3.md). It checked the 2014 path and a 2025 backcast reform: under the reform, large employers split 440/440 and small employers 440/220. a19c04c applies its last nit, the sentinel comment, and its optional rounding test.

r2 also found that in 2014 employer_total_additional_state_payroll_tax fails for every state with ParameterNotFoundError, because Colorado FAMLI's rate parameters on main start in 2023 with no sentinel. That is not this PR's change, and open PR #10154 adds the sentinel.

Impact

Not run here: a disk pause (#9, 2026-10-19) holds impact runs. Suggested hub queue line, measuring the employer side and confirming households don't move:

10294|2026|mn_employer_paid_leave_contribution employer_additional_state_payroll_tax employer_state_payroll_tax employer_payroll_tax

axiom: Minn. Stat. 268B.14 → TheAxiomFoundation/rulespec-us#1819 queued (extended with the employer outputs, the subd. 5a leaf inputs and companion rows matching these YAML cases; blocked on corpus ingestion, TheAxiomFoundation/axiom-corpus#893)

🤖 Generated with Claude Code

MaxGhenis and others added 7 commits October 19, 2026 14:33
Add employer_state_payroll_premium_deduction_share (default 1) for the
programs whose statute puts the premium on the employer and lets it deduct
up to a share from wages: CO FAMLI, DE Paid Leave, ME and MA PFML, MN Paid
Leave, NY PFL and DBL, the VT Child Care Contribution and WA PFML. The
employee amount is the permitted share times the deduction share; the
employer-side variables carry the part it does not deduct.

Encode Acts 2026 c. 101 ss. 25-26 for Massachusetts from 2027-01-01, with
DFML's 2027 family and medical rates, and cite CGS 31-49g(b)(1) for the
Connecticut paid leave rate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…variants

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe the deduction-share programs by the employer's choice, not by
who owes the premium (NY and WA put the contribution on the worker), note
that MN and NY employer costs are not modeled, state why WA PFML is in and
Paid Leave Oregon is out, and note that Rev. Rul. 2025-4's treatment of an
employer-paid employee share as wages is not modeled. Cap the one-worker
employer's taxable total in the invariants so the employer-level path is
checked for every modeled state and size, pin the 2027 Massachusetts
parameter values, and add file-page anchors to the PDF references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Minn. Stat. 268B.14 makes the premium payable by the employer, which pays at
least half (subd. 3); a small employer under subd. 5a pays 75% of the rate
and at least a quarter of the full rate. The employer pays the premium less
the employee deduction, so the part of the permitted employee share an
employer does not deduct (PR #10285) now lands on the employer side.

- New parameters: rate (0.88% for 2026 and 2027), employer_minimum_share,
  and small_employer/{rate_share, employer_minimum_share, max_headcount,
  max_average_quarterly_wage}. They replace employee_rate (0.44%), which is
  now derived.
- New variables: mn_paid_leave_small_employer (employer_headcount and a new
  average quarterly wage input stand in for subds. 5b and 5c),
  mn_paid_leave_premium_rate, mn_paid_leave_permitted_employee_rate,
  mn_paid_leave_premium, mn_employer_paid_leave_contribution,
  mn_employer_additional_state_payroll_tax and
  employer_total_mn_paid_leave_taxable_wages.
- employer_additional_state_payroll_tax and the employer-level
  employer_total_additional_state_payroll_tax include Minnesota.
- YAML cases computed from the statute and DEED rates, MN rows in the payroll
  contribution tests, and MN in the deduction-share invariants, with a new
  statute-literal property for Minnesota.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…re' into mn-employer-paid-leave-premium

# Conflicts:
#	policyengine_us/variables/input/employer_payroll.py
A reform of the rate or the employer minimums reaches both sides, and a small
employer minimum above the small employer premium leaves employees nothing
(subd. 5a(b)(2), "the remaining portion, if any").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 19, 2026 17:44
Brings in main through 1661d71, including #10279's update to North Carolina SA Case 37, which was the only CI failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 5 commits October 19, 2026 18:55
- The small employer wage limit is now the statutory 150% (subd. 5a(a)(2))
  times DEED's statewide average annual wage ($73,989 for 2026 premiums,
  from DEED's small employer designation notice) per quarter, compared in
  whole cents as DEED states it ($27,745.88). This replaces the
  max_average_quarterly_wage parameter, which had no period and cited a page
  that gives no year.
- The permitted employee rate is capped at the premium as well as floored at
  0 ("the remaining portion, if any"); the reform test covers both.
- The structural shares and limits no longer carry zero placeholders before
  2026; the rate alone gates the program.
- The property test draws the average wage in whole cents, so its float64
  reference can't disagree with the model's float32 input below a cent.
- Cite DEED's July 31, 2026 bulletin for the 2027 rate, and move the
  employee_rate removal into a removed changelog fragment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…at32

- Restore the 0000-01-01 sentinels on the Minnesota Paid Leave shares and
  limits. pe-us backdates parameters only to 2015, so without them every
  Minnesota employer-side calculation before 2015 raised
  ParameterNotFoundError (caught by the delta review; a 2014 YAML case now
  guards it).
- Compare the unrounded average wage with DEED's cent-rounded limit at the
  input's float32 precision, instead of rounding the input to cents: an
  average a fraction of a cent above $27,745.88 now fails the test, as it
  does against DEED's published limit, while an input of exactly $27,745.88
  still meets it. A YAML case covers $27,745.885.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Minnesota Paid Leave shares and limits now carry their 2026 values
  from 0000-01-01, so a reform that sets an earlier rate gets the statutory
  split instead of a zero employer minimum; the zero rate still keeps the
  program off before 2026, and pre-2015 years still compute.
- Round the small employer wage limit to the cent half up, as the repo does
  for Minnesota's taxable wage base, instead of numpy's half-to-even.
- Say that DEED calculates the statewide average annual wage each year, and
  that 150% of $73,989 / 4 is $27,745.875, which DEED gives as $27,745.88.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The sentinel comment now says what happens: earlier years read the 2026
  value every year, and the zero rate keeps every amount at 0 before 2026.
- A reform setting the statewide average to $73,991 puts the limit at
  $27,746.625, which half-up rounding makes $27,746.63; the new test fails
  under numpy's half-to-even rounding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 20, 2026 02:51
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Hand-off to the US + core hub.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Oct 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (909176a) to head (a19c04c).
⚠️ Report is 544 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main    #10294    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            4         1     -3     
  Lines           76       193   +117     
  Branches         2         0     -2     
==========================================
+ Hits            76       193   +117     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@DTrim99

DTrim99 commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Model the Minnesota Paid Leave employer premium

PR #10294 (author: MaxGhenis). Head a19c04c83c. The branch is 14 ahead of main and 19 behind. First review.

Summary

The PR adds the employer side of Minnesota Paid Leave under Minn. Stat. 268B.14:

  • Premium. The rate is 0.88% for 2026 and 2027, or 75% of it for a subd. 5a small employer.
  • Employer minimum. The employer pays at least 50% of the premium. A small employer pays at least 25% of the full rate.
  • Employee amount. The permitted employee rate is the premium rate less the employer minimum, times Let employers deduct less than the permitted state payroll premium, and apply Massachusetts' 2027 PFML cap swap #10285's deduction share. The employer pays the rest of the premium.
  • Aggregates. The premium now flows into employer_additional_state_payroll_tax and its parents. employer_total_additional_state_payroll_tax gets a Minnesota branch.
  • Parameters. employee_rate is removed and the employee rate is now derived from rate and the employer minimum shares.

Scope. This review covers only #10294's own six commits (git diff 3698893465..a19c04c83c, 27 files). The #10285 findings are in our #10285 review and aren't repeated here.

Law and sources. I re-read 268B.14 subds. 1, 3, 4, 5a–5c, 6 and 7 and 268B.01 subd. 43 on the Revisor's site. I also re-read DEED's small employer designation notice and DEED's July 31, 2026 bulletin for 2027. Every rate, share, limit and wage base matches the law and DEED's figures:

  • 0.88%, 0.66%, 0.44% and 0.22%;
  • 30 employees;
  • 150% of $73,989, which gives $27,745.88 a quarter;
  • $185,000 in 2026 and $192,000 in 2027.

Code.

  • The employer amount is the premium less the employee amount, so nothing is counted twice.
  • The employer-level formula matches the per-worker formula exactly.
  • Non-Minnesota results are unchanged.
  • Minnesota employee amounts are unchanged at every current parameter value.
  • No household variable reads the employer-side outputs.

Tests, axiom and branch.

Open items. One should-fix item remains, the same one we raised on #10285: seven new parameter descriptions don't follow the house template. There are five optional suggestions.

Critical (must fix)

None.

Should address

1. Seven new parameter descriptions don't follow the house template.

  • Where: line 1 of each file under parameters/gov/states/mn/tax/payroll/paid_leave/:
    • rate.yaml: "Minnesota charges this Paid Leave premium rate on taxable wages for an employer participating in both the family and medical benefit programs."
    • employer_minimum_share.yaml: "Minnesota requires employers to pay at least this share of the Paid Leave premium; employees pay the remaining portion, if any, through a wage deduction."
    • small_employer/employer_minimum_share.yaml: "Minnesota requires small employers to pay at least this share of the full Paid Leave premium rate; employees pay the remaining portion of the small employer premium, if any, through a wage deduction."
    • small_employer/rate_share.yaml: "Minnesota charges small employers this share of the full Paid Leave premium rate."
    • small_employer/max_headcount.yaml: "Minnesota limits the Paid Leave small employer premium rate to employers with at most this many employees."
    • small_employer/max_average_wage_ratio.yaml: "Minnesota limits the Paid Leave small employer premium rate to employers whose average wage is at most this multiple of the state's average wage in covered employment for the basis period."
    • small_employer/state_average_annual_wage.yaml: "Minnesota compares a small employer's average wage with this statewide average annual wage in covered employment, which the Department of Employment and Economic Development calculates each year and applies to the Paid Leave basis period."
  • The template: "one sentence, spell the program out fully (no acronyms), [State] [verb] ... under the [Full Program Name] program."
    • Each description opens correctly with "Minnesota [verb]" and uses no acronyms.
    • None ends with "under the Paid Leave program"; each puts "Paid Leave" inside a noun phrase instead.
    • Five use verbs outside the house list (limits, provides, sets, excludes, deducts, uses): "charges" and "requires" twice each, and "compares" once.
    • Two add a second clause after a semicolon about the employee side. The variable docs already say that.
    • This is the same item we raised on Let employers deduct less than the permitted state payroll premium, and apply Massachusetts' 2027 PFML cap swap #10285's Massachusetts and Delaware descriptions.
  • Fix, for example:
    • rate: "Minnesota sets this premium rate on taxable wages for an employer in both the family and medical benefit programs under the Paid Leave program."
    • employer_minimum_share: "Minnesota sets this minimum share of the premium that employers pay under the Paid Leave program."
    • small_employer.employer_minimum_share: "Minnesota sets this minimum share of the full premium rate that small employers pay under the Paid Leave program."
    • small_employer.rate_share: "Minnesota sets the small employer premium rate at this share of the full premium rate under the Paid Leave program."
    • small_employer.max_headcount: "Minnesota limits the small employer premium rate to employers with at most this many employees under the Paid Leave program."
    • small_employer.max_average_wage_ratio: "Minnesota limits the small employer premium rate to employers whose average wage is at most this multiple of the state's average wage in covered employment under the Paid Leave program."
    • small_employer.state_average_annual_wage: "Minnesota uses this statewide average annual wage in covered employment for the small employer wage test under the Paid Leave program."

Suggestions

1. Report the cost of the two new reform tests (CLAUDE.md, "Measure simulation-heavy additions").

  • What they build. test_minnesota_paid_leave_shares_follow_the_parameters (two parametrized cases) and test_minnesota_small_employer_wage_limit_rounds_half_up each build a full CountryTaxBenefitSystem(reform=(reform,)). That is three reformed systems in the core Python shard.
  • What's reported. The PR body gives time and peak memory for the invariants test but only a pass count (107) for test_payroll_contributions.py.
  • What CLAUDE.md asks. For new tests that build models, it asks for before/after elapsed time (including setup) and peak memory, and for a check of the affected CI group.
  • Why the tests are worth keeping. Their purpose is distinct: the reforms reach both sides through the derived rate, and they pin the floor, the cap and half-up rounding.
  • Fix. Add the numbers to the PR body.

2. Keep the 2027 carry-forward note in small_employer/state_average_annual_wage.yaml.

  • The gap. The basis period for 2027 premiums runs from October 2025 to September 2026. DEED has published no limit for it yet: pl.mn.gov still says "currently $27,745.88 per quarter". So $73,989 carries into 2027.
  • Where it's documented. The PR body says this, but the parameter file doesn't.
  • Fix. A one-line comment, such as "No DEED figure for 2027 premiums as of 2026-10-20; update when DEED issues 2027 small employer designations", keeps the follow-up with the value.

3. Separate the new flow case from Minnesota unemployment insurance values that are out of date on main.

  • The case. mn_employer_paid_leave_contribution.yaml, "The employer premium flows into employer state and total payroll taxes", asserts employer_state_unemployment_tax: 378. Its comment reads "0.9% default rate * the 42,000 wage base".
  • The problem. gov.states.mn.tax.payroll.unemployment.taxable_wage_base on main is a flat 0000-01-01: 42_000. Minnesota's 2026 base is $44,000. UIMN tax rates: "The Taxable wage base for 2026 is $44,000". Its history table gives 2024 $42,000, 2025 $43,000 and 2026 $44,000.
  • Why it matters here. The stale value comes from main, not this PR. But the new case pins it, so a later fix to the UI base would break a paid leave test.
  • Fix.
    • Set employer_state_unemployment_tax_rate_override: 0 in this case. Then it asserts employer_state_payroll_tax: 440 and employer_payroll_tax: 6,200 + 1,450 + 42 + 440 = 8,132.
    • Or keep only the paid leave assertions.
    • Either way, file a follow-up issue for the Minnesota UI wage base.

4. Update one sentence in rulespec-us#1819 to match the head's wage-limit logic.

  • The sentence. The Model the Minnesota Paid Leave employer premium #10294 extension says the limit is "compared in whole cents". It was last edited at 02:19 UTC on 2026-10-20, before f5b8ec27a2 and b0596abccf.
  • The head's logic.
    • The limit is 150% × the state average / 4, rounded half up to the cent.
    • The employer average is compared unrounded, at float32 precision.
    • So $27,745.885 fails, which the YAML pins.
  • Effect. The 14 companion rows all use whole cents and still match.
  • Fix. Reword the sentence and, optionally, add the $27,745.885 row so the encoder sees the boundary.

5. Small text fixes.

Verified correct

  • The statute (Minn. Stat. 268B.14):
    • subd. 1(a): "premiums accrue and become payable by each employer ... on the taxable wages that the employer paid to employees in covered employment". This is mn_paid_leave_premium on the employer.
    • subd. 3: "employers must pay a minimum of 50 percent of the annual premiums ... Employees, through a deduction in their wages ... must pay the remaining portion, if any". This gives employer_minimum_share = 0.5 and the floor at 0.
    • subd. 5a(a): eligible if "(1) has 30 or fewer employees pursuant to subdivision 5b; and (2) the average wage for that employer as calculated in subdivision 5c is less than or equal to 150 percent of the state's average wage in covered employment for the basis period". This gives max_headcount 30, max_average_wage_ratio 1.5 and the <= test.
    • subd. 5a(b): "75 percent of the annual premium rate ... (1) employers must pay a minimum of 25 percent of the rate calculated in subdivisions 6 and 7". This gives rate_share 0.75 and the small employer minimum of 0.25 × the full rate. The employee maximum is 0.66% − 0.22% = 0.44%, the same as for a large employer.
    • subds. 5b and 5c: the basis period is "the four-quarter period ending September 30 of the prior year". The employer's average is the maximum single-quarter covered wages divided by the maximum quarterly wage-record count. The docstrings of employer_headcount and mn_paid_leave_employer_average_quarterly_wage describe the proxies correctly.
    • subds. 6 and 7: the statutory rate is 0.7% (6(1)), and the commissioner adjusts it each year by July 31. The approved private plan rates (6(2)–(3)) are documented as not modeled.
  • DEED figures:
    • 2026 rate: DEED's press release "the premium rate will be 0.88 percent".
    • 2027 rate: DEED bulletin, July 31, 2026: "will remain steady at 0.88% of covered wages in Minnesota for 2027 ... employers can continue to collect up to 0.44% from employees in 2027 ... Small employers pay a smaller share – as little as 0.22%".
    • The small employer designation notice:
      • Page 1: "The effective rate for small employers is 0.66% ... Like large employers, small employers can deduct up to 0.44%", "30 or fewer employees", "150% of the statewide average wage", and "If this number was higher than $27,745.88, the employer was not designated".
      • Page 2: "The Statewide Average Annual Wage for 2025 was $73,989", and the table gives $18,497.25 and $27,745.88 a quarter. The page's prose says "$18,497.35"; that's a typo, and the table and arithmetic give $18,497.25.
      • The #page=1 and #page=2 anchors each show the cited figure.
    • Premiums page. pl.mn.gov returns 403 to automated requests. A search capture confirms "For 2026 and 2027, the Paid Leave premium rate is 0.88% ... The Paid Leave small employer rate is 0.66%".
  • Wage base:
    • 268B.01 subd. 43: "the maximum earnings in that year subject to the FICA Old-Age, Survivors, and Disability Insurance tax rounded to the nearest $1,000".
    • DEED's notice gives "rounded to the nearest thousand dollars (currently $185,000)".
    • 2026: $184,500 → $185,000. 2027: $192,300 → $192,000.
    • Subd. 4's unrounded wording conflicts with subd. 43. That conflict predates this PR (mn_paid_leave_taxable_wages is unchanged), and the PR body documents it.
  • Wages counted (OK Add Oklahoma state supplementation for 2026 #10165 lesson):
    • The base is gross employment_income, unchanged from main.
    • Minnesota "wages" include salary reductions under 401(k) and cafeteria plans: 268.035 subd. 29(b), "Nothing in this subdivision excludes from the term 'wages' any payment made under any type of salary reduction agreement, including ... cafeteria plan".
    • So deducting pre-tax amounts would be wrong, and the code doesn't.
  • Formulas:
    • mn_paid_leave_premium_rate = rate × where(small, 0.75, 1).
    • mn_paid_leave_permitted_employee_rate = rate × clip(premium share − employer minimum share, 0, premium share).
    • mn_employee_paid_leave_contribution = permitted rate × taxable wages × the clipped share.
    • mn_employer_paid_leave_contribution = premium − employee amount. It lies between the employer minimum and the full premium.
    • No double counting. The employee part feeds employee_state_payroll_tax; only the remainder feeds employer_additional_state_payroll_tax → employer_state_payroll_tax → employer_payroll_tax → employer_cost_of_employment.
    • Employer level. (premium rate − share × permitted rate) × employer_total_mn_paid_leave_taxable_wages is algebraically the per-worker formula. It reads the same small employer test, and property 5 checks the two agree.
  • The float32 boundary:
    • The limit. 100 × 1.5 × 18,497.25 = 2,774,587.5, +0.5, floor, /100 = $27,745.88.
    • Precision. In float32 the spacing near $27,745 is 2⁻⁹ ≈ $0.00195:
      • $27,745.88 → 27,745.880859, equal to np.float32(limit), so it meets the test;
      • $27,745.885 → 27,745.884766, above the limit, so it fails;
      • $27,745.89 → 27,745.890625, so it fails.
    • Rounding mode. DEED's 27,745.875 rounds to .88 under both half up and half to even, because the 7 is odd. So DEED's figure doesn't decide the mode. Half up is the usual convention, and the reform test pins it ($73,991 → $27,746.625 → $27,746.63).
  • Pre-2015 years and the 2026 start:
  • Defaults and other states:
    • Every new Minnesota variable has defined_for = StateCode.MN. The aggregate selects the Minnesota branch only for Minnesota.
    • The WI case and the multi-state property test (the optional states plus CA, CT, NJ, OR, PA, RI and TX) confirm other states are unchanged.
    • Minnesota employee amounts are unchanged: 0.0088 × 0.5 equals 0.0044 exactly in binary, for both large and small employers.
    • The new employer amounts at the defaults (100 employees, share 1) are intended.
    • Callers. employer_payroll_tax is read only by employer_cost_of_employment; the CRFB tax_employer_payroll_tax reform adds only employer Social Security and Medicare. So household outputs don't move.
  • Batch lessons:
  • Removing employee_rate:
    • No reference remains at the head or on main.
    • A top-level changelog.d/mn-employer-paid-leave-premium.removed.md documents it, alongside .added.md. Both types fit.
    • No partner contract test is touched.
  • Hand checks (2026 and $100,000 unless noted):
    • Large employer, share 1: 0.88% → premium 880; permitted 0.44% → employee 440; employer 440. The aggregates are 440 ✓.
    • Share 0.5: 220 / 660. Share 0: 0 / 880 ✓.
    • 30 employees (small): rate 0.66%; permitted (0.75 − 0.25) × 0.88% = 0.44%; premium 660; employee 440; employer 220 ✓.
    • Small, share 0.5: 220 / 440. Small, share 0: 0 / 660 ✓.
    • 31 employees: not small; 880 / employer 440 ✓.
    • Average wage, 10 employees: $27,745.88 → small, 660 / 220. $27,745.89 → 880 / 440. $27,745.885 → not small, 880 ✓.
    • $250,000 of wages: taxable 185,000; 0.88% → 1,628; 0.44% → 814 / 814 ✓.
    • $250,000, 9 employees: 0.66% × 185,000 = 1,221; employee 814; employer 407 = 0.22% × 185,000 ✓.
    • $8,000: 70.40 / 35.20 / 35.20 ✓. Negative wages: 0 ✓.
    • Flow: 378 + 440 = 818. Then 6,200 + 1,450 + 42 + 818 = 8,510 ✓. The UI part is arithmetically right but rests on the stale base in suggestion 3.
    • 2027: 880 / 440 / 440. 2025 and 2014: 0 ✓. WI: 0 ✓.
    • Employer level:
      • (0.88% − 0.44%) × 1,000,000 = 4,400 ✓.
      • 20 employees at share 0.25: (0.66% − 0.25 × 0.44%) × 1,000,000 = 5,500 ✓.
      • Minnesota base override: 0.44% × 370,000 = 1,628 ✓.
    • Deduction-share case: 0.88% × 100,000 − 220 = 660 ✓.
    • Python tests:
      • Employer side 440 / 440.
      • Minnesota wage base 7,000: employee 30.8, employer 30.8.
      • Employer total 0.44% × 100,000 = 440; the state-specific base gives 30.8 ✓.
    • Reform test (rate 1%, employer minimum 0.6):
      • Large: 1,000 / 400 / 600.
      • Small minimum 0.8: clip(−0.05) = 0, giving 750 / 0 / 750.
      • Small minimum −0.1: clip(0.85, 0, 0.75) = 0.75, giving 750 / 750 / 0 ✓.
    • Rounding test: 1.5 × 73,991 / 4 = 27,746.625 → 27,746.63. In float32, 27,746.63 → 27,746.630859 meets the test; 27,746.64 → 27,746.640625 fails ✓.
  • Test design:
    • Property 7 uses constants written from the statute and DEED (0.88%, 30 employees, $27,745.88), independent of the parameter files. It checks the premium, conservation and the employer's minimum plus the undeducted share.
    • The draws pin the 30/31-employee and $27,745.88/$27,745.89 boundaries, and the assertion mn_small[mn].any() and (~mn_small[mn]).any() guarantees both kinds of Minnesota employer appear.
    • The YAML file is named after mn_employer_paid_leave_contribution.
    • Periods are plain (no 2_026).

Axiom line assessment

Valid. The line reads axiom: Minn. Stat. 268B.14 → TheAxiomFoundation/rulespec-us#1819 queued (...; blocked on corpus ingestion, TheAxiomFoundation/axiom-corpus#893).

  • Status. rulespec-us#1819 is OPEN and labelled pe-parity. The blocker, axiom-corpus#893 ("Ingest state paid-leave premium sources ... for rulespec-us pe-parity"), is OPEN and was updated today.
  • Dispatch-ready. The body has:
    • the module target us-mn/statutes/268B/14.yaml with the proposed corpus citation us-mn/statute/268B.14;
    • the verbatim law for subds. 1(a), 3, 4, 5a(a)–(b), 5b(a)–(c), 5c(a)–(b) and 6, and for 268B.01 subd. 43;
    • DEED's figures for 2026 and 2027;
    • the required outputs, including mn_paid_leave_small_employer and the employer-paid premium;
    • the leaf inputs: employee count, employer average quarterly wage, deduction share and taxable wages;
    • companion tests hand-computed from the statute and DEED, not from PolicyEngine output;
    • an updated pasteable review_finding.
  • Match with the head.
    • All 14 rows of the "Extension for PE-US Model the Minnesota Paid Leave employer premium #10294" table match this head's YAML: 880/440/440, 880/220/660, 880/0/880, 660/440/220, 660/220/440, 660/0/660, 31 employees at 880/440/440, $27,745.88 → small, $27,745.89 → not small, 1,628/814/814, 1,221/814/407, 70.40/35.20/35.20, 2027 880/440/440, and 2025 at 0.
    • The 2027 comment's rows (220/220 and 1,689.60/844.80/844.80) also follow from 0.88% with the $192,000 base.
    • One sentence ("compared in whole cents") predates the head's wage-limit logic; suggestion 4 covers it.
  • Queued is the right status. rulespec-us main (5796861e58) has only us-mn/statutes/290; there is no 268B module.

CI status

29 checks pass and 3 are skipping at head a19c04c83c (gh pr checks 10294, re-checked at the end of this review). Nothing is pending.

Branch status

Verdict: REQUEST_CHANGES

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minnesota's rate, the employer/employee split, the small-employer reduction, the wage limit and the float32 boundary all match 268B.14 and DEED, and all 22 new cases hand-check. One should-address item: seven new MN parameter descriptions don't follow the house template (rewrites are in the report). Five suggestions. Merge #10285 first; the merge with it and with main is clean. Full report in the comment above.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants